createTrackbar(const string& trackbarname,
const string& winname,
int* value, int count,
TrackbarCallback onChange = 0,
void* userdata = 0);
用于创建一个滑动空间,可以动态调动阈值;
trackbarname:滑动空间的名称;
winname:滑动空间用于依附的图像窗口的名称;
value:初始化阈值;
count:滑动控件的刻度范围;
TrackbarCallback是回调函数,调动阈值后会执行
超级推荐Mat类详解:
https://blog.csdn.net/giantchen547792075/article/details/9107877
dst = Mat::zeros(Size size, int type);
例如本代码中用到dst = Mat::zeros(gray_src.size(), CV_32FC1);
Mat::zeros是初始化的一种用于生成一张全黑的图像
关于CV_32FC1等类似的参数的解释
https://blog.csdn.net/zuqiutxy/article/details/76104521
其中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的默认操作,即在卷积开始之前增加边缘像素以确保图像的边缘被处理,在卷积处理之后再去掉这些边缘。
https://blog.csdn.net/cosmispower/article/details/64457406
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
#include
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);
}