大家好,又见面了,我是你们的朋友全栈君。
1、Harris Corners角点检测
使用harris corners检测器:
使用OpenCV函数
void cornerHarris( InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT );
参数:
blockSize:感兴趣点周围邻居矩阵大小
ksize:孔径大小与sobel方法中的参数一样
k:计算像素点强度值的系数
dst:存放各个像素点的average intensity change值,越大说明越有可能是角点
average internsity change的计算方法:
参考:1、《OpenCV CookBook》P199
2、http://blog.csdn.net/crzy_sparrow/article/details/7391511
在《OpenCV CookBook》中对Harris Corners检测器稍稍做了改善,加入了非极大值抑制,也即不但感兴趣点的average internsity change要满足大于threshold,也要是局部极大值
部分代码如下:
代码语言:javascript复制 void detect(cv::Mat image)
{
cv::cornerHarris(image , cornersStrength ,
ksize , aperture , k) ;
}
cv::Mat getCornersMap(double threshold)
{
double minStrength ;
cv::minMaxLoc(cornersStrength , &minStrength , &maxStrength) ;
cv::Mat dilate ;
cv::dilate(cornersStrength , dilate , cv::Mat()) ;//dilate后只有局部极大值没有改变
cv::compare(cornersStrength , dilate , localMax , cv::CMP_EQ) ;//因局部极大值未变,所以只有局部极大值出为1
threshold = threshold * maxStrength ;
cv::threshold(cornersStrength , cornersMap , threshold , 255 , cv::THRESH_BINARY) ;//强度值满足>threshold
cornersMap.convertTo(cornersMap , CV_8U) ;
cv::bitwise_and(cornersMap , localMax , cornersMap) ;//结合得到满足两个条件的点定义为角点
return cornersMap ;
}
void drawImage(cv::Mat &image)
{
std::vector<cv::Point> points ;
for(int i = 0 ; i < cornersMap.rows ; i)
{
const uchar * ptr = cornersMap.ptr(i) ;
for(int j = 0 ; j < cornersMap.cols ; j)
{
if(ptr[j])
{
points.push_back(cv::Point(j , i)) ;//注意顺序是先X坐标 ,再Y坐标
}
}
}
std::vector<cv::Point>::const_iterator itc = points.begin() ;
while (points.end() != itc)
{
cv::circle(image , *itc , 3 , cv::Scalar(255) , 2) ;
itc ;
}
}
2、FAST(Features from Accelerated Segment Test) Feature
思想:给定候选像素点,指定半径,若圆上连续的超过圆周长3/4的像素点的比候选的中间点明亮或者暗淡,则认为候选点是一个keyPoint,可以使用一个快速判断的技巧:我们先预判断中心点上下左右四个点,它们中至少要有三个符合以上条件才有可能是keyPoint,我们可以先使用这个方法先预判一下。
代码:
代码语言:javascript复制 cv::Mat image = cv::imread ("D:/Development/OpenCV/images/church01.jpg" , 0);
std::vector<cv::KeyPoint> keyPoints ;
cv::FastFeatureDetector FastFD(40) ;
FastFD.detect(image , keyPoints) ;
cv::Mat timage = cv::imread ("D:/Development/OpenCV/images/church01.jpg") ;
cv::drawKeypoints(image , keyPoints , timage ,
cv::Scalar(-1 , -1 , -1) , cv::DrawMatchesFlags::DRAW_OVER_OUTIMG) ;
因其快速性常常用在视觉追踪中
参考:http://blog.csdn.net/skeeee/article/details/9405531
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/200801.html原文链接:https://javaforall.cn