OpenCV實現車輛識別和運動目標檢測
一:車輛識別成果展示
二:車輛識別超詳細步驟解析
步驟一:灰度化處理
灰度處理目的 RGB三通道轉灰度單通道 壓縮到原圖片三分之一大小
效果展示:【避免內存浪費 幀差法對前後幀圖像灰度化處理】
//1 灰度處理 目的 RGB三通道轉灰度單通道 壓縮到原圖片三分之一大小 cvtColor(frontFrame,frontGray,CV_RGB2GRAY);//前一幀灰度化處理 cvtColor(afterFrame,afterGray,CV_RGB2GRAY);//後一幀灰度化處理 //imshow("frontGray",frontGray);//測試 //imshow("afterGray",afterGray);//測試
步驟二:幀差處理
幀差處理目的 找到幀與幀之間的差異(正在運動的物體)
效果展示:【運動目標的檢測:運動事物顯示灰度,靜止事物顯示黑度】
//2 幀差處理 目的 找到幀與幀之間的差異(正在運動的物體) Mat diff; Mat frontGray,afterGray; absdiff(frontGray,afterGray,diff);//前後幀對比存於diff中 imshow("diff",diff);//測試
步驟三:二值化處理
二值化處理 目的 將灰度圖繼續識別轉換為黑白分明的圖像
效果展示:【步驟二中運動事物顯示灰度,靜止事物顯示黑度,在這裡進行二值化處理,能夠黑白分明,便於計算機識別運動目標,如下右圖二值化處理後黑白分明】【缺點:存在白色噪點,如下右圖除瞭車輛外後面的背景也顯示白度,這就是白色噪點,需要去除】
//3 二值化處理 目的 將灰度圖繼續識別轉換為黑白分明的圖像 threshold(diff,diff,25,255,CV_THRESH_BINARY); imshow("threshold",diff);//測試
步驟四:圖像降噪
4-1 腐蝕處理 目的 去除白色噪點
效果展示:【步驟三中存在的白色噪點能夠去除,但是在去除白色噪點的同時,也影響瞭車輛的白度顯示,如下右圖可以看出,車輛白度顯示有所降低,因此還是需要改進】
//4 圖像降噪 //4-1 腐蝕處理 目的 去除白色噪點 Mat element = cv::getStructuringElement(MORPH_RECT,Size(3,3));//小於3*3方塊的白色噪點都會被腐蝕 erode(diff,diff,element); imshow("erode",diff);//測試
4-2 膨脹處理 目的 把白色區域變大
效果展示:【如下右圖,將車輛形狀大致顯示,便於框選車輛識別操作】
//4-2 膨脹 目的 把白色區域變大 Mat element2=cv::getStructuringElement(MORPH_RECT,Size(20,20)); dilate(diff,diff,element2); imshow("dilate",diff);//測試
步驟五:提取關鍵點 框選運動目標檢測
效果展示:車輛識別成功
//5 提取關鍵點 //5-1 查找特征點 vector<vector<Point>>contours; findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0)); //5-2 提取關鍵點 vector<vector<Point>>contours_poly(contours.size()); vector<Rect>boundRect(contours.size()); //5-3 確定下四個點來用於框選目標物體 int x,y,w,h; int num=contours.size(); for(int i = 0;i < num;i++) { approxPolyDP(Mat(contours[i]),contours_poly[i],3,true); //多邊擬合 boundRect[i]=boundingRect(Mat(contours_poly[i])); x=boundRect[i].x; y=boundRect[i].y; w=boundRect[i].width; h=boundRect[i].height; //繪制矩形 rectangle(resFrame,Point(x,y),Point(x+w,y+h),Scalar(0,0,255),2); }
三:車輛識別完整代碼
#include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; Mat moveCheck(Mat &frontFrame,Mat &afterFrame) { Mat resFrame,diff; Mat frontGray,afterGray; //克隆當前幀畫面 返回最終結果 resFrame = afterFrame.clone(); //1 灰度處理 目的 RGB三通道轉灰度單通道 壓縮到原圖片三分之一大小 cvtColor(frontFrame,frontGray,CV_RGB2GRAY); cvtColor(afterFrame,afterGray,CV_RGB2GRAY); //imshow("frontGray",frontGray); //imshow("afterGray",afterGray); //2 幀差處理 目的 找到幀與幀之間的差異(正在運動的物體) absdiff(frontGray,afterGray,diff); //imshow("diff",diff); //3 二值化處理 目的 將灰度圖繼續識別轉換為黑白分明的圖像 threshold(diff,diff,25,255,CV_THRESH_BINARY); //imshow("threshold",diff); //4 圖像降噪 //4-1 腐蝕處理 目的 去除白色噪點 Mat element = cv::getStructuringElement(MORPH_RECT,Size(3,3));//小於3*3方塊的白色噪點都會被腐蝕 erode(diff,diff,element); //imshow("erode",diff); //4-2 膨脹 目的 把白色區域變大 Mat element2=cv::getStructuringElement(MORPH_RECT,Size(20,20)); dilate(diff,diff,element2); //imshow("dilate",diff); //5 提取關鍵點 //5-1 查找特征點 vector<vector<Point>>contours; findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0)); //5-2 提取關鍵點 vector<vector<Point>>contours_poly(contours.size()); vector<Rect>boundRect(contours.size()); //5-3 確定下四個點來用於框選目標物體 int x,y,w,h; int num=contours.size(); for(int i = 0;i < num;i++) { approxPolyDP(Mat(contours[i]),contours_poly[i],3,true); //多邊擬合 boundRect[i]=boundingRect(Mat(contours_poly[i])); x=boundRect[i].x; y=boundRect[i].y; w=boundRect[i].width; h=boundRect[i].height; //繪制矩形 rectangle(resFrame,Point(x,y),Point(x+w,y+h),Scalar(0,0,255),2); } return resFrame; } int main(int argc, char *argv[]) { Mat frame; Mat temp; Mat res; int count = 0; VideoCapture cap("D:/00000000000003jieduanshipincailliao/carMove.mp4");//視頻路徑 while (cap.read(frame)) { count++; if(count == 1) { res = moveCheck(frame,frame); } else { res = moveCheck(temp,frame); } imshow("frame",frame); imshow("res",res);//最終車輛識別成果 temp = frame.clone(); waitKey(15); } return 0; }
當然,夜晚的車輛也能夠正常識別
不過,本次的幀差法的車輛識別存在弊端,隻要是運動的物體都會識別,比如,博主打開攝像頭,動一動手指頭,也會被框選識別,因此是有一定弊端的
不過,這種幀差法的運動目標檢測,在夜晚監控中是非常廣泛地應用到,因為有任何的風吹草動,都會被框選識別。
到此這篇關於OpenCV實現車輛識別和運動目標檢測的文章就介紹到這瞭,更多相關OpenCV車輛識別和運動目標檢測內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Qt+OpenCV利用幀差法實現車輛識別
- C++ OpenCV技術實戰之身份證離線識別
- OpenCV+python實現膨脹和腐蝕的示例
- C++ opencv圖像處理實現圖像腐蝕和膨脹示例
- OpenCV基於背景減除實現行人計數