OpenCV + Android +车牌号识别

时间:2014-09-10 17:16:42

标签: java android opencv vector

我正在开发一款Android应用来检测车牌号码。我做了图像处理,找到了图像级别的图像。现在我需要将以下C ++代码转换为基于Opencv的Android java。

这是原始image

enter image description here

这是在Otsu阈值image

之后

enter image description here

这是我的andoid + opencv代码(100%工作)

ImageView imgView  = (ImageView) findViewById(R.id.imageView1);
Bitmap bmp = BitmapFactory.decodeResource(getResources(),car);
//First convert Bitmap to Mat
Mat ImageMatin = new Mat ( bmp.getHeight(), bmp.getWidth(), CvType.CV_8U, new Scalar(4));    
Mat ImageMatout = new Mat ( bmp.getHeight(), bmp.getWidth(), CvType.CV_8U, new Scalar(4));
Mat ImageMatBk = new Mat ( bmp.getHeight(), bmp.getWidth(), CvType.CV_8U, new Scalar(4));
Mat ImageMatTopHat = new Mat ( bmp.getHeight(), bmp.getWidth(), CvType.CV_8U, new Scalar(4));
Mat temp = new Mat ( bmp.getHeight(), bmp.getWidth(), CvType.CV_8U, new Scalar(4));

Bitmap myBitmap32 = bmp.copy(Bitmap.Config.ARGB_8888, true);
Utils.bitmapToMat(myBitmap32, ImageMatin);  


//Converting RGB to Gray.
Imgproc.cvtColor(ImageMatin, ImageMatBk, Imgproc.COLOR_RGB2GRAY,8);    

Imgproc.dilate(ImageMatBk, temp, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(9, 9)));
Imgproc.erode(temp, ImageMatTopHat, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(9,9)));  

//Core.absdiff(current, previous, difference);
Core.absdiff(ImageMatTopHat, ImageMatBk, ImageMatout);      

//Sobel operator in horizontal direction.    
Imgproc.Sobel(ImageMatout,ImageMatout,CvType.CV_8U,1,0,3,1,0.4,Imgproc.BORDER_DEFAULT);

//Converting GaussianBlur                   
Imgproc.GaussianBlur(ImageMatout, ImageMatout, new Size(5,5),2);    

Imgproc.dilate(ImageMatout, ImageMatout, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3,3)));

Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(17, 3));    
Imgproc.morphologyEx(ImageMatout, ImageMatout, Imgproc.MORPH_CLOSE, element);

//threshold image
Imgproc.threshold(ImageMatout, ImageMatout, 0, 255, Imgproc.THRESH_OTSU+Imgproc.THRESH_BINARY);

现在我需要提取数字板

请帮我将以下C ++代码转换为java + opencv:。

std::vector rects;  
std::vector<std::vector >::iterator itc = contours.begin();  
while (itc != contours.end())  
{  
    cv::RotatedRect mr = cv::minAreaRect(cv::Mat(*itc)); 
    float area = fabs(cv::contourArea(*itc));  
    float bbArea=mr.size.width * mr.size.height;  
    float ratio = area/bbArea;  
    if( (ratio < 0.45) || (bbArea < 400) ){  
        itc= contours.erase(itc);  
    }else{  
        ++itc;  
        rects.push_back(mr);  
    }  
} 

1 个答案:

答案 0 :(得分:1)

特别关注http://docs.opencv.org/javathe documentation for findContours

而不是

std::vector<std::vector<cv::Point> > contours;

你会有

java.util.ArrayList<MatOfPoint> contours;

您可以使用contours.listIterator()遍历列表。像下面的东西(没有编译,更不用说运行,可能包含重大错误):

import java.util.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.core.*;

/* ... */
ArrayList<RotatedRect> rects = new  ArrayList<RotatedRect>()
ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(image, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);

ListIterator<MatOfPoint> itc = contours.listIterator();
while(itc.hasNext())
{
     MatOfPoint2f mp2f = new MatOfPoint2f(itc.next().toArray());
     RotatedRect mr = Imgproc.minAreaRect(mp2f);
     double area = Math.abs(Imgproc.contourArea(mp2f));

     double bbArea= mr.size.area();  
     double ratio = area / bbArea;  
     if( (ratio < 0.45) || (bbArea < 400) )
     {  
         itc.remove();  // other than deliberately making the program slow,
                        // does erasing the contour have any purpose?
     }
     else
     {  
         rects.add(mr);  
     }  

}