主要参考:http://blog.csdn.net/thefutureisour/article/details/7574819
对于检测边缘,用morphologyEx函数就可以了,(cvMorphologyEx中形态操作的类型: CV_MOP_OPEN - 开运算 CV_MOP_CLOSE - 闭运算 CV_MOP_GRADIENT - 形态梯度 CV_MOP_TOPHAT - "顶帽" CV_MOP_BLACKHAT - "黑帽" ) 参数CV_MOP_GRADIENT - 形态梯度 大致就是检测到图像的变化的直线。 检测角点没有特定函数,就是对图像应用不同的结构元素膨胀腐蚀,然后做差分
//morphoFeatures.h
#if ! defined MORPHOF #define MORPHOF #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv; 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);//,THRESH_BINARY_INV); } public: //构造函数 MorphoFeatures():threshold(-1), cross(5,5,CV_8U,Scalar(0)), diamond(5,5,CV_8U,Scalar(255)), square(5,5,CV_8U,Scalar(255)), x(5,5,CV_8U,Scalar(0)) { //创建十字型结构元 for(int i = 0; i < 5; i++) { cross.at<uchar>(2,i) = 255; cross.at<uchar>(i,2) = 255; } //创建菱形结构元:手动画,只需要把不是菱形的部分变白即可 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; //创建X形 for(int i = 0; i < 5; i++) { //主对角线 x.at<uchar>(i,i) = 255; //副对角线 x.at<uchar>(4-i,i) = 255; } } //设置门限函数 void setThreshold(int t) { threshold = t; } //获取当前门限 int getThreshold() const { return threshold; } //检测直线函数 Mat getEdges(const Mat &image) { Mat result; //获取图像的梯度 morphologyEx(image,result,cv::MORPH_GRADIENT,Mat()); //imshow("检测直线",result); //结果二值化 applyThreshold(result); return result; } //检测角点函数 Mat getCorners(const Mat &image) { Mat result; dilate(image,result,cross); erode(result,result,diamond); Mat result2; dilate(image,result2,x); erode(result2,result2,square); absdiff(result2,result,result); applyThreshold(result); return result; } //在角点处画圆 morpho.drawOnImage(corners,image); 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)); //牛逼的坐标表达形式 } } }; #endif以下是主函数:
#include <opencv2/highgui/highgui.hpp> #include "morphoFeatures.h" int main() { Mat image = imread("C:\\Users\\Administrator\\Desktop\\工作\\testp\\building.jpg",0); if(!image.data) return -1; imshow("源图像",image); MorphoFeatures morpho; morpho.setThreshold(40); //获取边沿 Mat edges; edges = morpho.getEdges(image); imshow("边沿",edges); //获取角点 morpho.setThreshold(-1); Mat corners; corners = morpho.getCorners(image); // imshow("corners",corners); morphologyEx(corners,corners,MORPH_TOPHAT,Mat()); //;顶帽 //imshow("corners",corners); threshold(corners,corners,40,255,THRESH_BINARY_INV); //imshow("角点",corners); //imshow("corners",corners); //展示图片上的角点 morpho.drawOnImage(corners,image); imshow("图片上的角点",image); waitKey(0); return 0; }