2014-09-10 129 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