一.图像梯度处理
- 图像梯度处理是图像分析中的一个重要技术,用于检测图像中的边缘、纹理和结构。梯度表示图像亮度变化的方向和幅度,常用于边缘检测、特征提取和图像分割等任务。以下是 OpenCV 中常用的图像梯度处理方法及其函数。
1. 梯度计算
Sobel 算子--cv2.Sobel()`
Sobel 算子用于计算图像在水平和垂直方向的梯度。这有助于检测边缘。
函数:cv2.Sobel()
函数签名:
python
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
。
示例代码:
python
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()
函数签名:
python
cv2.Laplacian(src, ddepth, ksize=1, scale=1, delta=0, borderType=cv2.BORDER_DEFAULT)
参数解释:
src
:输入图像(通常是灰度图像)。ddepth
:目标图像的深度,常用cv2.CV_16S
或cv2.CV_8U
。ksize
:卷积核的大小(常用值为 1、3、5、7)。scale
:缩放系数(默认值 1)。delta
:添加的偏移量(默认值 0)。borderType
:边界类型(通常使用cv2.BORDER_DEFAULT
)。
示例代码:
python
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()
函数签名:
python
cv2.Canny(image, threshold1, threshold2, apertureSize=3, L2gradient=False)
参数解释:
image
:输入的灰度图像。threshold1
:第一个阈值,用于低梯度强度的边缘。threshold2
:第二个阈值,用于高梯度强度的边缘。apertureSize
:Sobel 算子的孔径大小(默认值 3)。L2gradient
:是否使用更精确的 L2 范数来计算梯度(默认值 False)。
示例代码:
python
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 中的一个函数,用于将两幅图像进行加权融合。它能够将两张图像按照指定的权重进行线性组合,从而得到一幅新的图像。这种操作常用于图像混合、图像叠加、以及在图像处理和计算机视觉中的各种应用。
函数签名
python
cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
参数解释
src1
: 第一幅输入图像,可以是多通道(如彩色图像)或单通道(如灰度图像)。alpha
: 第一幅图像的权重。该参数决定了src1
在结果图像中所占的比例。src2
: 第二幅输入图像,要求与src1
的大小和通道数相同。beta
: 第二幅图像的权重。该参数决定了src2
在结果图像中所占的比例。gamma
: 加到最终结果上的标量值,相当于图像整体的亮度调节。dst
(可选): 输出的目标图像,可以与src1
和src2
相同,也可以是新的图像。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)
处的像素值。alpha
和beta
控制图像的融合比例。gamma
控制结果图像的整体亮度。
示例代码
示例 1: 简单的图像混合
python
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: 添加亮度调整的图像融合
python
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()
函数原型:
python
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数组。
示例代码:
python
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()
函数原型:
python
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_8
、cv2.LINE_AA
(抗锯齿线)等。 -
hierarchy: 可选参数,通常不需要。如果指定了,通常用于选择按层绘制的轮廓。
-
maxLevel: 可选参数,用于限制绘制轮廓的最大层级,通常不需要设置。
示例
python
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()
函数。
示例代码:
python
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()