从零搭建 OpenCV 项目(新手向)-- 第五天 OpenCV图像预处理(四)

目录

一、图像梯度处理

1. 什么是图像梯度?

2. 梯度的数学形式

3.常见的梯度计算方法(近似求导)

3.1 Sobel算子

 3.2 Laplacian算子

二、图像边界检测

1. 边缘检测目标

2. Canny 边缘检测整体流程

3. 各步骤详解与 OpenCV 实现

3.1 高斯滤波(Gaussian Blur)

3.2 计算图像梯度和方向(Sobel 算子)

 3.3 非极大值抑制(NMS)

3.4 双阈值筛选(Double Threshold)

3.5  边缘连接(Hysteresis)

4. Canny 边缘检测 API

5. 案例

三、绘制图像轮廓

1. 什么是图像轮廓(Contours)

2. 寻找轮廓:cv2.findContours()

 3. mode 参数(轮廓检索模式)

3.1 RETR_EXTERNAL

3.2 RETR_LIST

3.3 RETR_CCOMP

3.4 RETR_TREE

3.5 总结

4. method 参数(轮廓逼近方法)

 5. 绘制轮廓:cv2.drawContours()

函数原型

6. 案例

四、凸包特征检测

1.什么是凸包(Convex Hull)

2. 凸包特征检测的作用

3. 凸包检测的常见方法

3.1 穷举法(Brute-force)

3.2 QuickHull 算法(快速凸包)

五、图像轮廓特征查找

1. 基本概念

2. 应用场景

3. 常见的轮廓特征提取方法

3.1 外接矩形(Bounding Rectangle)

3.2 最小外接矩形(Rotated Rectangle)

3.3 最小外接圆(Minimum Enclosing Circle)

3.4 总结


一、图像梯度处理

1. 什么是图像梯度?

图像梯度可以简单理解为图像像素值(灰度值)在某个方向上的变化率(类似数学上的导数):

  • 梯度方向:灰度变化最大的方向(即边缘的方向垂直线)

  • 梯度幅值:灰度值变化的快慢,值越大表示变化越明显(可能是边缘)

图像梯度就是——图像中像素亮度变化的快慢和方向

你可以把它想象成在一张图像上“摸”地形的感觉:

如果亮度变化平稳,摸起来就像平地;

如果亮度突然变得很亮或很暗,就像遇到了一个“陡坡”——这就是边缘

图像梯度就是帮我们找到这些“坡”,也就是图像中“变化剧烈”的地方。

2. 梯度的数学形式

对于一个灰度图像 $f(x, y)$,在位置 $(x, y)$ 处的图像梯度可以表示为二维向量:

  • $\frac{\partial f}{\partial x}$ 表示水平方向的变化(横向边缘)

  • $\frac{\partial f}{\partial y}$ 表示垂直方向的变化(纵向边缘)

模拟一张灰度图:

import cv2 as cv
import numpy as np
# 模拟一张图像,灰度图
img=np.array([[100,102,109,110,98,20,19,18,21,22],
             [109,101,98,108,102,20,21,19,20,21],
             [109,102,105,108,98,20,22,19,19,18],
             [109,98,102,108,102,20,23,19,20,22],
             [109,102,105,108,98,20,22,19,20,18],
             [100,102,108,110,98,20,19,18,21,22],
             [109,101,98,108,102,20,22,19,20,21],
             [109,102,108,108,98,20,22,19,19,18],
              ],dtype=np.float32)
# 定义卷积核,
kernel=np.array([[-1,0,1],
                 [-2,0,2],
                 [-1,0,1]],dtype=np.float32)
# 二维卷积操作
img2=cv.filter2D(img,-1,kernel)
# 打印卷积后的图
print(img2)

输出:

3.常见的梯度计算方法(近似求导)

由于图像是离散的,所以我们常用卷积的方式近似求导。

3.1 Sobel算子

加权平滑,抗噪能力强:

Sobel-X:               Sobel-Y:
[-1 0 +1]              [-1 -2 -1]
[-2 0 +2]              [ 0  0  0]
[-1 0 +1]              [+1 +2 +1]

上面的两个卷积核都叫做Sobel算子,只是方向不同,它先在垂直方向计算梯度

G_{x}=k_{1}\times s r c\displaystyle

再在水平方向计算梯度:

G_{y}=k_{2}\times s r c\displaystyle

最后求出总梯度:

G={\sqrt{G x^{2}+G y^{2}}}\displaystyle

在梯度处理方式这个组件中,当参数filter_method选择Sobel时,其他参数的含义如下所述:

**sobel_image = cv2.Sobel(src, ddepth, dx, dy, ksize)**

**src**:这是输入图像,通常应该是一个灰度图像(单通道图像),因为 Sobel 算子是基于像素亮度梯度计算的。在彩色图像的情况下,通常需要先将其转换为灰度图像。

**ddepth**:这个参数代表输出图像的深度,即输出图像的数据类型。在 OpenCV 中,-1 表示输出图像的深度与输入图像相同。

**dx,dy**:当组合为dx=1,dy=0时求x方向的一阶导数,在这里,设置为1意味着我们想要计算图像在水平方向(x轴)的梯度。当组合为    dx=0,dy=1时求y方向的一阶导数(如果同时为1,通常得不到想要的结果,想两个方向都处理的比较好 学习使用后面的算子)

**ksize**:Sobel算子的大小,可选择3、5、7,默认为3。

很多人疑问,Sobel算子的卷积核这几个值是怎么来的呢?事实上,并没有规定,你可以用你自己的。比如,最初只利用邻域间的原始差值来检测边缘的Prewitt算子:

k=\left[{\begin{array}{r r r}{-1}&{0}&{1}\\ {-1}&{0}&{1}\\ {-1}&{0}&{1}\end{array}}\right]\displaystyle

Prewitt-X:             Prewitt-Y:
[-1 0 +1]              [-1 -1 -1]
[-1 0 +1]              [ 0  0  0]
[-1 0 +1]              [+1 +1 +1]

还有比Sobel更好用的Scharr算子,大家可以了解下:

k=\left[{\begin{array}{r r r}{-3}&{0}&{3}\\ {-10}&{0}&{10}\\ {-3}&{0}&{3}\end{array}}\right]\displaystyle

Scharr-X:              Scharr-Y:
[-3 0 +3]              [-3 -10 -3]
[-10 0 +10]            [ 0   0  0]
[-3 0 +3]              [+3 +10 +3]

案例:

import cv2 as cv
import numpy as np
#读图
shu = cv.imread("D:\OpenCV_notes\day04\images\\shudu.png",cv.IMREAD_GRAYSCALE)
cv.imshow("shudu",shu)
#sobel 
# dx=1,dy=0 水平方向上差分 提取垂直边缘
dst=cv.Sobel(shu,-1,1,0,ksize=3)
cv.imshow("sobel",dst)

# dx=0 dy=1 垂直方向上差分 提取水平边缘
dst1=cv.Sobel(shu,-1,0,1,ksize=3)
cv.imshow("sobel1",dst1)

cv.waitKey(0)
cv.destroyAllWindows()

原图:

sobel水平差分后--sobel:

sobel垂直差分后--sobel1:

 

 3.2 Laplacian算子

高数中用一阶导数求极值,在这些极值的地方,二阶导数为0,所以也可以通过求二阶导k=\left[\begin{array}{c c c}{0}&{1}&{0}\\ {1}&{-4}&{1}\\ {0}&{1}&{0}\end{array}\right]\displaystyle

计算梯度:

d s t={\frac{\partial^{2}f}{\partial x^{2}}}+{\frac{\partial^{2}f}{\partial y^{2}}}\displaystyle

一维的一阶和二阶差分公式分别为:

{\frac{\partial f}{\partial x}}=f(x+1)-f(x)\displaystyle

{\frac{\partial^{2}f}{\partial x^{2}}}=f(x+1)+f(x-1)-2f(x)\displaystyle

提取前面的系数,那么一维的Laplacian滤波核是:

k=[1~~-2~~~1]\displaystyle

而对于二维函数f(x,y),两个方向的二阶差分分别是:

{\frac{\partial^{2}f}{\partial x^{2}}}=f(x+1,y)+f(x-1,y)-2f(x,y)\displaystyle

{\frac{\partial^{2}f}{\partial y^{2}}}=f(x,y+1)+f(x,y-1)-2f(x,y)\displaystyle

合在一起就是:

V^{2}f(x,y)=f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)-4f(x,y)\displaystyle

同样提取前面的系数,那么二维的Laplacian滤波核就是:

k=\left[\begin{array}{c c c}{0}&{1}&{0}\\ {1}&{-4}&{1}\\ {0}&{1}&{0}\end{array}\right]\displaystyle

这就是Laplacian算子的图像卷积模板,有些资料中在此基础上考虑斜对角情况,将卷积核拓展为:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值