Point identification complete
This commit is contained in:
parent
d044199220
commit
836270b9aa
3 changed files with 43 additions and 29 deletions
20
geometry.cpp
20
geometry.cpp
|
@ -110,3 +110,23 @@ is_above_line(cv::Vec<double,3> line, Point p)
|
||||||
{
|
{
|
||||||
return line(0)*p.x + line(1)*p.y + line(2) > 0;
|
return line(0)*p.x + line(1)*p.y + line(2) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Point
|
||||||
|
further_point_from_line(cv::Vec<double,3> line, std::vector<Point> 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;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ cv::Point unmap_point(double, cv::Point, cv::Point);
|
||||||
cv::Vec<double,3> get_line(cv::Point, cv::Point);
|
cv::Vec<double,3> get_line(cv::Point, cv::Point);
|
||||||
bool is_in_line(cv::Vec<double,3> line, cv::Point p);
|
bool is_in_line(cv::Vec<double,3> line, cv::Point p);
|
||||||
bool is_above_line(cv::Vec<double,3> line, cv::Point p);
|
bool is_above_line(cv::Vec<double,3> line, cv::Point p);
|
||||||
|
cv::Point further_point_from_line(cv::Vec<double,3>, std::vector<cv::Point>);
|
||||||
|
|
||||||
class CoordinateSystem
|
class CoordinateSystem
|
||||||
{
|
{
|
||||||
|
|
51
lines.cpp
51
lines.cpp
|
@ -44,7 +44,6 @@ int main(int argc, char *argv[])
|
||||||
cv::findContours(img,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
|
cv::findContours(img,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
|
||||||
|
|
||||||
unsigned short dotwidth = img.cols >> 6; // divide by 64, so efficient
|
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);
|
cv::drawContours(img,contours,-1,BROWN,dotwidth>>4);
|
||||||
|
|
||||||
if( 0==contours.size() ) {
|
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
|
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 << "Maxdist1:" << maxdistances[0] << " " << corn_1 << corn_2 << std::endl;
|
||||||
std::cout << "Maxdist2:" << maxdistances[1] << " " << corn_3 << corn_4 << 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::namedWindow("win", CV_GUI_NORMAL);
|
||||||
// cv::imshow("4 corners",img);
|
// cv::imshow("4 corners",img);
|
||||||
// cv::waitKey(0);
|
// 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]));
|
verticals.push_back(find_longest_line(hull, (maxdistances[1]+1)%hull.size(), maxdistances[0]));
|
||||||
free(maxdistances);
|
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
|
// theta is the angle of the line connecting point 1 and 2; it will be the
|
||||||
// rotation of our new coordinate system
|
// 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);
|
auto cs = CoordinateSystem(corn_1, corn_2);
|
||||||
assert(cs.map(corn_1).x == 0);
|
assert(cs.map(corn_1).x == 0);
|
||||||
assert(cs.map(corn_1).y == 0);
|
assert(cs.map(corn_1).y == 0);
|
||||||
|
@ -122,24 +99,40 @@ int main(int argc, char *argv[])
|
||||||
cv::Vec<double,3> diag1, diag2;
|
cv::Vec<double,3> diag1, diag2;
|
||||||
diag1 = get_line(cs.map(corn_1), cs.map(corn_3));
|
diag1 = get_line(cs.map(corn_1), cs.map(corn_3));
|
||||||
diag2 = get_line(cs.map(corn_4), cs.map(corn_2));
|
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 diag1: " << diag1 << std::endl;
|
||||||
std::cout << "mapped diag2: " << diag2 << std::endl;
|
std::cout << "mapped diag2: " << diag2 << std::endl;
|
||||||
|
|
||||||
|
std::vector<cv::Point> points1, points2;
|
||||||
for(cv::Point p: contour)
|
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);
|
cv::Point mapped = cs.map(p);
|
||||||
if(is_above_line(diag1, mapped) == is_above_line(diag2, mapped)) {
|
if(is_above_line(diag1, mapped)) {
|
||||||
cv::circle(img, p, dotwidth>>3, YELLOW,-1);
|
if(is_above_line(diag2, mapped)) {
|
||||||
|
points1.push_back(p);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(!is_above_line(diag2, mapped)) {
|
||||||
|
points2.push_back(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#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);
|
cv::imshow("win",img);
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
if( cv::waitKey(0) == 113 )
|
if( (char)cv::waitKey(0) == 113 )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
img.release();
|
img.release();
|
||||||
|
|
Loading…
Reference in a new issue