第一次发帖,希望我以正确的方式放置代码。
我试图检测和计算视频中的车辆,所以如果你看下面我的代码,我会在阈值和扩张后找到图像的轮廓,然后我用drawContours和矩形画一个盒子围绕检测到的轮廓。
我试着在drawContours / rectangle if语句中添加一个过滤器,说明矩形区域是否大于40,000,然后不要绘制它。
现在,如果你看一下我附上的图片,你会发现在较大的矩形内画有矩形,我不想这样做。 enter image description here。这些矩形的面积小于40,000但是由于某种原因它们被绘制。
我打算使用矩形来计算图像上的汽车,但如果这不是最好的方法,我可以接受建议。
感谢。
using namespace cv;
using namespace std;
int main()
{
VideoCapture TestVideo; //Declare video capture
Mat frame; //declare Mat as frame to grab
TestVideo.open("FroggerHighway.mp4"); //open the test video from the project directory
if (!TestVideo.isOpened()) //If its not open declare the error
{
cout << "Video did not open." << endl;
waitKey(0);
}
if (TestVideo.get(CV_CAP_PROP_FRAME_COUNT) < 1) //If the frame count is less than 1, basically an error checker
{
cout << "Video file must have at least one frame." << endl;
waitKey(0);
}
TestVideo.read(frame); //read the first frame
Mat frameGray = Mat::zeros(frame.size(), CV_8UC1); //Convert frame source to gray
cvtColor(frame, frameGray, CV_BGR2GRAY);
Mat frame2 = Mat::zeros(frameGray.size(), frameGray.type()); //Intermediate frame
Mat framediff; //Frame differencing
Mat thresh;
Mat element; //Element used for morphOps (dilation)
Mat dil;
while (TestVideo.isOpened() & waitKey(30) != 27) //while the video is open, show the frame, press escape to end video
{
absdiff(frameGray, frame2, framediff); //take absolute difference of both frames
threshold(framediff, thresh, 22, 255, CV_THRESH_BINARY); //If absdiff is greater than 22, turn it white.
namedWindow("Gray", CV_WINDOW_NORMAL); //Display gray video
imshow("Gray", frameGray);
namedWindow("FrameDiff", CV_WINDOW_NORMAL); //Show frame difference before threshold/dilation
imshow("FrameDiff", framediff);
namedWindow("Threshold", CV_WINDOW_NORMAL); //Show thresholded video
imshow("Threshold", thresh);
element = getStructuringElement(MORPH_CROSS, //morphOps dilation
Size(2 * 5 + 1, 2 * 5 + 1),
Point(5, 5));
dilate(thresh, dil, element, Point(-1, -1), 1, 1, 1);
namedWindow("Dilation", CV_WINDOW_NORMAL); //Show dilated video.
imshow("Dilation", dil);
//Apply findCountours function to draw countours and count the objects.
vector<vector<Point> > contours; //Not sure what this does but it works
findContours(dil, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); //(outout image, hierarchy, and 2 ways to calculate it)
vector<vector<Point> > contours_poly(contours.size()); //Also not sure what this does
vector<Rect> boundRect(contours.size()); //This is used to approximate a polygon to fit the contours it calculated I think
Mat output = Mat::zeros(dil.rows, dil.cols, CV_8UC3);
int counter = 0; //Used to count # of rectangle drawn
for (int i = 0; i < contours.size(); i++)
{
approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true); //Approximates a polygon to fit the contours calculated ?
boundRect[i] = boundingRect(Mat(contours_poly[i])); //for each approximation, a bounding rectangle is sorted around the contour ?
if ((boundRect[i].x * boundRect[i].y) > 40000) //If the bounding rectangle has an area less than 40,000 then just ignore it completely
{
counter = counter + 1;
drawContours(output, contours, i, Scalar(255, 255, 255), -3); //(input, countors, contour to be drawn, color of it, thickness (negative fills image));
rectangle(output, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 0, 255), 2, 8, 0); //Draws the actual rectangle around the contours
}
}
cout << "Rectangles Drawn: " << counter << endl;
namedWindow("Output", CV_WINDOW_NORMAL);
imshow("Output", output);
if (((TestVideo.get(CV_CAP_PROP_POS_FRAMES) + 1) < TestVideo.get(CV_CAP_PROP_FRAME_COUNT)) & (waitKey(30) != 27)) //Move the frame count up 1, show the frame
{
TestVideo.read(frame);
frameGray.copyTo(frame2); //MUST USE copyTo, or clone! Can't do frame2 = frameGray*
cvtColor(frame, frameGray, CV_BGR2GRAY);
}
else
{
cout << "End of Video" << endl;
waitKey(0);
break;
}
waitKey(30); //wait 30ms between showing each frame
}
return (0);
}
答案 0 :(得分:5)
您需要将x
和y
坐标相乘以获得矩形区域,您应该将width
和height
相乘。
//If the bounding rectangle has an area less than 40,000 then just ignore it completely
if ((boundRect[i].width * boundRect[i].height) > 40000)
{
// code here
}