主要的代码内容来自<OPencv 计算机视觉编程攻略>这本书和http://blog.csdn.net/thefutureisour/article/details/7574819这篇文章
#include <cv.h>
#include <highgui.h>
using namespace cv;
class MorphFeatures{
private:
//用于产生二值图像的阀值
int threshold;
//用于检测角点的 元素
Mat cross;
Mat diamond;
Mat square;
Mat x;
public:
MorphFeatures ():
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 applyThreshold(Mat &result)
{
if(threshold>0)
cv::threshold(result,result,threshold,255,THRESH_BINARY_INV);
}
Mat getCorners(const Mat &image){
Mat result;
//用十字元素膨胀
dilate(image,result,cross);
//用菱形元素腐蚀
erode(image,result,diamond);
//用X行元素膨胀
Mat result2;
dilate(image,result2,x);
//用正方形元素腐蚀
erode(result2,result2,square);
//闭合运算得到角点
absdiff(result2 ,result,result);
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 argc, char** argv )
{
Mat image=imread("./1.jpeg",CV_LOAD_IMAGE_GRAYSCALE);
Mat image2;
MorphFeatures mor;
image2= mor.getCorners(image);
mor.drawOnImage(image2,image);
imshow("ac",image);
imwrite("./2.jpeg",image);
waitKey(0);
return 0;
}
原图:
效果图: