OpenCV的+安卓+号牌识别号牌、OpenCV

2023-09-07 03:06:24 作者:27.遇见未来不躲避

我正在开发一个Android应用程序,以检测车辆的号牌。我做的图像处理高达图像findContours水平。现在,我需要将下面的C ++ code到基于OpenCV的Andr​​oid的Java。

这是原来的图片

这是大津阈值图片

基于OpenCV 的车牌识别

这是我andoid + OpenCV的code(工作100%)

  ImageView的imgView =(ImageView的)findViewById(R.id.imageView1);
BMP位= BitmapFactory.de codeResource(getResources(),汽车);
//首先转换成位图太
垫ImageMatin =新材料(bmp.getHeight(),bmp.getWidth(),CvType.CV_8U,新标(4));
垫ImageMatout =新材料(bmp.getHeight(),bmp.getWidth(),CvType.CV_8U,新标(4));
垫ImageMatBk =新材料(bmp.getHeight(),bmp.getWidth(),CvType.CV_8U,新标(4));
垫ImageMatTopHat =新材料(bmp.getHeight(),bmp.getWidth(),CvType.CV_8U,新标(4));
垫温度=新材料(bmp.getHeight(),bmp.getWidth(),CvType.CV_8U,新标(4));

位图myBitmap32 = bmp.copy(Bitmap.Config.ARGB_8888,真正的);
Utils.bitmapToMat(myBitmap32,ImageMatin);


// RGB转换为灰色。
Imgproc.cvtColor(ImageMatin,ImageMatBk,Imgproc.COLOR_RGB2GRAY,8);

Imgproc.dilate(ImageMatBk,温度,Imgproc.getStructuringElement(Imgproc.MORPH_RECT,新尺寸(9,9)));
Imgproc.erode(温度,ImageMatTopHat,Imgproc.getStructuringElement(Imgproc.MORPH_RECT,新尺寸(9,9)));

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

// Sobel算子在水平方向上。
Imgproc.Sobel(ImageMatout,ImageMatout,CvType.CV_8U,1,0,3,1,0.4,Imgproc.BORDER_DEFAULT);

//转换GaussianBlur
Imgproc.GaussianBlur(ImageMatout,ImageMatout,新尺寸(5,5),2);

Imgproc.dilate(ImageMatout,ImageMatout,Imgproc.getStructuringElement(Imgproc.MORPH_RECT,新尺寸(3,3)));

垫元= Imgproc.getStructuringElement(Imgproc.MORPH_RECT,新的大小(17,3));
Imgproc.morphologyEx(ImageMatout,ImageMatout,Imgproc.MORPH_CLOSE,元件);

//阈值图像
Imgproc.threshold(ImageMatout,ImageMatout,0,255,Imgproc.THRESH_OTSU + Imgproc.THRESH_BINARY);
 

现在我需要提取号牌

请帮我转换下C ++ code到Java + OpenCV的:

 的std ::向量rects;
的std ::矢量<的std ::矢量GT;:迭代ITC = contours.begin();
而(ITC!= contours.end())
{
    CV :: RotatedRect MR = CV :: minAreaRect(CV ::垫(* ITC));
    浮面积=晶圆厂(CV :: contourArea(* ITC));
    浮bbArea = mr.size.width * mr.size.height;
    流通股比例=面积/ bbArea;
    如果((比率&所述; 0.45)||(bbArea&所述; 400)){
        ITC = contours.erase(ITC);
    }其他{
        ++ ITC;
        rects.push_back(MR);
    }
}
 

解决方案

看着 HTTP://docs.opencv。组织/ java的和为findContours的文档尤其

而不是

 的std ::矢量<的std ::矢量< CV ::点> >轮廓;
 

您将有

 的java.util.ArrayList< MatOfPoint>轮廓;
 

您可以使用 contours.listIterator()来遍历列表。有点像以下(不编译更不用说来看,可能包含重大失误):

 进口的java.util。*;
进口org.opencv.imgproc.Imgproc;
进口org.opencv.core *。

/ * ... * /
ArrayList的< RotatedRect> rects =新的ArrayList< RotatedRect>()
ArrayList的< MatOfPoint>轮廓=新的ArrayList< MatOfPoint>();
Imgproc.findContours(图像,轮廓,新材料(),Imgproc.RETR_EXTERNAL,Imgproc.CHAIN​​_APPROX_NONE);

的ListIterator< MatOfPoint> ITC = contours.listIterator();
而(itc.hasNext())
{
     MatOfPoint2f mp2f =新MatOfPoint2f(itc.next()的toArray());
     RotatedRect MR = Imgproc.minAreaRect(mp2f);
     双面积= Math.abs(Imgproc.contourArea(mp2f));

     双bbArea = mr.size.area();
     双比=面积/ bbArea;
     如果((比< 0.45)||(bbArea< 400))
     {
         itc.remove(); //比故意使程序速度慢等,
                        //并删除轮廓有什么目的?
     }
     其他
     {
         rects.add(MR);
     }

}
 

I'm developing a Android app to detect vehicle number plate. i did image processing up to findContours level of image. Now i need to convert following C++ code to Opencv Based Android java.

This is original image

This is after Otsu thresholding image

This is my andoid+opencv code (working 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);

Now I need to extract number Plate

Please help me to convert following C++ code to 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);  
    }  
} 

解决方案

Looking at http://docs.opencv.org/java and the documentation for findContours in particular

instead of

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

you will have

java.util.ArrayList<MatOfPoint> contours;

You can use contours.listIterator() to traverse the list. Something like the below (not compiled let alone run,likely to contain major blunders):

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

}