1 | initial version |
i've answered a smilar question before.
i trial code based on convexityDefects gives you some key points.maybe you will improve it.
result images :
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
Mat src = imread( argv[1] );
if (src.empty())
return -1;
Mat bw;
cvtColor( src, bw, COLOR_BGR2GRAY );
bw = bw < 60;
// Find contours
vector<vector<Point> > contours;
vector<int> contoursHull;
vector<Vec4i> defects;
findContours( bw, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
for ( size_t i = 0; i < contours.size(); i++)
{
if( contourArea(contours[i]) > 500 )
{
approxPolyDP(contours[i],contours[i],9,true);
convexHull(contours[i], contoursHull,true);
convexityDefects(contours[i], contoursHull,defects);
for ( size_t j = 0; j < defects.size(); j++)
{
Vec4i defpoint = defects[j];
circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
}
}
}
imshow("result", src);
waitKey();
return 0;
}
2 | No.2 Revision |
i've answered a smilar question before.
i trial code based on convexityDefects gives you some key points.maybe you will improve it.it or i will try to improve when i find time.
(also see smilar question i've answered with almost same code before.)
result images :
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
Mat src = imread( argv[1] );
if (src.empty())
return -1;
Mat bw;
cvtColor( src, bw, COLOR_BGR2GRAY );
bw = bw < 60;
// Find contours
vector<vector<Point> > contours;
vector<int> contoursHull;
vector<Vec4i> defects;
findContours( bw, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
for ( size_t i = 0; i < contours.size(); i++)
{
if( contourArea(contours[i]) > 500 )
{
approxPolyDP(contours[i],contours[i],9,true);
convexHull(contours[i], contoursHull,true);
convexityDefects(contours[i], contoursHull,defects);
for ( size_t j = 0; j < defects.size(); j++)
{
Vec4i defpoint = defects[j];
circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
}
}
}
imshow("result", src);
waitKey();
return 0;
}
3 | No.3 Revision |
a trial code based on convexityDefects gives you some key points.maybe you will improve it or i will try to improve when i find time.
(also see smilar question i've answered with almost same code before.)
result images :
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
Mat src = imread( argv[1] );
if (src.empty())
return -1;
Mat bw;
cvtColor( src, bw, COLOR_BGR2GRAY );
bw = bw < 60;
// Find contours
vector<vector<Point> > contours;
vector<int> contoursHull;
vector<Vec4i> defects;
findContours( bw, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
for ( size_t i = 0; i < contours.size(); i++)
{
if( contourArea(contours[i]) > 500 )
{
approxPolyDP(contours[i],contours[i],9,true);
convexHull(contours[i], contoursHull,true);
convexityDefects(contours[i], contoursHull,defects);
for ( size_t j = 0; j < defects.size(); j++)
{
Vec4i defpoint = defects[j];
circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
}
}
}
imshow("result", src);
waitKey();
return 0;
}
EDIT 1: i tried to improve my solution by checking nonzero pixels count around the defect point.
result is perfect for the test images.
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
Mat src = imread( argv[1] );
if (src.empty())
return -1;
Mat bw;
cvtColor( src, bw, COLOR_BGR2GRAY );
bw = bw < 60;
// Find contours
vector<vector<Point> > contours;
vector<int> contoursHull;
vector<Vec4i> defects;
findContours( bw.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
for ( size_t i = 0; i < contours.size(); i++)
{
if( contourArea(contours[i]) > 500 )
{
approxPolyDP(contours[i],contours[i],2,true);
convexHull(contours[i], contoursHull,true);
convexityDefects(contours[i], contoursHull,defects);
for ( size_t j = 0; j < defects.size(); j++)
{
Vec4i defpoint = defects[j];
Point pt = contours[i][defpoint[2]]; // get defect point
Rect r3x3(pt.x-2, pt.y-2, 5, 5 ); // create 5x5 Rect from defect point
// maybe no need but to be sure that the rect is in the image
r3x3 = r3x3 & Rect(0, 0, bw.cols, bw.rows );
int non_zero_pixels = countNonZero( bw(r3x3) );
cout << non_zero_pixels << endl;
if( non_zero_pixels > 17 )
circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
}
}
}
imshow("result", src);
waitKey();
return 0;
}
4 | No.4 Revision |
a trial code based on convexityDefects gives you some key points.maybe you will improve it or i will try to improve when i find time.
(also see smilar question i've answered with almost same code before.)
result images :
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
Mat src = imread( argv[1] );
if (src.empty())
return -1;
Mat bw;
cvtColor( src, bw, COLOR_BGR2GRAY );
bw = bw < 60;
// Find contours
vector<vector<Point> > contours;
vector<int> contoursHull;
vector<Vec4i> defects;
findContours( bw, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE RETR_EXTERNAL, CHAIN_APPROX_NONE );
for ( size_t i = 0; i < contours.size(); i++)
{
if( contourArea(contours[i]) > 500 )
{
approxPolyDP(contours[i],contours[i],9,true);
convexHull(contours[i], contoursHull,true);
convexityDefects(contours[i], contoursHull,defects);
for ( size_t j = 0; j < defects.size(); j++)
{
Vec4i defpoint = defects[j];
circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
}
}
}
imshow("result", src);
waitKey();
return 0;
}
EDIT 1: i tried to improve my solution by checking nonzero pixels count around the defect point.
result is perfect for the test images.
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
Mat src = imread( argv[1] );
if (src.empty())
return -1;
Mat bw;
cvtColor( src, bw, COLOR_BGR2GRAY );
bw = bw < 60;
// Find contours
vector<vector<Point> > contours;
vector<int> contoursHull;
vector<Vec4i> defects;
findContours( bw.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE RETR_EXTERNAL, CHAIN_APPROX_NONE );
for ( size_t i = 0; i < contours.size(); i++)
{
if( contourArea(contours[i]) > 500 )
{
approxPolyDP(contours[i],contours[i],2,true);
convexHull(contours[i], contoursHull,true);
convexityDefects(contours[i], contoursHull,defects);
for ( size_t j = 0; j < defects.size(); j++)
{
Vec4i defpoint = defects[j];
Point pt = contours[i][defpoint[2]]; // get defect point
Rect r3x3(pt.x-2, pt.y-2, 5, 5 ); // create 5x5 Rect from defect point
// maybe no need but to be sure that the rect is in the image
r3x3 = r3x3 & Rect(0, 0, bw.cols, bw.rows );
int non_zero_pixels = countNonZero( bw(r3x3) );
cout << non_zero_pixels << endl;
if( non_zero_pixels > 17 )
circle(src,contours[i][defpoint[2]],2,Scalar(0,255,0),1);
}
}
}
imshow("result", src);
waitKey();
return 0;
}