canny边缘检测_【OpenCV实例笔记】特征检测

e4e8d2926146f74279964be78223d716.png

写在前面:理论的东西不多说,主要是做一一个实例的小笔记。

操作环境:Ubuntu 16.04, OpenCV 3.2,C++


定义

特征检测(feature detection)是图像处理和计算机视觉里的一个概念。它指的是使用计算机提取图像信息,决定每个图像的点是否属于一个图像特征。特征检测的结果是把图像上的点分为不同的子集,这些子集往往属于孤立的点、连续的曲线或者连续的区域。(摘自Wikipedia)

分类

  • 边缘检测

边缘指组成两个图像区域之间边界(或边缘)的像素。

9b2be3e727843faf05b569a84001fabe.png
橘子的边缘
  • 角检测

角指图像中点似的特征,在局部它有两维结构。

8feb85f0181bb77527170b9f6705d925.png
齿轮的角点
  • 区域检测

与角不同的是区域描写一个图像中的一个区域性的结构,但是区域也可能仅由一个像素组成,因此许多区域检测也可以用来监测角。

*区域检测可以被想象为把一张图像缩小,然后在缩小的图像上进行角检测。

  • 脊检测

长条形的物体被称为脊。在实践中脊可以被看作是代表对称轴的一维曲线,此外局部针对于每个脊像素有一个脊宽度。从灰梯度图像中提取脊要比提取边缘、角和区域困难。在空中摄影中往往使用脊检测来分辨道路,在医学图像中它被用来分辨血管。


今天主要介绍的实例是Harris角点检测,Canny边缘检测,Hough变换(直线和圆的检测)

1. Harris角点检测

b805d1ccd53c3588213c47ec7c95dadb.png

源码(C++):

#define _CRT_SECURE_NO_WARNINGS

运行结果:

8feb85f0181bb77527170b9f6705d925.png

这里用到一个OpenCV的函数:

void cv::goodFeaturesToTrack(
         InputArray image,                   /* 输入矩阵,8位浮动点数 */
         OutputArray corners,                /* 输出矩阵,检测出的角点的矢量 */
         int maxCorners,                     /* 检测角点的最大数的允许值 */
         double qualityLevel,                /* 角点检测的最低质量允许值 */
         double minDistance                  /* 检测出的角点间最小欧式距离的允许值 */
);

2. Canny边缘检测

17b0a5f82536c600c746f3221b01374b.png

源码(C++):

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
std::string win_src = "src";
std::string win_dst = "dst";

int main()
{
  cv::Mat img_src = cv::imread("./01-02.jpg", 1);
  cv::Mat img_gray, img_dst;

  if (!img_src.data) {
    std::cout << "error" << std::endl;
    return -1;
  }

  //彩图转灰度图
  cv::cvtColor(img_src, img_gray, cv::COLOR_BGR2GRAY);

  // Canny边缘检测法
  cv::Canny(img_gray, img_dst, 350, 1000);

  // 生成界面窗口
  cv::namedWindow(win_src, cv::WINDOW_AUTOSIZE);
  cv::namedWindow(win_dst, cv::WINDOW_AUTOSIZE);

  // 显示图片
  cv::imshow(win_src, img_src);
  cv::imshow(win_dst, img_dst);

  cv::waitKey(0);

  return 0;
}

运行结果:

85d08dea468784a85f79fc579a97b31a.png

这里用到一个OpenCV的函数:

void cv::Canny(
         InputArray image,                   /* 输入矩阵,8位浮动点数,单通道 */
         OutputArray edges,                  /* 输出矩阵,检测出的边缘,8为浮动点数,单通道 */
         double threshold,                   /* Hysteresis参数1 */
         double threshold                    /* Hysteresis参数2 */
);

3. Hough变化(直线检测)

93339fbe8cd0702258dba6d3d3fbe938.png

源码(C++):

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
std::string win_src = "src";
std::string win_edge = "edge";
std::string win_dst = "dst";

int main()
{
  cv::Mat img_src = cv::imread("./01-03.jpg", 1);
  cv::Mat img_gray, img_edge, img_dst;

  if (!img_src.data) {
    std::cout << "error" << std::endl;
    return -1;
  }
  img_src.copyTo(img_dst);
  cv::cvtColor(img_src, img_gray, cv::COLOR_BGR2GRAY);

  cv::Canny(img_gray, img_edge, 200, 200);

  std::vector<cv::Vec2f> lines;
  // Hough变换检测直线
  cv::HoughLines(img_edge, lines, 1, CV_PI / 180, 120);

  for (int i = 0; i < lines.size(); i++) {
    double rho = lines[i][0], theta = lines[i][1];
    double a = cos(theta), b = sin(theta);
    double x0 = a*rho, y0 = b*rho;
    cv::line(img_dst,
      cv::Point(x0 - img_dst.cols*b, y0 + img_dst.cols*a),
      cv::Point(x0 + img_dst.cols*b, y0 - img_dst.cols*a),
      cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
  }

  cv::namedWindow(win_src, cv::WINDOW_AUTOSIZE);
  cv::namedWindow(win_dst, cv::WINDOW_AUTOSIZE);

  cv::imshow(win_src, img_src);
  cv::imshow(win_edge, img_edge);
  cv::imshow(win_dst, img_dst);

  cv::waitKey(0);

  return 0;
}

运行结果:

2deffa83678b4aad0221d53cdfaea0dc.png
Canny边缘检测

c1bcc2460de9f268f57f9b5b758d6fd3.png
Hough直线检测

这里用到一个OpenCV的函数:

void cv::HoughLines(
         InputArray image,                   /* 输入矩阵,8位浮动点数,单通道,二值图像 */
         OutputArray lines,                  /* 输出矩阵,检测出的直线 */
         double rho,                         /* 像素距离 */
         double theta                        /* 弧度制角度 */
         double threshold                    /* 累加平面的阈值参数,大于阈值threshold的线段
                                                才可以被检测通过并返回到结果中。 */
);

4. Hough变化(圆形检测)

efcb496005c99fefa5af1aa94b458085.png

源码(C++):

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
std::string win_src = "src";
std::string win_edge = "edge";
std::string win_dst = "dst";

int main()
{
  cv::Mat img_src = cv::imread("./01-04.jpg", 1);
  cv::Mat img_gray, img_edge, img_dst;

  if (!img_src.data) {
    std::cout << "error" << std::endl;
    return -1;
  }

  img_src.copyTo(img_dst);

  cv::cvtColor(img_src, img_gray, cv::COLOR_BGR2GRAY);

  cv::Canny(img_gray, img_edge, 80, 120);

  std::vector<cv::Vec3f> circles;
  cv::HoughCircles(img_edge, circles, cv::HOUGH_GRADIENT, 50, 100);

  for (int i = 0; i < circles.size(); i++) {
    cv::Point center((int)circles[i][0], (int)circles[i][1]);
    int radius = (int)circles[i][2];
    cv::circle(img_dst, center, radius, cv::Scalar(0, 0, 255), 3);
  }

  cv::namedWindow(win_src, cv::WINDOW_AUTOSIZE);
  cv::namedWindow(win_dst, cv::WINDOW_AUTOSIZE);

  cv::imshow(win_src, img_src);
  cv::imshow(win_edge, img_edge);
  cv::imshow(win_dst, img_dst);

  cv::waitKey(0);

  return 0;
}

运行结果:

9b2be3e727843faf05b569a84001fabe.png
Canny边缘检测

bdae013fe2e50a00ea0e8011870b521d.png
Hough圆形检测(网上找的图不是很好,效果不是很明显)

这里用到一个OpenCV的函数:

void cv::HoughCircles(
         InputArray image,                 /* 输入矩阵,8位浮动点数,单通道,二值图像 */
         OutputArray circles,              /* 输出矩阵,用(x, y, radius)来表示 */
         double method,                    /* 检测方法,现在OpenCV中只有霍夫梯度法(HOUGH_GRADIENT) */
         double dp                         /* 累加器分辨率相对于图像分辨率的比率 */
         double minDist                    /* 检测出的圆心之间的最小距离 */
);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值