OpenCV2马拉松第21圈——形态学操作实现角点检测

计算机视觉讨论群162501053

收入囊中
  • 形态学膨胀腐蚀实现角点检测


葵花宝典
角点检测的方法仁者见仁,智者见智。
今天,我挑选了OpenCV2_Computer_Vision_Application_Programming_Cookbook里面的代码带来角点检测。
另外,附上自己在之前实现的harris角点检测openCV2马拉松第19圈——Harris角点检测(自己实现)

首先给大家看一下4种结构矩阵



我的原始矩阵如下


用cross膨胀再用diamond腐蚀后得到
发现角被磨掉了

用x膨胀再用square腐蚀后磨损的更多。


然后两个结果相减,角点就被检测出来了。


荷枪实弹
下面是创建4个结构矩阵的代码
MorphoFeatures() :  threshold(-1),
						cross(5,5,CV_8U,cv::Scalar(0)),
						diamond(5,5,CV_8U,cv::Scalar(1)),
						square(5,5,CV_8U,cv::Scalar(1)),
						x(5,5,CV_8U,cv::Scalar(0)) 
	{
		// Creating the cross-shaped structuring element
   		for (int i=0; i<5; i++) {
      		cross.at<uchar>(2,i)= 1;
      		cross.at<uchar>(i,2)= 1;
   		}
   		
   		// Creating the diamond-shaped structuring element
   		diamond.at<uchar>(0,0)= 0;
   		diamond.at<uchar>(0,1)= 0;
   		diamond.at<uchar>(1,0)= 0;
   		diamond.at<uchar>(4,4)= 0;
   		diamond.at<uchar>(3,4)= 0;
   		diamond.at<uchar>(4,3)= 0;
   		diamond.at<uchar>(4,0)= 0;
   		diamond.at<uchar>(4,1)= 0;
      	diamond.at<uchar>(3,0)= 0;
      	diamond.at<uchar>(0,4)= 0;
      	diamond.at<uchar>(0,3)= 0;
      	diamond.at<uchar>(1,4)= 0;
      	
      	// Creating the x-shaped structuring element
      	for (int i=0; i<5; i++) {
        	x.at<uchar>(i,i)= 1;
        	x.at<uchar>(4-i,i)= 1;
      	}

   	}

这里进行了我们讨论过的操作,分别进行膨胀腐蚀,再相减
Mat getCorners(const Mat &image) {
		Mat result;
      	// Dilate with a cross
		dilate(image,result,cross);
      	// Erode with a diamond
      	erode(result,result,diamond);
      	Mat result2;
      	// Dilate with a X
      	dilate(image,result2,x);
      	// Erode with a square
      	erode(result2,result2,square);
      	// Corners are obtained by differencing
      	// the two closed images
      	absdiff(result2,result,result);
     	 // Apply threshold to obtain a binary image
      	applyThreshold(result);
      	return result;
   }


完整实现
#include "opencv2/highgui/highgui.hpp"  
#include "opencv2/imgproc/imgproc.hpp"  
#include <iostream>
using namespace cv;  
using namespace std;

class MorphoFeatures {
private:

	int threshold;
	
	Mat cross;
	Mat diamond;
	Mat square;
	Mat x;
	
	void applyThreshold(Mat& result) {
		if (threshold>0)
			cv::threshold(result, result,threshold, 255, THRESH_BINARY_INV);
	}

public:

	MorphoFeatures() :  threshold(-1),
						cross(5,5,CV_8U,cv::Scalar(0)),
						diamond(5,5,CV_8U,cv::Scalar(1)),
						square(5,5,CV_8U,cv::Scalar(1)),
						x(5,5,CV_8U,cv::Scalar(0)) 
	{
		// Creating the cross-shaped structuring element
   		for (int i=0; i<5; i++) {
      		cross.at<uchar>(2,i)= 1;
      		cross.at<uchar>(i,2)= 1;
   		}
   		
   		// Creating the diamond-shaped structuring element
   		diamond.at<uchar>(0,0)= 0;
   		diamond.at<uchar>(0,1)= 0;
   		diamond.at<uchar>(1,0)= 0;
   		diamond.at<uchar>(4,4)= 0;
   		diamond.at<uchar>(3,4)= 0;
   		diamond.at<uchar>(4,3)= 0;
   		diamond.at<uchar>(4,0)= 0;
   		diamond.at<uchar>(4,1)= 0;
      	diamond.at<uchar>(3,0)= 0;
      	diamond.at<uchar>(0,4)= 0;
      	diamond.at<uchar>(0,3)= 0;
      	diamond.at<uchar>(1,4)= 0;
      	
      	// Creating the x-shaped structuring element
      	for (int i=0; i<5; i++) {
        	x.at<uchar>(i,i)= 1;
        	x.at<uchar>(4-i,i)= 1;
      	}

   	}

	void setThreshold(int x) {
		threshold = x;
	}

	Mat getCorners(const Mat &image) {
		Mat result;
      	// Dilate with a cross
		dilate(image,result,cross);
      	// Erode with a diamond
      	erode(result,result,diamond);
      	Mat result2;
      	// Dilate with a X
      	dilate(image,result2,x);
      	// Erode with a square
      	erode(result2,result2,square);
      	// Corners are obtained by differencing
      	// the two closed images
      	absdiff(result2,result,result);
     	 // Apply threshold to obtain a binary image
      	applyThreshold(result);
      	return result;
   }
   
	void drawOnImage(const Mat& binary, Mat& image) {
		Mat_<uchar>::const_iterator it = binary.begin<uchar>();
		Mat_<uchar>::const_iterator itend = binary.end<uchar>();
      	for (int i=0; it!= itend; ++it,++i) {
        	 if (!*it)
            	circle(image,Point(i%image.step,i/image.step),5,Scalar(255,0,0));
		} 
	}

   	
};
 

int main( int, char** argv )  
{  
	Mat image;
    image = imread( argv[1] );
    cvtColor( image, image, CV_RGB2GRAY );
    
	MorphoFeatures morpho;
	morpho.setThreshold(40); 
	
	Mat corners;
   	corners= morpho.getCorners(image);
   	
   	morpho.drawOnImage(corners,image);
   	namedWindow("Corners on Image");
   	imshow("Corners on Image",image);

    waitKey();  
    return 0;  
} 


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值