首页 > 代码库 > opencv对图像进行边缘及角点检测

opencv对图像进行边缘及角点检测

opencv对图像进行边缘及角点检测

先看结果:

代码:
// ConsoleApplication1_812.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "opencv2/opencv.hpp"

class Imagedetector{
public:
	Imagedetector():threshold(-1)
	,cross(5,5,CV_8U,cv::Scalar(0))  //初始化十字、菱形、方形、X形结构元素
	,diamond(5,5,CV_8U,cv::Scalar(1))
	,square(5,5,CV_8U,cv::Scalar(1))
	,x(5,5,CV_8U,cv::Scalar(0))
	{
		for(int i = 0;i < 5;++i){
			cross.at<uchar>(2,i) = 1;
			cross.at<uchar>(i,2) = 1;
		}

		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;
		for(int i = 0; i<5;++i)
		{
			x.at<uchar>(i,i) = 1;
			x.at<uchar>(4-i,i) = 1;
		}
		
	}
	void setThreshold(int thr){threshold = thr;}
	cv::Mat getEdges(const cv::Mat &image){
	
		cv::Mat result;
		cv::morphologyEx(image,result,cv::MORPH_GRADIENT,cv::Mat());
		appThreshold(result);
		return result;
	}
	void appThreshold(cv::Mat &image){
	
		if(threshold > 0)
			cv::threshold(image,image,threshold,255,cv::THRESH_BINARY);
	}
	cv::Mat getCornres(const cv::Mat &image){
	
		cv::Mat result;
	
		cv::dilate(image,result,cross);
		cv::erode(result,result,diamond);

		cv::Mat result2;
		cv::dilate(image,result2,x);
		cv::erode(result2,result2,square);

		cv::absdiff(result2,result,result);
		appThreshold(result);
		return result;
	}
	void drawImage(const cv::Mat binary,cv::Mat image){
		cv::Mat_<uchar>::const_iterator it= binary.begin<uchar>();
		cv::Mat_<uchar>::const_iterator itend= binary.end<uchar>();

		for (int i=0; it!= itend; ++it,++i) {
			if (!*it)
				cv::circle(image,cv::Point(i%image.step,i/image.step),5,cv::Scalar(255,0,0));
		}
	}


private:
	int threshold;
	cv::Mat cross;
	cv::Mat diamond;
	cv::Mat square;
	cv::Mat x;
};

int _tmain(int argc, _TCHAR* argv[])
{
	Imagedetector detector;
	detector.setThreshold(40);

	cv::Mat image = cv::imread("building.jpg",0);
	if(!image.data)
		return -1;
	cv::Mat edges = detector.getEdges(image);
	cv::namedWindow("test",CV_WINDOW_AUTOSIZE);
	cv::imshow("test",edges);


	cv::Mat corners = detector.getCornres(image);
	cv::morphologyEx(corners,corners,cv::MORPH_TOPHAT,cv::Mat());
	cv::threshold(corners, corners, 40, 255, cv::THRESH_BINARY_INV);
	detector.drawImage(corners,image);
	cv::namedWindow("corners",CV_WINDOW_AUTOSIZE);
	cv::imshow("corners",image);
	cv::waitKey(0);
	return 0;
}

原理稍后再说。