diff --git a/geometry.cpp b/geometry.cpp index 93df776..456c1f3 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -110,3 +110,23 @@ is_above_line(cv::Vec line, Point p) { return line(0)*p.x + line(1)*p.y + line(2) > 0; } + +cv::Point +further_point_from_line(cv::Vec line, std::vector points) +{ + //distance = abs(a*p.x+b*p.y+c) / sqrt(a^2+b^2) + double denom = sqrt(line(0)*line(0)+line(1)*line(1)); + Point further = points[0]; + double maxdist = -1; + std::cout << "--- further" << std::endl; + for(Point p: points) + { + double numerator = abs(line(0)*p.x + line(1)*p.y + line(2)); + double distance = numerator/denom; + if(distance > maxdist) { + maxdist = distance; + further = p; + } + } + return further; +} diff --git a/geometry.h b/geometry.h index 9eb6143..3fc079f 100644 --- a/geometry.h +++ b/geometry.h @@ -11,6 +11,7 @@ cv::Point unmap_point(double, cv::Point, cv::Point); cv::Vec get_line(cv::Point, cv::Point); bool is_in_line(cv::Vec line, cv::Point p); bool is_above_line(cv::Vec line, cv::Point p); +cv::Point further_point_from_line(cv::Vec, std::vector); class CoordinateSystem { diff --git a/lines.cpp b/lines.cpp index 7d00930..e37fea1 100644 --- a/lines.cpp +++ b/lines.cpp @@ -44,7 +44,6 @@ int main(int argc, char *argv[]) cv::findContours(img,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE); unsigned short dotwidth = img.cols >> 6; // divide by 64, so efficient - //img = cv::imread(fname,CV_LOAD_IMAGE_COLOR); // uncomment to this to display image with colors cv::drawContours(img,contours,-1,BROWN,dotwidth>>4); if( 0==contours.size() ) { @@ -77,10 +76,6 @@ int main(int argc, char *argv[]) img = cv::imread(fname,CV_LOAD_IMAGE_COLOR); // uncomment to this to display image with colors std::cout << "Maxdist1:" << maxdistances[0] << " " << corn_1 << corn_2 << std::endl; std::cout << "Maxdist2:" << maxdistances[1] << " " << corn_3 << corn_4 << std::endl; - cv::circle(img,corn_1,dotwidth>>1,MAGENTA,2); - cv::circle(img,corn_2,dotwidth>>2,MAGENTA,2); - cv::circle(img,corn_3,dotwidth>>2,BROWN,2); - cv::circle(img,corn_4,dotwidth>>2,BROWN,2); cv::namedWindow("win", CV_GUI_NORMAL); // cv::imshow("4 corners",img); // cv::waitKey(0); @@ -94,26 +89,8 @@ int main(int argc, char *argv[]) verticals.push_back(find_longest_line(hull, (maxdistances[1]+1)%hull.size(), maxdistances[0])); free(maxdistances); -#ifdef _DEBUG - //img = cv::imread(fname,CV_LOAD_IMAGE_COLOR); // uncomment to this to display image with colors - auto color = MAGENTA; - for( auto line: verticals ) - { - color = (color==BLUE) ? MAGENTA : BLUE; //flip color for the two lines - cv::Point p1 = line[0]; - cv::Point p2 = line[line.size()-1]; - cv::line(img, p1, p2, color, dotwidth>>4); - std::cout << "vertical: " << line[0] << line[line.size()-1] << std::endl; - for(cv::Point p: line) - { - cv::circle(img,p,dotwidth>>3,color,-1); - } - } -#endif - // theta is the angle of the line connecting point 1 and 2; it will be the // rotation of our new coordinate system - double theta = atan(((double)corn_2.y-corn_1.y) / ((double)corn_2.x-corn_1.x)); auto cs = CoordinateSystem(corn_1, corn_2); assert(cs.map(corn_1).x == 0); assert(cs.map(corn_1).y == 0); @@ -122,24 +99,40 @@ int main(int argc, char *argv[]) cv::Vec diag1, diag2; diag1 = get_line(cs.map(corn_1), cs.map(corn_3)); diag2 = get_line(cs.map(corn_4), cs.map(corn_2)); - cv::line(img, corn_1, corn_3, BLUE, dotwidth>>4); - cv::line(img, corn_2, corn_4, MAGENTA, dotwidth>>4); std::cout << "mapped diag1: " << diag1 << std::endl; std::cout << "mapped diag2: " << diag2 << std::endl; + std::vector points1, points2; for(cv::Point p: contour) - { + { // the point is interesting where it is above both lines or below both lines cv::Point mapped = cs.map(p); - if(is_above_line(diag1, mapped) == is_above_line(diag2, mapped)) { - cv::circle(img, p, dotwidth>>3, YELLOW,-1); + if(is_above_line(diag1, mapped)) { + if(is_above_line(diag2, mapped)) { + points1.push_back(p); + } + } else { + if(!is_above_line(diag2, mapped)) { + points2.push_back(p); + } } } #ifdef _DEBUG + cv::Point middle1 = further_point_from_line(get_line(corn_1, corn_2), points2); + cv::Point middle2 = further_point_from_line(get_line(corn_3, corn_4), points1); + cv::line(img, corn_1, middle1, MAGENTA, dotwidth>>3); + cv::line(img, corn_2, middle1, MAGENTA, dotwidth>>3); + cv::line(img, middle1, middle2, BLACK, dotwidth>>4); + cv::line(img, corn_3, middle2, MAGENTA, dotwidth>>3); + cv::line(img, corn_4, middle2, MAGENTA, dotwidth>>3); + cv::line(img, corn_2, corn_3, BLUE, dotwidth>>4); + cv::line(img, corn_1, corn_4, BLUE, dotwidth>>4); + std::cout << middle1 << middle2 << std::endl; + cv::imshow("win",img); while(1) { - if( cv::waitKey(0) == 113 ) + if( (char)cv::waitKey(0) == 113 ) break; } img.release();