sagoma/lines.cpp

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: