opencv(16)---图像边缘检测

来源:互联网 发布:怎么看端口是否被占用 编辑:程序博客网 时间:2024/05/01 03:18

边缘检测概述

作用

边缘检测可以提取图像重要轮廓信息, 减少图像内容, 可以用于分割图像、做特征提取等

一般步骤

滤波—-(滤出噪声対检测边缘的影响)
增强—-(可以将像素邻域强度变化凸显出来—梯度算子)
检测—-(阈值方法确定边缘)

边缘检测算子

Canny算子
Sobel算子
Scharr算子
Laplacian算子
Roberts 算子、Prewitt算子… …

Canny边缘检测

Canny边缘检测算子是John F.Canny于1986 年开发出来的一个多级边缘检测算法, Canny边缘检测算法以Canny的名字命名, 被很多人推崇为当今最优的边缘检测的算法。

步骤

  1. 消除噪声
    一般情况使用高斯平滑滤波器卷积降噪

  2. 计算梯度幅值和方向
    安装Sobel滤波器的步骤操作
    这里写图片描述

  3. 非极大值抑制
    排除非边缘像素

  4. 滞后阈值
    滞后阈值需要两个阈值(高阈值和低阈值)
    这里写图片描述

Canny()

函数原型

void Canny( InputArray image, OutputArray edges,            double threshold1, double threshold2,            int apertureSize = 3, bool L2gradient = false );
  • src: 输入原图像(一般为单通道8位图像)
  • dst: 输出边缘图像要求和src一样的尺寸和类型(单通道)
  • threshold1: 滞后阈值低阈值(用于边缘连接)
  • threshold2: 滞后阈值高阈值(控制边缘初始段)
    推荐高低阈值比值在2:1到3:1之间
  • apertureSize: 表示Sobel算子孔径大小, 默认值3
  • L2gradient: 计算图像梯度幅值的标识

代码

Mat srcImg = imread("1.jpg", 0);/*均值滤波---可以平滑图像,进行降噪处理,去除图像内部变化比较突兀的点*/blur(srcImg, srcImg, Size(5, 5));imshow("src", srcImg);Mat dstImg;/*边缘检测---设置两个阈值*/Canny(srcImg, dstImg, 30, 80);imshow("Canny", dstImg);waitKey(0);

运行结果

这里写图片描述

这里写图片描述

注意

在实际应用中,可以使用trackbar来控制canny的两个参数,动态观察变化

sobel边缘检测

基本概念

Sobel算子是一个主要用于边缘检测的离散微分算子, 它结合了高斯平滑和微分求导, 用来计算图像灰度函数的近似梯度。

步骤

分别在x和y两个方向求导
这里写图片描述

sobel()函数

函数原型

void Sobel( InputArray src, OutputArray dst, int ddepth,            int dx, int dy, int ksize = 3,            double scale = 1, double delta = 0,            int borderType = BORDER_DEFAULT );

src: 输入原图像
dst: 输出图像要求和src一样的尺寸和类型
ddepth: 输出图像的深度, 支持如下组合:
这里写图片描述

dx: X方向上的差分阶数
dy: Y方向上的差分阶数
ksize: 默认值3, 表示Sobel核大小, 1,3,5,7
scale: 计算导数值时的缩放因子, 默认值1, 表示不缩放
delta(δ): 表示在结果存入目标图之前可选的delta值, 默认值0
borderType: 边界模式, 一般采用默认

代码

Mat grad_x, grad_y;Mat abs_grad_x, abs_grad_y , dst;Mat src = imread("2.png", 0);imshow("src", src);Sobel(src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);convertScaleAbs(grad_x, abs_grad_x);imshow("X", abs_grad_x);Sobel(src, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);convertScaleAbs(grad_y, abs_grad_y);imshow("Y", abs_grad_y);addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);imshow("ALL ", dst);waitKey(0);destroyAllWindows();

知识点
1.CV_16S

Sobel(src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);convertScaleAbs(grad_x, abs_grad_x);imshow("X", abs_grad_x);

将图片的sobel检测以16位有符号的来进行存储,然后再将16位有符号数转为16位无符号数
2.读入以灰度图读入

Mat src = imread("2.png", 0);

运行结果

原图像
这里写图片描述

X方向
这里写图片描述

Y方向
这里写图片描述

X+Y方向
这里写图片描述

应用

计算摄像头聚焦程度

int FocusDetect0(Mat image){    Mat gray;    Mat grad_x,grad_y;    Mat abs_grad_x,abs_grad_y;    dst=img.clone();    int rowNumber=image.rows();    int colNumber=image.cols();    float result=0;    cvtColor(image,gray,COLOR_BGR2GRAY);//灰度转换    /*X方向梯度*/    Sobel(gray,grad_x,CV_16S,1,0,3,1,1,BORDER_DEFAULT);    convertScaleAbs(grad_x,abs_grad_x);    /*Y方向梯度*/    Sobel(gray,grad_y,CV_16S,0,1,3,1,1,BORDER_DEFAULT);    convertScaleAbs(grad_y,abs_grad_y);    addWeighted(abs_grad_x,0.5,abs_grad_y,0.5,0,dst);    imshow("Sobel",dst);    /*访问像素*/    for(int i=0;i<rowNumber;i++){        uchar* data=dst.ptr<uchar>(i);//获取第i行的首地址        for(int j=0;j<colNumber;j++){            result+=float(data[j]);        }    }    res_num=result/(rowNumber*colNumber);    result=0;}

对上面函数的引用

FocusDetect0(img);sprintf(Num,"%0.2f",res_num);Point org(35,35);putText(frame,Num,org,CV_FONT_HERSHEY_SIMPLEX,1.2f,CV_RGB(0,255,0),2);

Laplacian边缘检测

基本概念

Laplacian算子是n维欧几里德中的一个二阶微分算子。

Laplacian算子的定义
这里写图片描述

Laplacian函数

函数原型

void Laplacian( InputArray src, OutputArray dst, int ddepth,                int ksize = 1, double scale = 1, double delta = 0,                int borderType = BORDER_DEFAULT );

src: 输入原图像(单通道8位图像)
dst: 输出边缘图像要求和src一样的尺寸和通道数
ddepth: 目标图像的深度
Ksize: 用于计算二阶导数的滤波器孔径大小, 须为正奇数, 默认值1
scale: 可选比例因子, 默认值1
delta: 可选参数δ, 默认值0
borderType: 边界模式, 一般采用默认值

代码

Mat grad_x, grad_y;Mat abs_grad_x, abs_grad_y, dst;Mat abs_dst;Mat src = imread("1.jpg", 0);imshow("src", src);Laplacian(src, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);convertScaleAbs(dst, abs_dst);imshow("Laplacian", abs_dst);waitKey(0);destroyAllWindows();

运行结果

这里写图片描述

这里写图片描述

0 0
原创粉丝点击