程序对蓝色车辆检测效果不是很好,有待改进。文字识别和提取正在做
#include"opencv2/opencv.hpp"
#include"opencv2/highgui/highgui.hpp"
#include"opencv2/imgproc/imgproc.hpp"
#include "opencv2/ml.hpp"
#include"iostream"
#include"stdio.h"
using namespace cv;
using namespace std;
bool verify(Rect rect);
int OtsuAlgThreshold(const Mat image);
//void svm_train(SVM & svmClassifier);
int main(int argc, char**argv)
{
Mat srcimage = imread("7.jpg");
if (srcimage.data == NULL)
{
return 0; cout << "无法加载图片" << endl;
}
Mat midimage1, grayimage;
cvtColor(srcimage, grayimage, CV_BGR2GRAY);
blur(grayimage, grayimage, Size(3, 3));
Sobel(grayimage, midimage1, CV_8UC1, 1, 0, 3, 1, 1);
convertScaleAbs(midimage1, midimage1);
imshow("1", midimage1);
///hsv提取蓝色通道
Mat midimage2, midimage3;
cvtColor(srcimage, midimage2, CV_BGR2HSV);
vector hsv_vec;
split(midimage2, hsv_vec);
midimage3 = (hsv_vec[0] > 90)&(hsv_vec[0] < 124)&(hsv_vec[1] > 70)&(hsv_vec[2] > 70);
imshow("2", midimage3);
//////形态学处理和找轮廓
Mat midimage5 = Mat::zeros(srcimage.size(), CV_8UC1);
midimage5 = midimage3&midimage1;
imshow("3", midimage5);
Mat morph;
morphologyEx(midimage5, morph, MORPH_CLOSE, Mat::ones(2, 25, CV_8UC1));
vector> contours;
findContours(morph, contours ,RETR_LIST, CHAIN_APPROX_SIMPLE);
Rect rec_adapt[30]; int j = 0;
Mat sizeimage[30], grayResult[30];
Mat resultResized[30];
Mat outimage[10];
//调用SVM文件
FileStorage fs;
fs.open("SVM.xml", FileStorage::READ);
if (!fs.isOpened()) // failed
{
std::cout << "Save File Failed!" << std::endl;
return 0;
}
Mat SVM_TrainningData;
Mat SVM_Classes;
fs["TrainingData"] >> SVM_TrainningData;
fs["classes"] >> SVM_Classes;
//cout << SVM_Classes << endl;
SVM_Classes.convertTo(SVM_Classes, CV_32SC1);
cv::Ptr svm = cv::ml::SVM::create();
svm->setType(cv::ml::SVM::Types::C_SVC);
svm->setKernel(cv::ml::SVM::KernelTypes::LINEAR);
svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 100, 1e-6));
svm->train(SVM_TrainningData, ml::ROW_SAMPLE, SVM_Classes);
for (size_t i = 0; i < contours.size(); i++)
{ //绘出所有找到的轮廓
drawContours(morph, contours, static_cast(i), Scalar(255, 0, 0), 2);
imshow("4", morph);
//double car_image_rate = static_cast(countNonZero(morph(boundingRect(contours[i]))) / static_cast(boundingRect(contours[i]).area()));
//cout << car_image_rate << endl;
//判定符合车牌条件
if (verify(boundingRect(contours[i])) == 1)//&& car_image_rate>0.4)
{ //裁剪图像和直方图均衡化
rec_adapt[j] = boundingRect(contours[i]);
sizeimage[j] = srcimage(rec_adapt[j]);
resize(sizeimage[j], resultResized[j], Size(144, 33), 0, 0, INTER_CUBIC);
cvtColor(resultResized[j], grayResult[j], CV_BGR2GRAY);
equalizeHist(grayResult[j], grayResult[j]);
//grayResult[j].convertTo(grayResult[j], CV_32FC1);
//图像矩阵转换成一行
Mat p = grayResult[j].reshape(1, 1);
p.convertTo(p, CV_32FC1);
int response = svm->predict(p);
if (response == 1)
{
outimage[j] = grayResult[j];
imshow("车牌", outimage[j]);
}
else
{
cout << "未检索到车牌" << endl;
}
j++;
}
}
waitKey(0);
return 0;
//
}
bool verify(Rect rect)
{
float error = 0.4;
const float aspect = 4.7272;
int min = 15 * aspect * 15; // 面积下限
int max = 180 * aspect * 180; // 面积上限
float rmin = aspect - aspect * error; // 宽高比下限
float rmax = aspect + aspect * error; // 宽高比上限
int area = rect.width * rect.height; // 计算面积
float r = rect.width / rect.height; // 计算宽高比
r = r < 1 ? 1 / r : r;
//return area >= min && area <= max && r >= rmin && r <= rmax&&rect.width>80&& rect.height>10;
return rect.width > 50 && rect.height > 10 && area >= min && area <= max;
}
以下贴出一张运行图
工程路径如下 点击打开链接