처음 게시 할 때 올바른 방법으로 코드를 삽입하시기 바랍니다.OpenCV는 큰 윤곽선 주위에 직사각형을 그립니까?
저는 비디오에서 차량을 감지하고 계산하려고합니다. 따라서 아래 코드를 보면 thresholding 및 dilating 후 이미지의 윤곽선을 찾은 다음 drawContours와 rectangle을 사용하여 주위에 상자를 그립니다 검출 된 윤곽.
사각형의 영역이 40,000보다 크지 않은 경우 drawContours/rectangle if 문에 필터를 넣으려고했다가 그려 보지 않았습니다.
이제 내가 첨부 한 그림을 보면 큰 직사각형 안에 그려지는 직사각형이 있음을 알 수 있습니다. 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);
}
문제없이 읽을 수 있도록 코드를 포맷 해주십시오. – DarkCygnus