- 最近這段時間需要進行圖片方面的處理涛碑,眾所周知精堕,
OpenCv
是開源圈里幾乎最優(yōu)秀的計算機視覺處理庫,本文記錄在研究過程中所做的一個車牌定位的Demo蒲障。
本文所提供的Demo僅限于車牌定位歹篓,定位出的車牌進行識別的話可以使用TeseRact
進行,本文不做更多描述揉阎。
工具準備
Qt
- Qt的安裝網(wǎng)上有大量的教程庄撮,或許之后本人會出一個相關(guān)的文章,不過在這里就只放一個下載的Link好了
http://download.qt.io/archive/qt/
OpenCv庫文件
OpenCv
在Windows下配合Qt的使用需要對源碼進行重新編譯毙籽,我所使用的是最新的4.3版本,放個下載連接以及安裝編譯教程OpenCv
下載OpenCv
安裝視頻教程windows- 如果各位覺得上述操作太麻煩我這里提供一個我自己編譯出來的OpenCv4.3的lib
Demo
1.新建一個Qt的項目
2.Pro文件中需添加OpenCv
庫的頭文件路徑
以及lib路徑
[1]
INCLUDEPATH += C:\Users\houxia2x\Desktop\Asa\opencv\opencv\asa_build\install\include\opencv2\
C:\Users\houxia2x\Desktop\Asa\opencv\opencv\asa_build\install\include
LIBS += -LC:\Users\houxia2x\Desktop\Asa\opencv\opencv\asa_build\install\x64\mingw\bin\
-llibopencv_world430
3.頭文件需包含OpenCv的統(tǒng)籌文件"opencv2/opencv.hpp"
#include "opencv2/opencv.hpp"
4.加載命名空間
using namespace cv;
5.加載圖片
Mat srcImage = imread(path);
if(srcImage.empty())
{
cout<<"load pic failed";
return;
}
6.對圖片進行高斯模糊處理(圖像平滑處理)
Mat dealImage = srcImage.clone();
GaussianBlur(srcImage,dealImage,Size(3,3),0);
7.邊緣檢查
Mat h_filler,v_filler,abs_h_filler,abs_v_filler;
Sobel(dealImage,h_filler,CV_16S,1,0,3,1,0,BORDER_DEFAULT); //橫向檢查
convertScaleAbs(h_filler,abs_h_filler);
Sobel(dealImage,v_filler,CV_16S,0,1,3,1,0,BORDER_DEFAULT); //縱向檢查
convertScaleAbs(v_filler,abs_v_filler);
addWeighted(abs_h_filler,0.5,abs_v_filler,0.5,0,dealImage); //合并檢查結(jié)果
8.圖像二值化處理
cvtColor(dealImage,dealImage,COLOR_BGR2GRAY); //轉(zhuǎn)為灰度圖像
threshold(dealImage,dealImage,95,255,THRESH_BINARY); //二值化
9.圖像補全處理
Mat element = getStructuringElement(MORPH_RECT,Size(25,25)); //核陣列
vector<vector<Point>> vec_count;
morphologyEx(dealImage,dealImage,MORPH_CLOSE,element); //閉運算(膨脹--腐蝕)
morphologyEx(dealImage,dealImage,MORPH_OPEN,element); //開運算(腐蝕--膨脹)
10.獲取車牌區(qū)域(截取車牌范圍的算法可自行判斷設(shè)計)
vector<vector<Point>> vec_area;
findContours(dealImage,vec_area,RETR_EXTERNAL,CHAIN_APPROX_NONE);
vector<Point> max_point_area;
size_t num_max = 0;
Point2f tmp_rect[4];
for(size_t i = 0 ; i < vec_area.size() ; ++i) //獲取最大面積的區(qū)域洞斯,即車牌區(qū)域
{
minAreaRect(vec_area[i]).points(tmp_rect);
double width = powf((tmp_rect[0].x - tmp_rect[1].x), 2) + powf((tmp_rect[0].y - tmp_rect[1].y), 2);
width = sqrt(width);
double height = powf((tmp_rect[0].x - tmp_rect[3].x), 2) + powf((tmp_rect[0].y - tmp_rect[3].y), 2);
height = sqrt(height);
if(height*width > num_max)
{
num_max = height*width;
max_point_area = vec_area[i];
}
}
if(num_max > 0) //是否獲取到區(qū)域
{
/*描繪最大區(qū)域的輪廓*/
Mat carPlateAreaImage = srcImage.clone();
for(size_t i = 0 ; i < max_point_area.size() ; ++i)
{
circle(carPlateAreaImage,max_point_area.at(i),2,Scalar(255,0,0));
}
/*描繪最大區(qū)域的矩形形態(tài)*/
Point2f max_rect_corner_point[4];
RotatedRect max_rect = minAreaRect(max_point_area);
max_rect.points(max_rect_corner_point);
for(size_t j = 0 ; j < 4 ; ++j)
{
line(carPlateAreaImage,max_rect_corner_point[j],max_rect_corner_point[(j+1)%4],Scalar(0,0,255),3);
}
// imshow("carPlateAreaImage image",carPlateAreaImage);
Mat carPlateImage = Mat(srcImage,max_rect.boundingRect());
imshow("carPlateImage image",carPlateImage);
}else{
cout<<"Fail for fetch area of car plate";
}
Note
- Demo中所提供的代碼是經(jīng)過本人親測有效的,不過考慮到汽車圖像的各種情況不同惧财,定位效果不做保證巡扇,如果希望進行汽車圖像車牌的復(fù)雜環(huán)境多種類型都可以定位的話,需要依靠機器學(xué)習的模型來進行垮衷,本文只是提供一種車牌定位的實現(xiàn)厅翔,后面有機會再分享機器模型的創(chuàng)建以及訓(xùn)練
-
我將OpenCv的庫文件編譯成了一個文件,所以在LIBS中只添加了一個lib搀突,如果不是這種情況刀闷,需要將所有l(wèi)ib都添加進來 ?