92 lines
2.5 KiB
C++
92 lines
2.5 KiB
C++
#include<opencv2/opencv.hpp>
|
|
|
|
// all those colors are still visible on b/w (the first component is not so low)
|
|
auto WHITE = cv::Scalar(255,255,255);
|
|
auto BLUE = cv::Scalar(200,10,10);
|
|
auto MAGENTA = cv::Scalar(110,10,200);
|
|
|
|
// takes the two points that are more distant from the next, ie:
|
|
// i st distance(hull[i], hull[i+1]) is maximum and 2nd maximum
|
|
int* max2_distance(std::vector<cv::Point> hull)
|
|
{
|
|
int *idx = (int*) calloc(2, sizeof(int));
|
|
int distance[2];
|
|
for( unsigned i=0; hull.size()>i; i++ )
|
|
{
|
|
cv::Point thispoint=hull[i];
|
|
cv::Point nextpoint=hull[(i+1)%hull.size()];
|
|
int d=pow(thispoint.x-nextpoint.x,2)+pow(thispoint.y-nextpoint.y,2);
|
|
if( d>distance[0] ) //the biggest till now
|
|
{
|
|
idx[1]=idx[0];
|
|
idx[0]=i;
|
|
distance[1]=distance[0];
|
|
distance[0]=d;
|
|
}
|
|
else if( d>distance[1] ) // it is the second biggest till now
|
|
{
|
|
idx[1]=i;
|
|
distance[1]=d;
|
|
}
|
|
}
|
|
|
|
return idx;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
char const *fname = "files/masckera.png";
|
|
if( 1<argc )
|
|
fname = argv[1];
|
|
if( 2<argc) {
|
|
std::cerr << "Too many arguments" << std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
cv::Mat img;
|
|
img=cv::imread(fname,CV_LOAD_IMAGE_GRAYSCALE);
|
|
if( img.empty() ) {
|
|
std::cerr << "Error opening image, aborting" << std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
std::vector< std::vector<cv::Point> > contours;
|
|
std::vector<cv::Vec4i> hierarchy;
|
|
cv::findContours(img,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
|
|
|
|
cv::drawContours(img,contours,-1,cv::Scalar(255,255,255),5);
|
|
|
|
if( 0==contours.size() ) {
|
|
std::cerr << "No contours found" << std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
auto contour = contours[0];
|
|
if( 1!=contours.size() )
|
|
{
|
|
// choosing the biggest contour in the image
|
|
// you can test it with files/2contours.png
|
|
for(auto cont: contours) {
|
|
if(cont.size() > contour.size())
|
|
contour = cont;
|
|
}
|
|
}
|
|
|
|
std::vector<cv::Point> hull;
|
|
cv::convexHull(cv::Mat(contour),hull,false);
|
|
|
|
int *maxdistances = max2_distance(hull);
|
|
|
|
//img = cv::imread(fname,CV_LOAD_IMAGE_COLOR); // uncomment to this to display image with colors
|
|
unsigned short dotwidth = img.cols >> 6; // divide by 64, so efficient
|
|
cv::circle(img,hull[maxdistances[0]],dotwidth,MAGENTA,-1);
|
|
cv::circle(img,hull[(maxdistances[0]+1)%hull.size()],dotwidth,MAGENTA,-1);
|
|
cv::circle(img,hull[maxdistances[1]],dotwidth>>1,BLUE,-1);
|
|
cv::circle(img,hull[(maxdistances[1]+1)%hull.size()],dotwidth>>1,BLUE,-1);
|
|
|
|
cv::namedWindow("4 corners",CV_WINDOW_NORMAL);
|
|
cv::imshow("4 corners",img);
|
|
cv::waitKey(0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
// vim: set noet ts=4 sw=4:
|