2014-09-10 98 views
-1

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

这是原来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); 
    } 
} 
+0

该代码无法编译。你需要'std :: vector > :: iterator itc = contours.begin();',对于初学者。 – Bull 2014-09-11 01:12:57

回答

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); 
    } 

} 
+0

优秀的工作.'float'没有工作。但'双'正在工作。 – 2014-09-11 07:49:09

+0

这是因为没有从double到float的隐式转换 – Bull 2014-09-11 07:52:30