Opencv之边缘检测(一)

OpenCV三种边缘检测简介

一般步骤

  1. 滤波,以除去噪声
  2. 增强,将领域内有显著变化的像素点凸显
  3. 检测,从可疑边缘点中舍去非边缘点,一般用threshold进行处理

Canny算子

步骤

  1. 采用size=5的高斯内核进行卷积降噪
    K= 1139 245424912945121512549129424542
  2. 计算梯度幅值和方向——此处采用sobel算法
  3. 非极大值抑制,排除非边缘像素
  4. 滞后阀值
    • 若幅值->(low, high),当且仅当连接到一个高于high阀值的像素时被保留
    • 若幅值>high阀值,保留
    • 若幅值

应用代码

canny(src, dst, low, high, 3);

Sobel算子

水平方向求导:

K=121000+1+2+1I

 sobel(src, grad_x, CV_16S, 1, 0, 3, scale=1, delta=1, BORDER_DEFAULT);
 convertScaleAbs(grad_x, abs_grad_x);

垂直方向求导:

K=121000+1+2+1I

sobel(src, grad_x, CV_16S, 0, 1, 3, scale=1, delta=1, BORDER_DEFAULT);
convertScaleAbs(grad_y, abs_grad_y);

合并梯度

addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);

Laplacian算子

Laplacian(src, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);

Scharr 滤波器

当内核大小为 3 时, 以上Sobel内核可能产生比较明显的误差(毕竟,Sobel算子只是求取了导数的近似值)。 为解决这一问题,OpenCV提供了 Scharr 函数,但该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果却更加精确。
以下两句代码等价,由于两者参数几乎一致(除了Scharr舍去了ksize,因为默认为3,且不可修改)

Scharr(src, dst, CV_16S, dx, dy, scale=1, delta=1, BORDER_DEFAULT);

Sobel(src, dst, CV_16S, dx, dy, CV_SCHARR, scale=1, delta=1, BORDER_DEFAULT);

示例代码:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;

/** @function main */
int main( int argc, char** argv )
{

  Mat src, src_gray;
  Mat grad;
  char* window_name = "Sobel Demo - Simple Edge Detector";
  int scale = 1;
  int delta = 0;
  int ddepth = CV_16S;

  int c;

  /// 装载图像
  src = imread( argv[1] );

  if( !src.data )
  { return -1; }

  GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );

  /// 转换为灰度图
  cvtColor( src, src_gray, CV_RGB2GRAY );

  /// 创建显示窗口
  namedWindow( window_name, CV_WINDOW_AUTOSIZE );

  /// 创建 grad_x 和 grad_y 矩阵
  Mat grad_x, grad_y;
  Mat abs_grad_x, abs_grad_y;

  /// 求 X方向梯度
  //Scharr( src_gray, grad_x, ddepth, 1, 0, scale, delta, BORDER_DEFAULT );
  Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_x, abs_grad_x );

  /// 求Y方向梯度
  //Scharr( src_gray, grad_y, ddepth, 0, 1, scale, delta, BORDER_DEFAULT );
  Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
  convertScaleAbs( grad_y, abs_grad_y );

  /// 合并梯度(近似)
  addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );

  imshow( window_name, grad );

  waitKey(0);

  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值