在計算機視覺中,興趣點(也叫關鍵點或者特徵點)的概念被大量用於解決物體識別、圖像匹配、視覺跟蹤、三維重建等問題。它依賴於這個想法,即不再觀察整副圖像,而是選擇某些特殊的點,然後對它們執行局部分析。如果能檢測到足夠多的這種點,同時它們的區分度很高,並且可以精確定位穩定的特徵,那麼這個方法就很有效。
Harris角點的理論部分見opencv1的這篇blog:http://blog.csdn.net/lu597203933/article/details/15088485。 下面闡述opencv2中如何進行harris角點檢測和極大值抑制。
一:harris角點檢測
Code:
-
int main()
-
{
-
Mat image = imread("F:\\huangrong.jpg", 0);
-
if(!image.data)
-
{
-
cout << "Fail to load image" << endl;
-
return 0;
-
}
-
Mat cornerStrength;
-
int blockSize = 2;
-
int kSize = 3;
-
cornerHarris(image, cornerStrength, blockSize, kSize, 0.01);
-
-
Mat harrisCorner;
-
double thresh = 0.00001;
-
threshold(cornerStrength, harrisCorner, thresh, 255, THRESH_BINARY_INV);
-
namedWindow("image");
-
imshow("image", image);
-
namedWindow("cornerStrength");
-
imshow("cornerStrength", cornerStrength);
-
namedWindow("harrisCorner");
-
imshow("harrisCorner", harrisCorner);
-
waitKey(0);
-
return 0;
-
}
Explaination:
<1>opencv2中使用cornerHarris(InputArray src, OutputArray dst, int blockSize,int ksize, double k, int borderType=BORDER_DEFAULT );
第一個參數: 輸入源圖像
第二個參數:輸出 用於保存計算得到的得分
第三個參數:相鄰像素尺寸
第四個:sobel運算核大小
第五:公式中的參數
<2>二值化函數threshold( InputArray src, OutputArray dst,doublethresh,double maxval, inttype );
Result:
二:極大值抑制
以上獲取到的角點圖像包含許多角點羣,所以需要極大值抑制。我們使用膨脹函數dilate和比較compare運算來進行抑制。
主要思想是通過dilate和compare這兩個函數得到極大值點所對應的標識,後將二值化的得分值與標識進行與運算即bitwise_and 函數。具體解釋見代碼註釋。
Code:
HarrisDetector.h
-
class HarrisDetector{
-
private:
-
-
Mat cornerStrength;
-
-
Mat cornerTh;
-
-
Mat localMax;
-
int neighbourhood;
-
int aperture;
-
double k;
-
-
double thre;
-
-
public:
-
HarrisDetector():neighbourhood(2),aperture(3), k(0.01),
-
thre(0.00001){
-
-
}
-
void detect(Mat &image);
-
Mat getCornerMap();
-
void getCorners(vector<Point> &points);
-
void drawOnImage(Mat &image, vector<Point> &points);
-
};
-
-
void HarrisDetector::detect(Mat &image){
-
cornerHarris(image, cornerStrength, neighbourhood, aperture, k);
-
Mat dilated;
-
-
dilate(cornerStrength, dilated, Mat());
-
compare(cornerStrength, dilated, localMax, CMP_EQ);
-
}
-
-
Mat HarrisDetector::getCornerMap()
-
{
-
Mat cornerMap;
-
-
threshold(cornerStrength, cornerTh, thre, 255, THRESH_BINARY);
-
-
cornerTh.convertTo(cornerMap, CV_8U);
-
-
bitwise_and(cornerMap, localMax, cornerMap);
-
return cornerMap;
-
}
-
void HarrisDetector::getCorners(vector<Point> &points)
-
{
-
Mat cornerMap = getCornerMap();
-
for(int y = 0; y < cornerMap.rows; y++)
-
{
-
uchar *cornerPtr = cornerMap.ptr<uchar>(y);
-
for(int x = 0; x < cornerMap.cols; x++)
-
{
-
if(cornerPtr[x]){
-
points.push_back(Point(x, y));
-
}
-
}
-
}
-
}
-
-
void HarrisDetector::drawOnImage(Mat &image, vector<Point> &points)
-
{
-
int radius = 3, thickness = 2;
-
vector<Point>::iterator it = points.begin();
-
-
while(it!= points.end())
-
{
-
-
circle(image, *it, radius, Scalar(255,255,255), thickness);
-
it ++;
-
}
-
}
main.cpp:
-
Mat image = imread("F:\\huangrong.jpg", 0);
-
vector<Point> points;
-
HarrisDetector hdetector;
-
hdetector.detect(image);
-
hdetector.getCorners(points);
-
cout << points.size()<< endl;
-
hdetector.drawOnImage(image, points);<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
Result:
三:適合跟蹤的優質特徵
Opencv2自帶了goodFeaturesToTrack這個函數,用於解決特徵點聚類問題,除了引入局部極大值的條件,特徵點傾向於在圖像中不均勻分佈,集中在在紋理豐富的部分。該函數的具體解釋見代碼註釋。
Code:
-
-
-
-
goodFeaturesToTrack(image, points, 100, 0.01, 10);
-
cout << points.size() << endl;
此外cv:: goodFeaturesToTrack函數擁有一個封裝類cv::GoodFeaturesToTrackDetector,他繼承自抽象類FeatureDetector類。下面代碼實現功能和上面一樣。
Code:
-
-
Mat result;
-
vector<KeyPoint> keypoints;
-
GoodFeaturesToTrackDetector gftt(100, 0.01, 10);
-
gftt.detect(image, keypoints);
-
drawKeypoints(image, keypoints, result);
作者:小村長 出處:http://blog.csdn.net/lu597203933 歡迎轉載或分享,但請務必聲明文章出處。
(新浪微博:小村長zack, 歡迎交流!)