萌新學習手冊:openCV中Hassi角點檢測
createTrackbar(const string& trackbarname,
const string& winname,
int* value, int count,
TrackbarCallback onChange = 0,
void* userdata = 0);
用於建立一個滑動空間,可以動態調動閾值;
trackbarname:滑動空間的名稱;
winname:滑動空間用於依附的影象視窗的名稱;
value:初始化閾值;
count:滑動控制元件的刻度範圍;
TrackbarCallback是回撥函式,調動閾值後會執行
超級推薦Mat類詳解:
dst = Mat::zeros(Size size, int type);
例如本程式碼中用到dst = Mat::zeros(gray_src.size(), CV_32FC1);
Mat::zeros是初始化的一種用於生成一張全黑的影象
關於CV_32FC1等類似的引數的解釋
其中CV_32FC1表示每一個畫素點在記憶體中佔32位,型別為float(還有S和U分別代表有符號整型和無符號整型)C1表示單通道影象
cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT)
用於Harris角點檢測
src 輸入影象
dst儲存檢測的影象
blockSize傳入鄰域的大小
ksize用於求導的視窗大小
k Harris 角點檢測方程中的自由引數
BORDER_DEFAULT 影象卷積的時候邊界畫素不能被卷積操作,因為邊界畫素沒有完全跟kernel重疊,這種是openCV的預設操作,即在卷積開始之前增加邊緣畫素以確保影象的邊緣被處理,在卷積處理之後再去掉這些邊緣。
normalize(InputArry src,InputOutputArray dst,double alpha=1,double beta=0,int norm_type=NORM_L2,
normalsize用於歸一化資料,分為資料歸一化和範圍歸一化
引數說明
src 輸入陣列;
dst 輸出陣列,陣列的大小和原陣列一致;
alpha 1,用來規範值,2.規範範圍,並且是下限;
beta 只用來規範範圍並且是上限;
norm_type 歸一化選擇的數學公式型別;
dtype 當為負,輸出在大小深度通道數都等於輸入,當為正,輸出只在深度與輸入不同,不同的地方由dtype決定;
mark 掩碼。選擇感興趣區域,選定後只能對該區域進行操作。
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
const char* output_title = "HarrisCornerDetectionResult";
Mat src,gray_src;
int thresh = 130;//設定閾值
int max_counter = 255;
void Harris_Demo(int, void*);
int main(int argc,char** argv)
{
src = imread("C:/Users/pbiha/Desktop/image/1.png");
if (src.empty())
{
printf("can not load image\n");
return -1;
}
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
namedWindow(output_title, CV_WINDOW_AUTOSIZE);
cvtColor(src, gray_src, COLOR_BGR2GRAY);
createTrackbar("Threshold:", output_title, &thresh, max_counter, Harris_Demo);
Harris_Demo(0, 0);
waitKey(0);
return 0;
}
void Harris_Demo(int, void*)
{
Mat dst,norm_dst,normScaleDst;
dst = Mat::zeros(gray_src.size(), CV_32FC1);
int ksize = 3;
int blockSize = 2;
double k = 0.04;
cornerHarris(gray_src, dst, blockSize,ksize, k, BORDER_DEFAULT);//用Harris演算法計算並儲存在輸出陣列中
normalize(dst, norm_dst, 0, 255, NORM_MINMAX,CV_32FC1,Mat());//把需要處理的資料經過歸一化限制在你需要的一定範圍內
convertScaleAbs(norm_dst, normScaleDst);//使用線性變換轉換輸入陣列元素成8位無符號整型
Mat resultImage = src.clone();
for(int row = 0; row < resultImage.rows; row++) {
uchar* currentRow = normScaleDst.ptr(row);//直接提取出當前這一行的所有的畫素點
for (int col = 0; col < resultImage.cols; col++) {
int value = (int)*currentRow;
if (value>thresh) {
circle(resultImage, Point(col, row), 1, Scalar(0, 0, 255), 2, 8, 0);
}
currentRow++;
}
}
imshow(output_title, resultImage);
}