C++调用opencv完成运动目标捕捉
使用編譯器:Qt Creator 4.2.1?
目錄
一、原理說明:
二、過程詳解:
1.將傳入的兩幀先進行灰度處理,轉化將rgb類型圖片轉化為灰度圖,可大大降低處理時間和資源消耗
2.將兩幀圖片進行差幀處理
3.將圖像二值化,只有黑和白,便于計算機計算,但是會產生噪點(后續會進行簡單的降噪操作)
4.腐蝕處理,腐蝕掉*x方塊大小的像素,我這里設置了4*4,清除大部分噪點
5. 膨脹處理,把去除過噪點的像素圖像膨脹,變大,我這里膨脹了30*30
6.將變動過的像素目標打上標記(注意要在原幀上進行標記)
?三、代碼
一、原理說明:
????????差幀識別原理:將這一幀的圖像和上一幀的圖像進行比對,產生變化的即為運動的目標像素塊
二、過程詳解:
1.將傳入的兩幀先進行灰度處理,轉化將rgb類型圖片轉化為灰度圖,可大大降低處理時間和資源消耗
將轉換后的圖片轉存至frontGray和afterGray
cvtColor(frontFrame,frontGray,CV_BGR2GRAY);cvtColor(afterFrame,afterGray,CV_BGR2GRAY);2.將兩幀圖片進行差幀處理
將有差別的像素轉存至diff
//幀差處理 找到兩幀之間運動物體差異//缺點:會捕捉所有運動的物體,沒辦法專門捕捉某個目標absdiff(frontGray,afterGray,diff);?效果如下:
3.將圖像二值化,只有黑和白,便于計算機計算,但是會產生噪點(后續會進行簡單的降噪操作)
//二值化: 使其變得更加黑白分明,便于計算,會產生噪點threshold(diff,diff,25,255,CV_THRESH_BINARY);效果如下:
一個個單獨的小白點就是噪點,是因為光線反光和樹葉的晃動4.腐蝕處理,腐蝕掉<x*x方塊大小的像素,我這里設置了4*4,清除大部分噪點
//腐蝕處理:去除大部分的白色噪點Mat element = cv::getStructuringElement(MORPH_RECT,Size(4,4));//小于4*4方塊的白色噪點都會被腐蝕erode(diff,diff,element);效果如下,噪點確實少了很多,但是運動的物體也被腐蝕掉了很多,可能會出現漏掉運動物體的情況
可以發現,噪點幾乎沒有了,但是車輛的像素也被腐蝕了?
5. 膨脹處理,把去除過噪點的像素圖像膨脹,變大,我這里膨脹了30*30
//膨脹處理:將白色區域變"胖",便于識別Mat element2=cv::getStructuringElement(MORPH_RECT,Size(30,30));dilate(diff,diff,element2);效果如下:
小像素變成“大果粒”了6.將變動過的像素目標打上標記(注意要在原幀上進行標記)
//動態物體標記vector<vector<Point>>contours;//用于保存關鍵點findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));//提取關鍵點vector<vector<Point>>contours_poly(contours.size());vector<Rect>boundRect(contours.size());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,255,0),2);}效果如下:
實際效果,偶爾有樹葉飄動會產生一點點干擾?三、代碼
#include <iostream> #include <opencv2/opencv.hpp> using namespace cv; using namespace std;Mat moveCheck(Mat &frontFrame,Mat &afterFrame) {Mat frontGray,afterGray,diff;Mat resFrame=afterFrame.clone();//灰度處理,節省運算時間cvtColor(frontFrame,frontGray,CV_BGR2GRAY);cvtColor(afterFrame,afterGray,CV_BGR2GRAY);//幀差處理 找到兩幀之間運動物體差異//缺點:會捕捉所有運動的物體,沒辦法專門捕捉某個目標absdiff(frontGray,afterGray,diff);//二值化: 使其變得更加黑白分明,便于計算,會產生噪點threshold(diff,diff,25,255,CV_THRESH_BINARY);//腐蝕處理:去除大部分的白色噪點Mat element = cv::getStructuringElement(MORPH_RECT,Size(4,4));//小于4*4方塊的白色噪點都會被腐蝕erode(diff,diff,element);//膨脹處理:將白色區域變"胖",便于識別Mat element2=cv::getStructuringElement(MORPH_RECT,Size(30,30));dilate(diff,diff,element2);//動態物體標記vector<vector<Point>>contours;//用于保存關鍵點findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));//提取關鍵點vector<vector<Point>>contours_poly(contours.size());vector<Rect>boundRect(contours.size());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,255,0),2);}return resFrame; }int main(int argc, char *argv[]) {Mat frame;Mat temp;Mat res;int num=0;VideoCapture cap("D:/VideoTraining/carMove.mp4");while (cap.read(frame)){num++;if(num==1){//如果為第一幀則把當前幀傳入(即不產生效果)res=moveCheck(frame,frame);}else{//從第二幀開始才有差幀res=moveCheck(temp,frame);}temp=frame.clone();//此處注意要調用.clone深拷貝,否則會出現兩個畫面一樣的情況imshow("frame",frame);imshow("res",res);waitKey(25);}return 0; }?QT下配置opencv可以看看這一篇:
Qt下配置opencv環境_一個不同的ID的博客-CSDN博客opencv在QT下調用,環境配置https://blog.csdn.net/baidu_38326512/article/details/124235789?spm=1001.2014.3001.5502
識別特定目標可以看看這一篇:
C++使用opencv調用級聯分類器來識別目標物體_一個不同的ID的博客-CSDN博客前言:相較于幀差法捕捉目標物體識別,級聯分類器識別目標物體更加具有針對性,使用前者只要是動的物體都會被捕捉識別到,畫面里有一點風吹草動,都會被捕捉識別下來,如果我想識別具體的人或者物,都無法做到精準的目標識別,所以有了級聯分類器識別(即模型識別),會按照訓練好的級聯分類器(模型)來進行目標識別流程講解:1.創建一個級聯分類器對象創建一個級聯分類器對象,并讀取已經已經訓練好的模型 CascadeClassifier cascade;//級聯分類器(模型) cascadehttps://blog.csdn.net/baidu_38326512/article/details/124271434您的支持就是我最大的動力!看完記得點個贊哦!
總結
以上是生活随笔為你收集整理的C++调用opencv完成运动目标捕捉的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NginX and Riak
- 下一篇: ubuntu更新软件包