您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“c#如何實現車輛的輪廓識別”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“c#如何實現車輛的輪廓識別”這篇文章吧。
場景
實現了車輛的輪廓識別,并且已經提取輪廓的最小矩形范圍,現在需要知道車尾離矩形最近的兩個點,可能有點大材小用
代碼
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <vector>
using namespace cv;
using namespace std;
void Dilate( InputArray src, OutputArray dst)
{
int dilation_type = MORPH_RECT;
int dilation_size = 10;
Mat dielem = getStructuringElement( dilation_type,
Size( 2*dilation_size + 1, 2*dilation_size+1 ),
Point( dilation_size, dilation_size ) );
///膨脹操作
dilate( src, dst, dielem );
}
/*
該函數主要是捕獲圖片中完整出現輪廓的車輛,判斷條件為
車輛的輪廓的Y坐標不能大于圖片的長度,其次過濾掉面積過小
的輪廓,很可能是車鏡或者幀間差分將車輛拆分成兩段的誤差
*/
void CaptureCompleteVehicle(Mat &srcMat, Mat &grayMat)
{
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(grayMat, contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_NONE,Point());
Mat dstMat=Mat::zeros(grayMat.size(),CV_8UC1);
Mat contourMat;
srcMat.copyTo(contourMat);
int picHeight = grayMat.size().height;
bool bTouchBotton = false;
bool bTouchTop = false;
vector<Moments> mu(contours.size());
for (int i=0; i<contours.size(); i++)
{
mu[i] = moments(contours[i], false);
}
vector<Point2f> mc(contours.size());
for (int i=0; i<contours.size(); i++)
{
mc[i] = Point2d(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
}
for(int i=0; i<contours.size(); i++)
{
if (contourArea(contours[i]) < 10000) continue;
bTouchBotton = false;
bTouchTop = false;
for (int k=0; k<contours[i].size(); k++)
{
Point2f pos = contours[i][k];
if ((pos.y +10) > picHeight)
{
bTouchBotton = true;
break;
}
if (pos.y == 0)
{
bTouchTop = true;
break;
}
}
if (bTouchBotton || bTouchTop) continue;
drawContours(dstMat, contours, i, Scalar(255, 0, 0), 1, 8, hierarchy);
RotatedRect rect=minAreaRect(contours[i]);
Point2f P[4];
rect.points(P);
int leftBottonIndex = 0;
for(int j=0; j<=3; j++)
{
line(contourMat, P[j], P[(j+1)%4], Scalar(255, 0, 0), 2);
if ((P[j].x < mc[i].x) && (P[j].y > mc[i].y))
{
leftBottonIndex = j;
}
}
cv::Rect re(P[leftBottonIndex].x - 20, P[leftBottonIndex].y - 20 , 40, 40);
rectangle(contourMat, re, Scalar(0, 255, 0), 4);
circle(contourMat, mc[i], 5, Scalar(0, 0, 255), -1, 8, 0);
}
imshow("NewAreaRect", contourMat);
}
int main(int argc,char *argv[])
{
VideoCapture videoCap("E:/smoky-cars/positive/大慶東路與水機路交叉口(東北)_冀BU0157_02_141502_01_3_50.wh364");
if(!videoCap.isOpened()) return -1;
double videoFPS=videoCap.get(CV_CAP_PROP_FPS); //獲取幀率
double videoPause=1000/videoFPS;
Mat framePrePre; //上上一幀
Mat framePre; //上一幀
Mat frameNow; //當前幀
Mat frameDet; //運動物體
videoCap>>framePrePre;
videoCap>>framePre;
cvtColor(framePrePre,framePrePre,CV_RGB2GRAY);
cvtColor(framePre,framePre,CV_RGB2GRAY);
int save=0;
while(true)
{
videoCap>>frameNow;
if(frameNow.empty()||waitKey(videoPause)==27) break;
cvtColor(frameNow,frameNow,CV_RGB2GRAY);
Mat Det1;
Mat Det2;
absdiff(framePrePre,framePre,Det1); //幀差1
absdiff(framePre,frameNow,Det2); //幀差2
threshold(Det1,Det1,0,255,CV_THRESH_OTSU); //自適應閾值化
threshold(Det2,Det2,0,255,CV_THRESH_OTSU);
Mat element=getStructuringElement(0,Size(3,3)); //膨脹核
dilate(Det1,Det1,element); //膨脹
dilate(Det2,Det2,element);
bitwise_and(Det1,Det2,frameDet);
framePrePre=framePre;
framePre=frameNow;
Dilate(frameDet, frameDet);
CaptureCompleteVehicle(frameNow, frameDet);
waitKey(1000);
}
return 0;
}
以上是“c#如何實現車輛的輪廓識別”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。