OpenCV--图像梯度处理,图片轮廓,边缘检测

一.图像梯度处理

  • 图像梯度处理是图像分析中的一个重要技术,用于检测图像中的边缘、纹理和结构。梯度表示图像亮度变化的方向和幅度,常用于边缘检测、特征提取和图像分割等任务。以下是 OpenCV 中常用的图像梯度处理方法及其函数。

1. 梯度计算

Sobel 算子–cv2.Sobel()`

Sobel 算子用于计算图像在水平和垂直方向的梯度。这有助于检测边缘。

函数:cv2.Sobel()

函数签名:

cv2.Sobel(src, ddepth, dx, dy, ksize, scale=1, delta=0, borderType=cv2.BORDER_DEFAULT)

参数解释:

  • src:输入图像(通常是灰度图像)。
  • ddepth:目标图像的深度,常用 cv2.CV_16S(有符号 16 位)或 cv2.CV_8U(无符号 8 位)。
  • dx:x 方向的导数阶数(0 表示不计算 x 方向的梯度)。
  • dy:y 方向的导数阶数(0 表示不计算 y 方向的梯度)。
  • ksize:Sobel 卷积核的大小(常用值为 1、3、5、7)。
  • scale:缩放系数,用于调整结果的大小(默认值 1)。
  • delta:在计算梯度值时添加的偏移量(默认值 0)。
  • borderType:边界类型,通常使用 cv2.BORDER_DEFAULT

示例代码:

import cv2
import numpy as np

# 读取灰度图像
gray_image = cv2.imread('gray_image.jpg', cv2.IMREAD_GRAYSCALE)

# 计算 x 方向的梯度
sobel_x = cv2.Sobel(gray_image, -1, 1, 0, ksize=3)

# 计算 y 方向的梯度
sobel_y = cv2.Sobel(gray_image,-1, 0, 1, ksize=3)

# 合并 x 和 y 方向的梯度
sobel_combined = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)

# 显示图像
cv2.imshow('Sobel X', sobel_x)
cv2.imshow('Sobel Y', sobel_y)
cv2.imshow('Sobel Combined', sobel_combined)
cv2.waitKey(0)
cv2.destroyAllWindows()
Laplacian 算子—cv2.Laplacian()

Laplacian 算子用于计算图像的二阶导数,常用于检测边缘和角点。

函数:cv2.Laplacian()

函数签名:

cv2.Laplacian(src, ddepth, ksize=1, scale=1, delta=0, borderType=cv2.BORDER_DEFAULT)

参数解释:

  • src:输入图像(通常是灰度图像)。
  • ddepth:目标图像的深度,常用 cv2.CV_16Scv2.CV_8U
  • ksize:卷积核的大小(常用值为 1、3、5、7)。
  • scale:缩放系数(默认值 1)。
  • delta:添加的偏移量(默认值 0)。
  • borderType:边界类型(通常使用 cv2.BORDER_DEFAULT)。

示例代码:

import cv2

# 读取灰度图像
gray_image = cv2.imread('1.jpg', cv2.IMREAD_GRAYSCALE)

# 计算 Laplacian
laplacian = cv2.Laplacian(gray_image, ksize=3)


# 显示图像
cv2.imshow('Laplacian', laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. Canny 边缘检测

Canny 边缘检测算法是一种多阶段边缘检测算法,用于检测图像中的边缘。

函数:cv2.Canny()

函数签名:

cv2.Canny(image, threshold1, threshold2, apertureSize=3, L2gradient=False)

参数解释:

  • image:输入的灰度图像。
  • threshold1:第一个阈值,用于低梯度强度的边缘。
  • threshold2:第二个阈值,用于高梯度强度的边缘。
  • apertureSize:Sobel 算子的孔径大小(默认值 3)。
  • L2gradient:是否使用更精确的 L2 范数来计算梯度(默认值 False)。

示例代码:

import cv2

# 读取灰度图像
gray_image = cv2.imread('gray_image.jpg', cv2.IMREAD_GRAYSCALE)

# Canny 边缘检测
edges = cv2.Canny(gray_image, 100, 200)

# 显示图像
cv2.imshow('Canny Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

这些函数和算法提供了强大的图像梯度处理能力,可以帮助你进行各种图像分析和处理任务。

3.cv2.addWeighted() --将两幅图像进行加权融合

cv2.addWeighted() 是 OpenCV 中的一个函数,用于将两幅图像进行加权融合。它能够将两张图像按照指定的权重进行线性组合,从而得到一幅新的图像。这种操作常用于图像混合、图像叠加、以及在图像处理和计算机视觉中的各种应用。

函数签名

cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])

参数解释

  • src1: 第一幅输入图像,可以是多通道(如彩色图像)或单通道(如灰度图像)。
  • alpha: 第一幅图像的权重。该参数决定了 src1 在结果图像中所占的比例。
  • src2: 第二幅输入图像,要求与 src1 的大小和通道数相同。
  • beta: 第二幅图像的权重。该参数决定了 src2 在结果图像中所占的比例。
  • gamma: 加到最终结果上的标量值,相当于图像整体的亮度调节。
  • dst (可选): 输出的目标图像,可以与 src1src2 相同,也可以是新的图像。
  • dtype (可选): 输出图像的数据类型。通常不需要指定,默认与输入图像类型一致。

函数功能

cv2.addWeighted() 计算如下公式来进行图像融合:

[ \text{dst}(x, y) = \text{src1}(x, y) \times \alpha + \text{src2}(x, y) \times \beta + \gamma ]

其中:

  • src1(x, y)src2(x, y) 分别表示两幅图像在位置 (x, y) 处的像素值。
  • alphabeta 控制图像的融合比例。
  • gamma 控制结果图像的整体亮度。

示例代码

示例 1: 简单的图像混合
import cv2

# 读取两幅图像
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')

# 调整图像大小使其相同
image1 = cv2.resize(image1, (400, 400))
image2 = cv2.resize(image2, (400, 400))

# 线性加权融合图像
alpha = 0.7
beta = 0.3
gamma = 0
blended_image = cv2.addWeighted(image1, alpha, image2, beta, gamma)

# 显示结果
cv2.imshow('Blended Image', blended_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这个示例中,我们读取了两幅图像并将其调整到相同的大小。使用 cv2.addWeighted() 函数以 0.7 和 0.3 的权重混合这两幅图像。gamma 设置为 0,表示不进行亮度调整。

示例 2: 添加亮度调整的图像融合
import cv2

# 读取两幅图像
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')

# 调整图像大小使其相同
image1 = cv2.resize(image1, (400, 400))
image2 = cv2.resize(image2, (400, 400))

# 线性加权融合图像,且添加亮度调整
alpha = 0.6
beta = 0.4
gamma = 50  # 提高亮度
blended_image = cv2.addWeighted(image1, alpha, image2, beta, gamma)

# 显示结果
cv2.imshow('Blended Image with Brightness', blended_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

使用 cv2.addWeighted() 调整图像的亮度和对比度。alpha 控制对比度,beta 控制亮度。通过将同一图像作为 src1 和 src2 使用,我们可以通过调整 alpha 和 beta 来改变图像的亮度和对比度。

二.绘制图像轮廓

  • 在计算机视觉中,绘制图像轮廓是一个常见的操作,用于可视化和分析图像中的边缘和形状。OpenCV 提供了几种方法来检测和绘制图像轮廓。以下是一些常用的方法和示例代码。

  • 在OpenCV中,cv2.findContours()cv2.drawContours()是两个常用于处理图像轮廓的函数。下面对这两个函数的参数进行详细说明。

1. cv2.findContours()

函数原型:
contours, hierarchy = cv2.findContours(image, mode, method)
参数说明:
  • image: 输入图像,通常为二值化图像(像素值为0或255)。在调用此函数之前,建议使用如cv2.threshold()cv2.Canny()等函数进行图像处理,确保图像是二值的。

  • mode: 轮廓检索模式,用于指定如何获取轮廓。选项包括:

    • cv2.RETR_EXTERNAL: 只提取最外层的轮廓。
    • cv2.RETR_LIST: 提取所有的轮廓,但不建立层级关系。
    • cv2.RETR_TREE: 提取所有轮廓,并重建轮廓之间的层级关系。
    • cv2.RETR_CCOMP: 提取所有的轮廓,并组织为两级层次结构。
  • method: 轮廓逼近方法,用于指定如何近似轮廓。选项包括:

    • cv2.CHAIN_APPROX_SIMPLE: 只保留水平、垂直和斜线段,省略所有冗余点,节省内存。
    • cv2.CHAIN_APPROX_NONE: 保留所有轮廓点,更详细,但是消耗更多内存。
返回值:
  • contours: 轮廓的列表,每个轮廓都是一组点的数组。
  • hierarchy: 结构体,表示轮廓之间的层级关系,通常为一个Numpy数组。
示例代码:
import cv2
import numpy as np

# 读取图像并转换为灰度图像
image = cv2.imread('image.jpg')
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 使用阈值处理将图像转换为二值图像
_, binary_image = cv2.threshold(gray_image, 127, 255, cv2.THRESH_BINARY)

# 检测轮廓
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 在原图像上绘制轮廓
contour_image = image.copy()
cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2)  # 绿色轮廓,线宽为 2

# 显示结果
cv2.imshow('Contours', contour_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. cv2.drawContours()

函数原型:
cv2.drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel)
参数说明:
  • image: 输入图像,要在其上绘制轮廓。

  • contours: 轮廓数组,通常是从findContours得到的contours

  • contourIdx: 要绘制的轮廓索引,可以是一个整数:

    • -1表示绘制所有轮廓。
    • 其他非负整数绘制特定索引的轮廓(例如,0表示第一个轮廓)。
  • color: 轮廓颜色,通常以BGR格式表示,如(255, 0, 0)表示红色。

  • thickness: 轮廓线的厚度:可以是正整数(表示线段的厚度),或者是cv2.FILLED(用指定颜色填充轮廓内)。

  • lineType: 线型,通常使用cv2.LINE_8cv2.LINE_AA(抗锯齿线)等。

  • hierarchy: 可选参数,通常不需要。如果指定了,通常用于选择按层绘制的轮廓。

  • maxLevel: 可选参数,用于限制绘制轮廓的最大层级,通常不需要设置。

示例

import cv2
import numpy as np

# 创建一个二值图像
image = np.zeros((400, 400), dtype=np.uint8)
cv2.rectangle(image, (50, 50), (350, 350), 255, -1)

# 查找轮廓
contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 在原图上绘制轮廓
output = np.zeros((400, 400, 3), dtype=np.uint8)
cv2.drawContours(output, contours, -1, (0, 255, 0), 3)

# 显示结果
cv2.imshow('Contours', output)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 使用 cv2.fillPoly() 填充轮廓

如果你想要填充轮廓区域,可以使用 cv2.fillPoly() 函数。

示例代码:
import cv2
import numpy as np

# 读取图像并转换为灰度图像
image = cv2.imread('image.jpg')
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 使用阈值处理将图像转换为二值图像
_, binary_image = cv2.threshold(gray_image, 127, 255, cv2.THRESH_BINARY)

# 检测轮廓
contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 在原图像上填充轮廓
filled_image = image.copy()
cv2.fillPoly(filled_image, contours, (0, 255, 0))  # 填充绿色区域

# 显示结果
cv2.imshow('Filled Contours', filled_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值