在“学习OpenCV3"的QQ群众,网友且行且珍惜针对前期博客(https://www.cnblogs.com/jsxyhelu/p/9345590.html)中的内容提出了以下问题:
比如这张图,利用PCA求出了特征向量之后,我想要求解与轮廓的交点,不知道有没有简单的方法@禾老师
非常好的问题!在寻找到轮廓的”主方向“后,往往下一个动作就是寻找向量和轮廓的交点,因为往往这才是我们更关心的地方。为了解决这个问题,我认为的思路应该是这样的:
1、首先要界定范围。对于交点来说,肯定是在这个轮廓的“最小外接矩形”中的,所以先求出外接矩形作为限定;
2、向量只是一个方向,要将其变成一条直线(如果在“最小外接矩形”中就是线段),推荐使用LineIterator来表示直线;
3、最后,判断这条线段上的点是否在轮廓上,可以使用pointpolytest函数。
结合代码具体讲解。为了凸显本文知识重点,本文采用以下一幅图像来说明算法
最后得到的结果是这样的,其中黄点为主方向向量和外界矩形交点,红点为和轮廓交点。
全部代码为:
;
;
vector ;i,,THRESH_OTSU,,));
, CV_64FC1);; i ) ) , ),
pca_analysis.mean.at, )); ); );
; i ; ),
pca_analysis.eigenvectors.at));
eigen_val[i] );
}
line(src, pos . ].x ],eigen_vecs[].y ]),
pos. ].x ],eigen_vecs[].y ]) , Scalar(, , ));].y].x; ,Scalar(,,),);
circle(src,pt2,,Scalar(,,),);
);
; i )
circle(src,pt,,Scalar(,,),);
}
waitKey();
;
}
;
vector ;i,,THRESH_OTSU,,));
, CV_64FC1);; i ) ) , ),
pca_analysis.mean.at, )); ); );
; i ; ),
pca_analysis.eigenvectors.at));
eigen_val[i] );
}
line(src, pos . ].x ],eigen_vecs[].y ]),
pos. ].x ],eigen_vecs[].y ]) , Scalar(, , ));].y].x; ,Scalar(,,),);
circle(src,pt2,,Scalar(,,),);
);
; i )
circle(src,pt,,Scalar(,,),);
}
waitKey();
;
}
知识重点:
1、FindBigestContour为寻找轮廓中最大轮廓的函数,目前这个函数还没有merge到OpenCV中,下一步有这个计划,注意这个函数的命名规则是按照OpenCV的方法定义的;
2、我们采用Rect boundRect = boundingRect( Mat(biggestContour) );
来获得轮廓的最小外接矩形。为什么要首先获得这个外接矩形了,因为我们这里来所有要求的点肯定都在这个矩形中,我们做这一步就能够降低算法的计算复杂程度;
3、PCA分析的具体原来和细节,请查看《如何获得物体的主要方向?》 https://www.cnblogs.com/jsxyhelu/p/7690699.html
我们这里使用,主要是获得两个数据,一个是该轮廓的重心,这个点是我们最后要求的那条直线肯定经过的;二个是求出直线的斜率。那么对于一条直线,已经知道斜率和经过的一点,就已经能够被定义出来;
4、最后在求该直线和轮廓的交点的时候,采用了LineIterator 和pointPolygonTest,前者是OpenCV中专门用来遍历直线的;后者是专门用来计算点和轮廓的关系的,应该说这里的应用还是非常高效的。
感谢阅读至此,希望有所帮助。