opencv中的harris角点检测函数
来源:互联网 发布:netbeans php下载 编辑:程序博客网 时间:2024/05/17 18:02
函数接口
//! computes Harris cornerness criteria at each image pixelCV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT );
参数说明
src —— 待检测图像,单通道灰度图
dst —— 角点响应值,类型CV_32FC1
blockSize —— 论文中窗口大小,下面细说
ksize —— sobel窗口大小
k —— 原始论文里的调节参数 0.04到0.05之间
borderType —— 边界处理方式
其实写这个我想说明的就是这个blockSize和ksize的意义,查看源码
static voidcornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size, int aperture_size, int op_type, double k=0., int borderType=BORDER_DEFAULT ){#ifdef HAVE_TEGRA_OPTIMIZATION if (tegra::cornerEigenValsVecs(src, eigenv, block_size, aperture_size, op_type, k, borderType)) return;#endif int depth = src.depth(); double scale = (double)(1 << ((aperture_size > 0 ? aperture_size : 3) - 1)) * block_size; if( aperture_size < 0 ) scale *= 2.; if( depth == CV_8U ) scale *= 255.; scale = 1./scale; CV_Assert( src.type() == CV_8UC1 || src.type() == CV_32FC1 ); Mat Dx, Dy; if( aperture_size > 0 ) { Sobel( src, Dx, CV_32F, 1, 0, aperture_size, scale, 0, borderType );//参数ksize Sobel( src, Dy, CV_32F, 0, 1, aperture_size, scale, 0, borderType ); } else { Scharr( src, Dx, CV_32F, 1, 0, scale, 0, borderType ); Scharr( src, Dy, CV_32F, 0, 1, scale, 0, borderType ); } Size size = src.size(); Mat cov( size, CV_32FC3 ); int i, j; for( i = 0; i < size.height; i++ ) { float* cov_data = (float*)(cov.data + i*cov.step); const float* dxdata = (const float*)(Dx.data + i*Dx.step); const float* dydata = (const float*)(Dy.data + i*Dy.step); for( j = 0; j < size.width; j++ ) { float dx = dxdata[j]; float dy = dydata[j]; cov_data[j*3] = dx*dx; cov_data[j*3+1] = dx*dy; cov_data[j*3+2] = dy*dy; } } boxFilter(cov, cov, cov.depth(), Size(block_size, block_size), Point(-1,-1), false, borderType );//参数blockSize if( op_type == MINEIGENVAL ) calcMinEigenVal( cov, eigenv ); else if( op_type == HARRIS ) calcHarris( cov, eigenv, k ); else if( op_type == EIGENVALSVECS ) calcEigenValsVecs( cov, eigenv );}}
标出了使用两个参数的位置,其中ksize是sobel算子窗体大小就不用多说了,越大抗噪声能力越强,但模糊也更加严重。opencv用sobel来计算dx和dy,进而求得dx*dy dx*dx dy*dy,也即求得原方法中的海森矩阵。在论文中二次型参数M,是一个窗口内的海森矩阵加权和。窗口可以为方形或者高斯,opencv使用了boxFilter函数(窗口大小由blocksize控制)来实现方形窗口。论文这么实现应该主要还是为了抗噪。不要让噪声成为角点被检测出来,另外也可以用这两个参数来控制角点对比度。所以值的选取要看具体的应用场景中噪声的特性了。
示例代码
#include<iostream>#include<opencv2/opencv.hpp>#include<opencv2/imgproc/imgproc.hpp>using namespace std;using namespace cv;int thres;int blockSize;int kSize;void harrisCorner(int,void *){ Mat srcImg; Mat grayImg,dst_norm,dst_normScale; Mat responseImg = Mat::zeros( srcImg.size(), CV_32FC1 ); vector<Point2d> vConners; //1.读取图片 srcImg=imread("box.png"); cvtColor(srcImg,grayImg,CV_RGB2GRAY); //2.检查参数 if(blockSize<2) blockSize=2; if(kSize<3) kSize=3; //3.计算角点可能性 cornerHarris(grayImg,responseImg,blockSize,kSize,0.04); // sobel size cv::normalize(responseImg,dst_norm,0,255,NORM_MINMAX,CV_32FC1); cv::convertScaleAbs(dst_norm,dst_normScale);//归一化到0~255 //4.根据阈值记录角点 for(int y=0;y<dst_normScale.rows;y++){ unsigned char *ptr=dst_normScale.data+y*dst_normScale.cols; for(int x=0;x<dst_normScale.cols;x++){ if(*ptr>thres){ vConners.push_back(Point2d(x,y)); } ptr++; } } //5.显示 for(auto &p : vConners){ circle(srcImg,p,5,Scalar(0,0,0)); } imshow("showConners",srcImg);}int main(){ namedWindow("showConners"); thres=100; blockSize=2; kSize=3; createTrackbar("thres","showConners",&thres,255,harrisCorner); createTrackbar("blockSize","showConners",&blockSize,10,harrisCorner); createTrackbar("kSize","showConners",&kSize,10,harrisCorner); waitKey(0); return 0;}
另外一些离的很近的角点可以用非极大值抑制来消除,窗体大小可参考blockSize的大小,一种实现如下
//4.根据阈值记录角点 for(int y=1;y<dst_normScale.rows-1;y++){ unsigned char *ptrT=dst_normScale.data+(y-1)*dst_normScale.cols; unsigned char *ptrC=dst_normScale.data+y*dst_normScale.cols; unsigned char *ptrB=dst_normScale.data+(y+1)*dst_normScale.cols; for(int x=1;x<dst_normScale.cols-1;x++){ if(*ptrC>thres){ if(ptrC[0]<ptrC[-1]||ptrC[0]<ptrC[1]) goto CON; if(ptrC[0]<ptrT[-1]||ptrC[0]<ptrT[1]||ptrC[0]<ptrT[0]) goto CON; if(ptrC[0]<ptrB[-1]||ptrC[0]<ptrB[1]||ptrC[0]<ptrB[0]) goto CON; vConners.push_back(Point2d(x,y)); } CON: ptrC++; ptrB++; ptrT++; } }
阅读全文
1 0
- opencv中的harris角点检测函数
- opencv harris角点检测
- opencv-Harris 角点检测
- Opencv Harris角点检测
- opencv学习_12 (harris角点检测)
- Opencv学习笔记------Harris角点检测
- opencv的Harris角点检测
- OpenCV Harris 角点检测子
- Harris角点检测(Python-OpenCV)
- Opencv学习笔记------Harris角点检测
- opencv学习_12 (harris角点检测)
- 基于OpenCV的harris角点检测
- OpenCV + Python Harris角点检测
- OpenCV角点检测之Harris角点检测
- ★OpenCV 角点检测之Harris角点检测
- Harris 角点检测
- Harris角点检测
- Harris角点检测
- python写算法题:leetcode: 1. Two Sum
- tensorflow实现图像色彩的调整
- 1727: Dungeon Master
- android 几个常见过时解决办法
- MySQL查询数据表中表字段及其注释
- opencv中的harris角点检测函数
- “傻瓜”式填充,自定义LayoutManager
- 《UNIX网络编程 卷1》 笔记: TCP 客户/服务器程序示例
- 『ORACLE』 对永久表空间进行DDL操作(11g)
- 《数据结构实战》模拟文件系统目录组织------树的应用
- 原生Hibernate和Jpa Hibernate
- HDU 1111 Piggy-Bank(完全背包例题)
- Python笔记(6)----列表、元组、字符串、字典等的相关用法
- 方法的调用-----求一个质数