私は3つの幾何学的形態の三角形の円と五角形を検出したいビデオを実行しています.ここではこのビデオのフレームと私が得た結果:
正しい結果
多くの中から 1 つの悪い結果。
ここに私のコードがあります:
img =src;
cv::Moments mom;
cv::Mat result(img.size(),CV_8U,cv::Scalar(255));
cv::threshold(img,img,127,255,CV_THRESH_BINARY_INV);
cv::findContours(img,contours,/*hiararchy,*/CV_RETR_LIST, CV_CHAIN_APPROX_NONE );
for ( int i=0; i<contours.size();i++){
cv::approxPolyDP(cv::Mat(contours[i]),approx,(cv::arcLength(cv::Mat(contours[i]),true)*.02),true);
switch(approx.size()){
case 8: // should be a circle
cv::minEnclosingCircle(cv::Mat(contours[i]),center,radius);
cv::circle(src,cv::Point(center),static_cast<int> (radius),cv::Scalar(255,255,0),3,3);
mom= cv::moments(cv::Mat(contours[i]));
// draw mass center
cv::circle(result,
// position of mass center converted to integer
cv::Point(mom.m10/mom.m00,mom.m01/mom.m00),
2,cv::Scalar(0,0,255),2);// draw black dot
break;
case 3: // should be a triangle
poly.clear();
cv::approxPolyDP(cv::Mat(contours[i]),poly,
5, // accuracy of the approximation
true); // yes it is a closed shape
// Iterate over each segment and draw it
itp= poly.begin();
while (itp!=(poly.end()-1)) {
cv::line(src,*itp,*(itp+1),cv::Scalar(0,255,255),2);
++itp;
}
// last point linked to first point
cv::line(src,*(poly.begin()),*(poly.end()-1),cv::Scalar(100,255,100),2);
mom= cv::moments(cv::Mat(contours[i]));
// draw mass center
cv::circle(result,
// position of mass center converted to integer
cv::Point(mom.m10/mom.m00,mom.m01/mom.m00),
2,cv::Scalar(0,0,255),2);// draw black dot
break;
case 5 :// should be a pentagon
poly.clear();
cv::approxPolyDP(cv::Mat(contours[i]),poly,
5, // accuracy of the approximation
true); // yes it is a closed shape
// Iterate over each segment and draw it
itp= poly.begin();
while (itp!=(poly.end()-1)) {
cv::line(src,*itp,*(itp+1),cv::Scalar(0,0,255),2);
++itp;
}
// last point linked to first point
cv::line(src,*(poly.begin()),*(poly.end()-1),cv::Scalar(255,0,0),2);
mom= cv::moments(cv::Mat(contours[i]));
// draw mass center
cv::circle(result,
// position of mass center converted to integer
cv::Point(mom.m10/mom.m00,mom.m01/mom.m00),
2,cv::Scalar(0,0,255),2);// draw black dot
break;
default :
contours[i].clear();
}
// iterate over all contours
int j = 0;
for( int i = 0; i < contours.size();i++) {
if ( !contours[i].empty()){
// compute all moments
j++; // At the end j should be 3
}
if(j ==3 ){
cv::drawContours(result,contours,-1, // draw all contours
cv::Scalar(0), // in black
2); // with a thickness of 2
cv::imshow("result",result);
}
} std::cout<<j<<std::endl;
return j;
}
これを解決する方法はありますか?ありがとう!