cvCornerHarris:
功能:检测图像的哈里斯角点检测,判断出某一点是不是图像的角点
函数形式:
void cvCornerHarris( const CvArr* image, CvArr* harris_responce, int block_size, int aperture_size=3, double k=0.04 );
参数列表:
Image 输入图像
harris_responce存储哈里斯检测responces的图像。与输入图像等大
block_size 邻域大小(见关于cvCornerEigenValsAndVecs的讨论)
aperture_size 扩展 Sobel 核的大小(见 cvSobel)。格式.当输入图像是浮点数格式时,该参数表示用来计算差分固定的浮点滤波器的个数
k 哈里斯检测器的自由参数
示例代码
原图片:
例程1:使用Mat
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src,src_gray;
src= imread("1.jpg");
cvtColor(src, src_gray, CV_RGB2GRAY); //灰度处理
Mat cornerStrength;
cornerHarris(src_gray, cornerStrength, 3, 3, 0.01); //检测
threshold(cornerStrength, cornerStrength, 0.0001, 255, THRESH_BINARY); //二值化灰度图
imshow("shiyan", cornerStrength);
waitKey(0);
return 0;
}
运行结果:
例程2:使用IplImage
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
IplImage* src = cvLoadImage("1.jpg");
cvNamedWindow("src");
cvShowImage("src", src);
//IPL_DEPTH_32F 4通道彩色图格式
IplImage* harris = cvCreateImage(cvGetSize(src), IPL_DEPTH_32F, 1);
//IPL_DEPTH_8U 单通道灰度图格式
IplImage* gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
//需转成单通道灰度图,才能进行角点提取。cvCornerHarris的提取角点的原图输入要求IPL_DEPTH_8U
cvCvtColor(src, gray, CV_BGR2GRAY);
//提取角点
cvCornerHarris(gray, harris, 3);
cvNamedWindow("harris");
cvShowImage("harris", harris);
//此时,计算出来的harris值非常小,显示一片黑,因此需要对其值进行放缩
double minVal, maxVal;
//提取harris最大最小值,用于计算亮度放缩值
cvMinMaxLoc(harris, &minVal, &maxVal, NULL, NULL, 0);
IplImage *harris_out = cvCreateImage(cvGetSize(src), 8, 1);
//亮度放缩值计算
double Scale;
double Shift;
//将harris的值均匀分布在0-255之间
Scale = 255 / (maxVal - minVal);
Shift = -minVal * Scale;
//图像亮度调整
cvConvertScale(harris, harris_out, Scale, Shift);
cvShowImage("harris_out", harris_out);
waitKey(0);
cvReleaseImage(&src);
cvReleaseImage(&harris);
cvReleaseImage(&harris_out);
return 0;
}
运行结果:
例程3:使用 cvCalcOpticalFlowPyrLK匹配角点
#include<opencv/cv.h>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
#include<stdio.h>
using namespace cv;
using namespace std;
const int MAX_CORNERS = 500;
int main(int argc, char** argv) {
IplImage* imgA = cvLoadImage("h1.jpg",CV_LOAD_IMAGE_GRAYSCALE);
IplImage* imgB = cvLoadImage("h2.jpg",CV_LOAD_IMAGE_GRAYSCALE);
CvSize img_sz = cvGetSize( imgA );
int win_size = 10;
IplImage* imgC = cvLoadImage("h2.jpg",CV_LOAD_IMAGE_UNCHANGED);
//需要做的第一件事就是获取我们想要跟踪的特征
IplImage* eig_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );
IplImage* tmp_image = cvCreateImage( img_sz, IPL_DEPTH_32F, 1 );
int corner_count = MAX_CORNERS;
CvPoint2D32f* cornersA = new CvPoint2D32f[ MAX_CORNERS ];
cvGoodFeaturesToTrack(
imgA,
eig_image,
tmp_image,
cornersA,
&corner_count,
0.01,
5.0,
0,
3,
0,
0.04
);
cvFindCornerSubPix(
imgA, cornersA, corner_count, cvSize(win_size,win_size),
cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)
);
char features_found[ MAX_CORNERS ];
float feature_errors[ MAX_CORNERS ];
CvSize pyr_sz = cvSize( imgA->width+8, imgB->height/3 );
IplImage* pyrA = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );
IplImage* pyrB = cvCreateImage( pyr_sz, IPL_DEPTH_32F, 1 );
CvPoint2D32f* cornersB = new CvPoint2D32f[ MAX_CORNERS ];
cvCalcOpticalFlowPyrLK( //在图像金字塔中计算LK光流
imgA,
imgB,
pyrA,
pyrB,
cornersA,
cornersB,
corner_count,
cvSize( win_size,win_size ),
5,
features_found,
feature_errors,
cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3 ),
0
);
for( int i=0; i<corner_count; i++ ) {
if( features_found[i]==0 || feature_errors[i]>550 ) {
printf("Error is %f\n", feature_errors[i]);
continue;
}
//显示匹配点,在原图中显示像素的移动
//找到前后对应的点的像素坐标,用红色连接显示
printf("Got it\n");
CvPoint p0 = cvPoint(
cvRound( cornersA[i].x ),
cvRound( cornersA[i].y )
);
CvPoint p1 = cvPoint(
cvRound( cornersB[i].x ),
cvRound( cornersB[i].y )
);
cvLine( imgC, p0, p1, CV_RGB(255,0,0),2 );
}
cvNamedWindow("ImageA",0);
cvNamedWindow("ImageB",0);
cvNamedWindow("LKpyr_OpticalFlow",0);
cvShowImage("ImageA",imgA);
cvShowImage("ImageB",imgB);
cvShowImage("LKpyr_OpticalFlow",imgC);
cvWaitKey(0);
return 0;
}
运行结果:
编译命令:
g++ harr.cpp `pkg-config --libs --cflags opencv`
参考链接:
cvCornerHarris函数-https://blog.csdn.net/jinwanchiji/article/details/78950919
cvCornerHarris角点检测-https://blog.csdn.net/c_ros/article/details/46523845
opencv-常用函数:https://www.cnblogs.com/xiaopanlyu/p/4561728.html
opencv3-0 API https://docs.opencv.org/3.0-beta/modules/refman.html
cvCalcOpticalFlowPyrLK的使用-https://blog.csdn.net/qq_28584889/article/details/103261377