【Python计算机视觉】Python全栈体系(二十五)

计算机视觉

第五章 图像梯度处理

一、什么是图像梯度

  • 图像梯度计算的是图像变化的速度。对于图像的边缘部分,其灰度值变化较大,梯度值也较大;相反,对于图像中比较平滑的部分,其灰度值变化较小,相应的梯度值也较小。一般情况下,图像梯度计算的是图像的边缘信息。

二、模板运算

  • 模板(滤波器)是一个尺寸为n*n的小图像W(n一般取奇数,称为模板尺寸),每个位置上的值w被称为权重。在进行计算时,将模板的中心和像素P对齐,选取原始图像中和模板相同范围的邻域N的像素值作为输入。模板运算分为模板卷积、模板排序。
  • 模板卷积的计算是将对齐后的对应位置像素相乘,再进行累加作为像素P位置的输出值。记原始图像的像素灰度值为s,计算后的值为d,则P点的输出值

d = ∑ w i s i ∑ w i d = \frac{\sum w_is_i}{\sum w_i} d=wiwisi

  • 模板排序的计算时将邻域N的像素值进行排序,选择特定次序的灰度值,作为像素P位置的输出值,如最大值、最小值、中位数等。

三、均值滤波

  • 均值滤波指模板权重都为1的滤波器。它将像素的邻域平均值作为输出结果,均值滤波可以起到图像平滑的效果,可以去除噪声,但随着模板尺寸的增加图像会变得更为模糊。经常被作为模糊化使用。
    在这里插入图片描述

四、高斯滤波

  • 为了减少模板尺寸增加对图像的模糊化,可以使用高斯滤波器,高斯滤波的模板根据高斯分布来确定模板系数,接近中心的权重比边缘的大。5的高斯滤波器如下所示:
    在这里插入图片描述

五、中值滤波

  • 中值滤波属于模板排序运算的滤波器。中值滤波器将邻域内像素排序后的中位数值输出代替原像素值。它在实现降噪操作的同时,保留了原始图像的锐度,不会修改原始图像的灰度值。
  • 中值滤波的使用非常普遍,它对椒盐噪声的抑制效果很好,在抑制随机噪声的同时能有效保护边缘少受模糊。但中值滤波是一种非线性变化,它可能会破坏图像中线性关系,对于点、线等细节较多的图像和高精度的图像处理任务中并不太合适。
    在这里插入图片描述

六、边沿检测

  • 通过梯度计算可以获取图像中细节的边缘。为在锐化边缘的同时减少噪声的影响,通过改进梯度法发展出了不同的边缘检测算子:
    • 一阶梯度:Prewitt梯度算子、Sobel梯度算子
    • 二阶梯度:Laplacian梯度算子
      在这里插入图片描述
  • 边沿检测效果
    在这里插入图片描述

七、锐化

  • 图像锐化与图像平滑是相反的操作,锐化是通过增强高频分量来减少图像中的模糊,增强图像细节边缘和轮廓,增强灰度反差,便于后期对目标的识别和处理。锐化处理在增强图像边缘的同时也增加了图像的噪声。
  • 将求取的边缘按照一定系数比例叠加到原始图像上,即可实现对图像的锐化操作。例如使用Laplacian梯度算子进行锐化操作的模板,其中A是大于等于1的系数:
    在这里插入图片描述

八、代码

# 图像模糊化处理
import cv2
import numpy as np

im = cv2.imread("../data/lena.jpg", 0)
cv2.imshow("im", im)

# 中值滤波
im_median_blur = cv2.medianBlur(im, 5)
cv2.imshow("im_median_blur", im_median_blur)

# 均值滤波
im_mean_blur = cv2.blur(im, (3, 3))
cv2.imshow("im_mean_blur", im_mean_blur)

# 高斯滤波
im_gaussian_blur = cv2.GaussianBlur(im, (5, 5), 3)
cv2.imshow("im_gaussian_blur", im_gaussian_blur)

# 自定义高斯核执行滤波计算
gaussian_blur = np.array([
    [1, 4, 7, 4, 1],
    [4, 16, 26, 16, 4],
    [7, 26, 41, 26, 7],
    [4, 16, 26, 16, 4],
    [1, 4, 7, 4, 1]
], np.float32) / 273

# 使用filter2D执行滤波计算
im_gaussian_blur2 = cv2.filter2D(im,  # 原始图像
                                 -1,  # 目标图像深度,-1表示和原图像相同
                                 gaussian_blur)  # 滤波器
cv2.waitKey()  # 等待用户按某个按键
cv2.destroyAllWindows()  # 销毁所有创建的窗口

在这里插入图片描述

# 图像锐化
import cv2
import numpy as np

im = cv2.imread("../data/lena.jpg", 0)
cv2.imshow("im", im)

# 锐化算子1
sharpen_1 = np.array([[-1, -1, -1],
                      [-1, 9, -1],
                      [-1, -1, -1]])
im_sharpen1 = cv2.filter2D(im,
                           -1,
                           sharpen_1)
cv2.imshow("im_sharpen1", im_sharpen1)

# 锐化算子2
sharpen_2 = np.array([[0, -1, 0],
                      [-1, 8, -1],
                      [0, 1, 0]]) / 4.0
im_sharpen2 = cv2.filter2D(im,
                           -1,
                           sharpen_2)
cv2.imshow("im_sharpen2", im_sharpen2)

cv2.waitKey()  # 等待用户按某个按键
cv2.destroyAllWindows()  # 销毁所有创建的窗口

在这里插入图片描述

第六章 图像轮廓

一、什么是图像轮廓

  • 边缘检测虽然能够检测出边缘,但边缘是不连续的,检测到的边缘并不是一个整体。图像轮廓是将边缘连接起来形成的一个整体,用于后续的计算。
  • 图像轮廓是图像中非常重要的一个特征信息,通过对图像轮廓的操作,我们能够获取目标图像的大小、位置、方向等信息。
  • 图像轮廓操作包括:查找轮廓、绘制轮廓、轮廓拟合等。

二、查找和绘制轮廓

  • 一个轮廓对应着一系列的点,这些点以某种方式表示图像中的一条曲线,将这些点绘制成不同样式的线条,就是轮廓查找与绘制
    在这里插入图片描述

三、轮廓拟合

  • 在计算轮廓时,可能并不需要实际的轮廓,而仅需要一个接近于轮廓的近似多边形,绘制这个近似多边形称之为轮廓拟合

四、矩形包围框

在这里插入图片描述

五、最小包围圆形

在这里插入图片描述

六、最优拟合椭圆

在这里插入图片描述

七、逼近多边形

在这里插入图片描述

八、代码

1. 查找并绘制轮廓
# 查找并绘制轮廓
import cv2
import numpy as np

im = cv2.imread("../data/3.png")
cv2.imshow("im", im)

# 灰度化
im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
# 二值化
ret, im_binary = cv2.threshold(im_gray, 127, 255, cv2.THRESH_BINARY)
# cv2.imshow("im_binary", im_binary)

# 查找轮廓
cnts, hie = cv2.findContours(im_binary,  # 原图(经过二值化处理后的)
                             cv2.RETR_EXTERNAL,  # 只检测外轮廓
                             cv2.CHAIN_APPROX_NONE)  # 存储所有轮廓点
# print(type(cnts)) # tuple
# for cnt in cnts:
#     # print(type(cnt)) # <class 'numpy.ndarray'>
#     print(cnt.shape)
#     """
#     (257, 1, 2)
#     (371, 1, 2)
#     (336, 1, 2)
#     (228, 1, 2)
#     """

# 绘制轮廓
im_cnt = cv2.drawContours(im,  # 原始图像
                          cnts,  # 轮廓数据,findContours的返回值
                          -1,  # 绘制所有轮廓
                          (0, 0, 255),  # 轮廓颜色:红色
                          2)  # 轮廓粗细
cv2.imshow("im_cnt", im_cnt)
cv2.waitKey()  # 等待用户按某个按键
cv2.destroyAllWindows()  # 销毁所有创建的窗口

在这里插入图片描述

2. 绘制矩形包围框
# 绘制轮廓外接矩形框
import cv2
import numpy as np

im = cv2.imread("../data/cloud.png", 0)
cv2.imshow("im", im)

# 二值化处理
ret, im_binary = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)
cnts, hie = cv2.findContours(im_binary,
                                  cv2.RETR_LIST,  # 不建立等级关系
                                  cv2.CHAIN_APPROX_NONE)  # 存储轮廓所有坐标点
# print(cnts[0].shape) # (498, 1, 2)

# 根据轮廓产生外接矩形框参数
x, y, w, h = cv2.boundingRect(cnts[0])

# 绘制矩形框
brcnt = np.array([[[x, y]], [[x+w, y]],[[x+w,y+h]], [[x, y+h]]])
cv2.drawContours(im, [brcnt], -1, (255, 255, 255), 2)
cv2.imshow("result", im)

cv2.waitKey()  # 等待用户按某个按键
cv2.destroyAllWindows()  # 销毁所有创建的窗口

在这里插入图片描述

3. 绘制圆形包围圈
# 绘制轮廓的最小圆形包围圈
import cv2
import numpy as np

im = cv2.imread("../data/cloud.png", 0)
cv2.imshow("im", im)

# 二值化处理
ret, im_binary = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)
cnts, hie = cv2.findContours(im_binary,
                             cv2.RETR_LIST,
                             cv2.CHAIN_APPROX_NONE)
(x, y), radius = cv2.minEnclosingCircle(cnts[0])  # 产生轮廓的最小外接圆形参数
print((x, y), radius)  # (204.5, 91.5) 86.53621673583984
center = (int(x), int(y))  # 将圆心的坐标转换为整型
radius = int(radius)  # 将半径转换为整型

cv2.circle(im, center, radius, (255, 255, 255), 2)  # 绘制圆形
cv2.imshow("result", im)
cv2.waitKey()  # 等待用户按某个按键
cv2.destroyAllWindows()  # 销毁所有创建的窗口

在这里插入图片描述

4. 绘制最佳拟合椭圆
# 绘制最优拟合椭圆
import cv2
import numpy as np

im = cv2.imread("../data/cloud.png")
cv2.imshow("im", im)

im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, im_binary = cv2.threshold(im_gray, 127, 255, cv2.THRESH_BINARY)
# 提取轮廓
cnts, hie = cv2.findContours(im_binary,
                             cv2.RETR_LIST,
                             cv2.CHAIN_APPROX_NONE)
ellipse = cv2.fitEllipse(cnts[0])  # 产生最优拟合椭圆数据
print("ellipse",
      ellipse)  # ellipse ((204.24952697753906, 91.23741149902344), (69.94644165039062, 162.95944213867188), 84.70285034179688)

cv2.ellipse(im, ellipse, (0, 0, 255), 2)  # 绘制椭圆
cv2.imshow("result", im)
cv2.waitKey()  # 等待用户按某个按键
cv2.destroyAllWindows()  # 销毁所有创建的窗口

在这里插入图片描述

5. 逼近多边形
# 使用多边形对轮廓进行拟合
import cv2
import numpy as np

im = cv2.imread("../data/cloud.png")
cv2.imshow("im", im)

# 转灰度图像
im_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
# 二值化
ret, im_binary = cv2.threshold(im_gray, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
cnts, hie = cv2.findContours(im_binary,
                             cv2.RETR_LIST,
                             cv2.CHAIN_APPROX_NONE)
# 精度一
adp = im.copy()
epsilon = 0.005 * cv2.arcLength(cnts[0], True)  # 精度,根据周长计算
approx = cv2.approxPolyDP(cnts[0], epsilon, True)  # 构造多边形,返回多边形数据
adp = cv2.drawContours(adp, [approx], 0, (0, 0, 255), 2)  # 绘制
cv2.imshow("result_0.005", adp)

# 精度二
adp2 = im.copy()
epsilon = 0.01 * cv2.arcLength(cnts[0], True)  # 精度,根据周长计算
approx = cv2.approxPolyDP(cnts[0], epsilon, True)  # 构造多边形,返回多边形数据
adp = cv2.drawContours(adp2, [approx], 0, (0, 0, 255), 2)  # 绘制
cv2.imshow("result_0.01", adp2)

cv2.waitKey()  # 等待用户按某个按键
cv2.destroyAllWindows()  # 销毁所有创建的窗口

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柠檬小帽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值