Corners检测「建议收藏」

2022-11-19 17:08:29 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

1、Harris Corners角点检测

使用harris corners检测器:

使用OpenCV函数

void cornerHarris( InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT );

参数:

blockSize:感兴趣点周围邻居矩阵大小

ksize:孔径大小与sobel方法中的参数一样

k:计算像素点强度值的系数

dst:存放各个像素点的average intensity change值,越大说明越有可能是角点

average internsity change的计算方法:

参考:1、《OpenCV CookBook》P199

2、http://blog.csdn.net/crzy_sparrow/article/details/7391511

在《OpenCV CookBook》中对Harris Corners检测器稍稍做了改善,加入了非极大值抑制,也即不但感兴趣点的average internsity change要满足大于threshold,也要是局部极大值

部分代码如下:

代码语言:javascript复制
	void detect(cv::Mat image)
	{
		cv::cornerHarris(image , cornersStrength ,
			ksize , aperture , k) ;
	}

	cv::Mat  getCornersMap(double threshold)
	{
		double minStrength ;
		cv::minMaxLoc(cornersStrength , &minStrength , &maxStrength) ;
		cv::Mat dilate ;
		cv::dilate(cornersStrength , dilate , cv::Mat()) ;//dilate后只有局部极大值没有改变

		cv::compare(cornersStrength , dilate , localMax , cv::CMP_EQ) ;//因局部极大值未变,所以只有局部极大值出为1
		threshold = threshold * maxStrength ;

		cv::threshold(cornersStrength , cornersMap , threshold , 255 , cv::THRESH_BINARY) ;//强度值满足>threshold
		cornersMap.convertTo(cornersMap , CV_8U) ;
		cv::bitwise_and(cornersMap , localMax , cornersMap) ;//结合得到满足两个条件的点定义为角点
		return cornersMap ;
	}

	void drawImage(cv::Mat &image)
	{
		std::vector<cv::Point> points ;
		for(int i = 0 ; i < cornersMap.rows ;    i)
		{
			const uchar * ptr = cornersMap.ptr(i) ;
			for(int j = 0 ; j < cornersMap.cols ;    j)
			{
				if(ptr[j])
				{
					points.push_back(cv::Point(j , i)) ;//注意顺序是先X坐标 ,再Y坐标
				}
			}
		}
		std::vector<cv::Point>::const_iterator itc = points.begin() ;
		while (points.end() != itc)
		{
			cv::circle(image , *itc , 3 , cv::Scalar(255) , 2) ;
			itc    ;
		}
	}

2、FAST(Features from Accelerated Segment Test) Feature

思想:给定候选像素点,指定半径,若圆上连续的超过圆周长3/4的像素点的比候选的中间点明亮或者暗淡,则认为候选点是一个keyPoint,可以使用一个快速判断的技巧:我们先预判断中心点上下左右四个点,它们中至少要有三个符合以上条件才有可能是keyPoint,我们可以先使用这个方法先预判一下。

代码:

代码语言:javascript复制
	cv::Mat image =  cv::imread ("D:/Development/OpenCV/images/church01.jpg"  , 0);

	std::vector<cv::KeyPoint> keyPoints ;
	cv::FastFeatureDetector FastFD(40) ;
	FastFD.detect(image , keyPoints) ;
	cv::Mat timage = cv::imread ("D:/Development/OpenCV/images/church01.jpg") ;
	cv::drawKeypoints(image , keyPoints , timage , 
		cv::Scalar(-1 , -1 , -1) , cv::DrawMatchesFlags::DRAW_OVER_OUTIMG) ;

因其快速性常常用在视觉追踪中

参考:http://blog.csdn.net/skeeee/article/details/9405531

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/200801.html原文链接:https://javaforall.cn

0 人点赞