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,也要是局部极大值
部分代码如下:
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 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::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,我们可以先使用这个方法先预判一下。
代码:
cv::Mat image = cv::imread ("D:/Development/OpenCV/images/church01.jpg" , 0);
std::vector 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