通过OpenCV的特征点线检测方法来检测车牌,使用高斯模糊、灰度化、Sobel算子、二值化、开运算等进行图像形态学处理,然后根据车牌的面积大小、长宽比等筛选出车牌并标记出来。
这只是一个简单的车牌检测,并不包含车牌号的识别。图片的每次处理依赖于前一次处理的结果。如果以下代码不能正确检测车牌的话可通过修改调用函数的参数来满足其他车牌检测的需求。
#include
using namespace cv;
using namespace std;
Mat srcImage, dstImage1, dstImage2;
String imagePath = "C:/Users/admin/Pictures/car2.jpg";
int main() {
srcImage = imread(imagePath, 1);
imshow("原图", srcImage);
// 高斯模糊
Mat gausImage = srcImage.clone();
GaussianBlur(srcImage, gausImage, Size(3, 3), 0, 0);
imshow("高斯模糊", gausImage);
// 灰度化
Mat grayImage = srcImage.clone();
cvtColor(gausImage, grayImage, COLOR_BGR2GRAY);
imshow("灰图", grayImage);
// Sobel算子
Mat sobelImage = srcImage.clone();
Sobel(grayImage, sobelImage, CV_8UC1, 1, 0);
imshow("Sobel算子", sobelImage);
// 二值化
Mat binaryImage = srcImage.clone();
threshold(sobelImage, binaryImage, 90, 255, THRESH_BINARY);
imshow("二值化", binaryImage);
// 开运算(先腐蚀,再膨胀)
// Mat morphologyExImage=srcImage.clone();
// Imgproc.morphologyEx(binaryImage, morphologyExImage, Imgproc.MORPH_CLOSE, Imgproc.getStructuringElement( Imgproc.MORPH_RECT,new Size(1,1)));
// HighGui.imshow("开运算", morphologyExImage);
Mat erodeImage = srcImage.clone();
erode(binaryImage, erodeImage, getStructuringElement(MORPH_RECT, Size(3, 2)));
imshow("腐蚀", erodeImage);
Mat dilateImage = srcImage.clone();
dilate(erodeImage, dilateImage, getStructuringElement(MORPH_RECT, Size(22, 22)));
imshow("膨胀", dilateImage);
// 取轮廓,显示全部轮廓
Mat flagImage = srcImage.clone();
vector> contours;
Mat hierarchy ;
findContours(dilateImage, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
drawContours(flagImage, contours, -1, Scalar(0, 255, 0));//绿线画出所有的轮廓
imshow("轮廓", flagImage);
//识别车牌(找出面积最大且宽高比例符合要求),仅对提供的两个车牌识别有效!!!
double maxArea = 0;
int targetIndex;
for (int i = 1; i < contours.size(); i++) {
double area = contourArea(contours[i]);
Rect rect = boundingRect(contours[i]);
double scaleWH = (double)rect.width / rect.height;//这个比例范围是目测的
if (area > maxArea&&scaleWH > 1.5 && scaleWH < 3.5) {
maxArea = area;
targetIndex = i;
}
}
//显示车牌轮廓
Mat licenseImage = srcImage.clone();
Rect r = boundingRect(contours[targetIndex]);
rectangle(licenseImage,r,Scalar(0, 255, 0));
imshow("车牌标记", licenseImage);
waitKey(0);
return 0;
}
处理流程:读入原图—>高斯模糊—>灰度化—>Sobel算子—>二值化—>开运算—>轮廓全标记—>根据特征筛选车牌—>显示车牌标记
车牌①:
【图片侵删】
车牌②:
(处理流程同上上,略)
代码并不完善,仅供参考。形态学处理方式方法有很多,请自行查阅相关资料!