zoukankan      html  css  js  c++  java
  • 形态学滤波(3):使用形态学滤波对图像进行边缘及角点检测.

      1 #include<opencv2/opencv.hpp>
      2 #include<iostream>
      3 
      4 using namespace std;
      5 using namespace cv;
      6 
      7 //首先定义MorphoFeatures类,我们将使用它来检测图像特征
      8 class MorphoFeatures {
      9 private:
     10     int threShold;  //用于生成二值图像的阈值
     11     Mat cross;      //角点检测中用到的结构元素
     12     Mat diamond;
     13     Mat square;
     14     Mat x; 
     15 public:
     16     /*
     17         使用形态学检测角点,OpenCV没有直接实现它。这是一个很好的使用非方形结构元素的例子。
     18         事实上,它需要定义四种不同的结构元素,包括方形、菱形、十字形以及X形,这都是在构造
     19         函数中完成的(简单起见,所有元素的尺寸都固定为5*5)
     20     */
     21     MorphoFeatures() :threShold(-1), cross(5, 5, CV_8U, Scalar(0)),
     22         diamond(5, 5, CV_8U, Scalar(0)),
     23         square(5, 5, CV_8U, Scalar(0)),
     24         x(5, 5, CV_8U, Scalar(0)) {
     25         //创建十字形元素
     26         for (int i = 0; i < 5; i++) {
     27             cross.at<uchar>(2, i) = 1;
     28             cross.at<uchar>(i, 2) = 1;
     29         }
     30 
     31         //创建菱形元素
     32         diamond.at<uchar>(0, 0) = 0;
     33         diamond.at<uchar>(0, 1) = 0;
     34         diamond.at<uchar>(1, 0) = 0;
     35         diamond.at<uchar>(4, 4) = 0;
     36         diamond.at<uchar>(3, 4) = 0;
     37         diamond.at<uchar>(4, 3) = 0;
     38         diamond.at<uchar>(4, 0) = 0;
     39         diamond.at<uchar>(4, 1) = 0;
     40         diamond.at<uchar>(3, 0) = 0;
     41         diamond.at<uchar>(0, 4) = 0;
     42         diamond.at<uchar>(0, 3) = 0;
     43         diamond.at<uchar>(1, 4) = 0;
     44 
     45         //创建X形元素
     46         for (int i = 0; i < 5; i++) {
     47             x.at<uchar>(i, i) = 1;
     48             x.at<uchar>(4-i, i) = 1;
     49         }
     50     }
     51 
     52     //在检测角点特征的过程中,需要接连使用这些结构元素以得到最终的角点映射图
     53     Mat getCorners(const Mat &image) {
     54         Mat result;
     55         //十字形膨胀
     56         dilate(image, result, cross);
     57         //菱形腐蚀
     58         erode(result, result, diamond);
     59 
     60         Mat result2;
     61 
     62         //X形膨胀
     63         dilate(image, result2, x);
     64         //方形腐蚀
     65         erode(result2, result2, square);
     66 
     67         //通过对两张图像做差值得到角点图像
     68         absdiff(result2, result, result);
     69         //阈值化以得到二值图像
     70         applyThreshold(result);
     71 
     72         return result;
     73     }
     74     //为了更好的可视化检测的结果,使用下述方法在二值图像中的每个检测点上绘制一个园
     75     void drawOnImage(const Mat &binary, Mat &image) {
     76         Mat_<uchar>::const_iterator it = binary.begin<uchar>();
     77         Mat_<uchar>::const_iterator itend = binary.end<uchar>();
     78 
     79         //遍历每个像素
     80         for (int i = 0; it != itend; ++it, ++i) {
     81             if (!*it)
     82                 circle(image, Point(i%image.step, i / image.step), 5, Scalar(255, 0, 0));
     83         }
     84     }
     85     void setThreshold(int t) {
     86         threShold = t;
     87     }
     88     Mat getEdges(const Mat & image) {
     89         //得到梯度图
     90         Mat result;
     91         morphologyEx(image, result, MORPH_GRADIENT, Mat());
     92     
     93         //阈值化得到二值图像
     94         applyThreshold(result);
     95         return result;
     96     }
     97 
     98     void applyThreshold(Mat &result) {
     99         if (threShold > 0)
    100             threshold(result, result, threShold, 255, THRESH_BINARY);
    101     }
    102 };
    103 
    104 
    105 int main()
    106 {
    107     Mat    image = imread("C:\Users\Administrator\Pictures\Camera Roll\07.jpg");
    108 
    109     //创建形态学特征实例
    110     MorphoFeatures morpho;
    111     //morpho.setThreshold(40);
    112 
    113     //获取边缘
    114     Mat edges;
    115     edges = morpho.getEdges(image);
    116 
    117     //得到角点
    118     Mat corners;
    119     corners = morpho.getCorners(image);
    120 
    121     namedWindow("边缘");
    122     imshow("边缘", edges);
    123 
    124     namedWindow("角点");
    125     imshow("角点", corners);
    126 
    127     waitKey();
    128     return 0;
    129 }
    130     
  • 相关阅读:
    权限设计
    ts infer关键字
    Array初始化 以及 Array.prototype.map()的一些问题
    同步、异步、事件循环
    Spring学习笔记(一)
    【面试】关于get和post两种方法的不同。
    【算法】背包问题
    当你在浏览器输入一个网址(如http://www.taobao.com),按回车之后发生了什么?
    数据库语句复习笔记
    【算法】雀魂启动(笔试题)
  • 原文地址:https://www.cnblogs.com/Nelsoner/p/6784938.html
Copyright © 2011-2022 走看看