[opencv]中一些函数的用法

1.cv2.bitwise_and()

cv2.bitwise_and() 是 OpenCV 中的位运算函数之一,用于对两幅二值图像进行按位“与”操作。具体来说,对于每个像素,将两幅输入图像相应位置的像素值分别进行按位“与”运算,输出的结果图像的对应像素值即为这两幅输入图像对应像素值的按位与结果。

cv2.bitwise_and() 函数的语法如下:

dst = cv2.bitwise_and(src1, src2[, mask])

其中,src1src2 表示要进行按位“与”操作的两幅输入图像;mask 是可选参数,如果指定了掩膜,则只对掩膜对应位置的像素进行按位“与”操作。函数的返回值 dst 表示按位“与”运算的结果。

import cv2
import numpy as np

# 创建两幅二值图像
img1 = np.zeros((300, 300), dtype=np.uint8)
img1[100:200, 100:200] = 100
img2 = np.zeros((300, 300), dtype=np.uint8)
img2[150:250, 150:250] = 255

# 对两幅二值图像进行按位"与"操作
result = cv2.bitwise_and(img1, img2)

# 显示结果图像
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('1', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

6d68193aa3be402fb51e598b7a75d14b.png

下面是一个使用了 mask 参数的例子:

import cv2
import numpy as np

# 读取图像
img = cv2.imread(r"C:\Users\asus\Desktop\20230104200344_6edae.thumb.1000_0.jpg")
# 创建与图像相同大小的掩膜
mask = np.zeros(img.shape[:2], dtype=np.uint8)
# 创建一个圆形掩膜,半径为100,中心为图像中心
mask = cv2.circle(mask, (img.shape[1]//2, img.shape[0]//2), 100, 100, -1)
# 将图像与掩膜进行位运算
masked_img = cv2.bitwise_and(img, img, mask=mask)

# 显示结果
cv2.imshow('image', img)
cv2.imshow('mask', mask)
cv2.imshow('masked_image', masked_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 17df1cdb30144d4680510762d2669c29.png1d63920ab53445ceb6cd2f91659d9d91.png24a355554de9414dba60fdd258e07195.png

 这个例子中,首先读取一张图像 image.jpg,然后创建一个与图像大小相同的掩膜。然后使用 cv2.circle() 创建了一个圆形掩膜,半径为100,中心为图像中心。最后使用 cv2.bitwise_and() 将图像与掩膜进行位运算,得到只包含圆形部分的图像 masked_img。最后将图像、掩膜和掩膜运算结果显示出来。

 2.cv2.threshold()/cv2.adaptiveThreshold()

(1)cv2.threshold() 是Python中OpenCV库中用于图像处理的函数。它用于对灰度或彩色图像应用固定级别的阈值。

该函数接受以下参数:

  • src:输入图像
  • thresh:阈值
  • maxval:将超过阈值的像素值分配的最大值。对于灰度图像,这通常设置为255。
  • type:要应用的阈值类型。这可以是两种类型之一:
    • cv2.THRESH_BINARY:像素值大于阈值的设置为maxval,小于阈值的设置为0。
    • cv2.THRESH_BINARY_INV:像素值大于阈值的设置为0,小于阈值的设置为maxval
  • dst:输出图像。

函数返回包含两个值的元组:

  • retval:使用的阈值值
  • dst:阈值化后的图像
    import cv2
    import numpy as np
    
    
    img2 = cv2.imread("C:/Users/asus/Desktop/20220802203106_eaafd.jpeg")
    img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
    ret, pic = cv2.threshold(img2gray, 100, 255, cv2.THRESH_BINARY)
    cv2.imshow('pic',pic)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

 bba9d7a04860452ea9df525bb7f835f7.png

(2)cv2.adaptiveThreshold 是 OpenCV 中的一个函数,用于对给定的图像执行自适应阈值处理。

阈值处理是一种常用的图像处理技术,用于将图像分割成两个区域,通常是将感兴趣的物体与背景分开。在阈值处理中,像素值与阈值进行比较,如果超过阈值,则被赋予一定的值,否则被赋予另一个值。

在自适应阈值处理中,阈值值不是固定的,而是根据每个像素附近的图像特征局部变化。这可以更好地处理图像中的光照、对比度和噪声等变化。

cv2.adaptiveThreshold 函数有以下参数:

  • src:输入图像。
  • maxValue:像素超过阈值时要赋的最大值。通常设置为 255。
  • adaptiveMethod:自适应阈值处理算法。有两个选项:cv2.ADAPTIVE_THRESH_MEAN_Ccv2.ADAPTIVE_THRESH_GAUSSIAN_C。前者将局部邻域内像素值的平均值作为阈值,后者将局部邻域内像素值的加权和作为阈值。
  • thresholdType:阈值处理类型。有两个选项:cv2.THRESH_BINARYcv2.THRESH_BINARY_INV。前者将超过阈值的像素赋为 maxValue,低于阈值的像素赋为 0,后者则相反。
  • blockSize:用于计算阈值的局部邻域的大小。这应该是一个奇数,通常设置为 3、5、7 等。
  • C:在计算阈值时从像素值的平均值或加权和中减去的常数值。这可以帮助调整阈值处理的敏感度。
import cv2

# 读取图像
img = cv2.imread('image.jpg', 0)

# 对图像执行自适应阈值处理
img_thresh = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)

# 显示原始图像和处理后的图像
cv2.imshow('Original', img)
cv2.imshow('Adaptive Threshold', img_thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这个例子中,我们首先读取了一张灰度图像,然后使用 cv2.adaptiveThreshold 函数对其执行自适应阈值处理。我们选择了 cv2.ADAPTIVE_THRESH_MEAN_C 算法来计算阈值,并将 blockSize 设为 11, C 设为 2,这意味着在计算阈值时会使用 11x11 的局部邻域,并从像素值的平均值中减去 2。最后,我们将 thresholdType 设置为 cv2.THRESH_BINARY,这意味着超过阈值的像素会被赋为 255,低于阈值的像素会被赋为 0。

运行上述代码后,我们将看到原始图像和处理后的图像分别显示在两个窗口中。处理后的图像中,像素值大于自适应阈值的像素被赋为白色(255),低于阈值的像素被赋为黑色(0)。

 3.HSV图像空间

HSV(即 Hue、Saturation、Value)是一种常用的颜色空间,常用于图像处理中的颜色分析和识别。HSV颜色空间将颜色表示为三个分量:色调(Hue)、饱和度(Saturation)和明(Value)。

OpenCV 中的 HSV 图像空间具有以下特点:

  1. HSV 图像空间将颜色的明度、饱和度和色相三个要素分离开来,方便对颜色进行分析和处理。

  2. 在 HSV 图像空间中,颜色的明度通过 V(value)通道表示,取值范围为 0-255,表示颜色的亮度程度。明度为 0 时,表示黑色,明度为 255 时,表示最亮的白色。

  3. 颜色的饱和度通过 S(saturation)通道表示,取值范围为 0-255,表示颜色的纯度程度。饱和度为 0 时,表示灰色,饱和度为 255 时,表示最鲜艳的颜色。

  4. 颜色的色相通过 H(hue)通道表示,取值范围为 0-180,表示颜色在色谱中的位置。H 通道是一个角度度量,因此其取值范围为 0-360 度,但 OpenCV 中将其除以了 2,变成了 0-180。色相表示颜色的种类,比如红色、绿色、蓝色等等。

因此,HSV 图像空间在图像处理中应用非常广泛,例如在颜色分割、目标跟踪、图像增强等方面都有很好的应用。

4.cv2.inRange

cv2.inRange() 函数是 OpenCV 中的一个图像分割函数,用于根据设定的阈值范围将输入图像中的像素分为两类:符合条件的像素和不符合条件的像素。

cv2.inRange() 函数的语法如下:

cv2.inRange(src, lowerb, upperb, dst=None)

其中,参数的含义如下:

  • src: 输入图像(单通道或三通道)
  • lowerb: 阈值下界(可以是标量或数组)
  • upperb: 阈值上界(可以是标量或数组)
  • dst: 输出图像,与输入图像大小相同,数据类型为 np.uint8

函数的返回值为输出图像 dst

cv2.inRange() 函数返回的是一个二值图像,其中像素的值为0或255,表示输入图像中对应像素是否符合设定的阈值范围。如果一个像素的值在阈值范围内,它在输出图像中对应的像素值为255;否则,输出图像中对应的像素值为0。

输出图像的数据类型为 np.uint8,它可以是单通道的灰度图像,也可以是三通道的彩色图像。如果输入图像是单通道图像,那么输出图像也是单通道的;如果输入图像是三通道图像,那么输出图像也是三通道的,但是每个通道的像素值都相同。

例子:追踪蓝色物体

import cv2
import numpy as np
cap=cv2.VideoCapture(0)
while(1):
# 获取每一帧
ret,frame=cap.read()
# 转换到 HSV
hsv=cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
# 设定蓝色的阈值
lower_blue=np.array([110,50,50])
upper_blue=np.array([130,255,255])
# 根据阈值构建掩模
mask=cv2.inRange(hsv,lower_blue,upper_blue)
# 对原图像和掩模进行位运算
res=cv2.bitwise_and(frame,frame,mask=mask)
# 显示图像
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k=cv2.waitKey(5)&0xFF
if k==27:
break
# 关闭窗口
cv2.destroyAllWindows()

24ef8185dc594f62ac54b91080689ab6.png

 4.仿射变换

原文链接:https://blog.csdn.net/m0_50294896/article/details/120577389

仿射变换(Affine Transformation)是指在向量空间中进行一次线性变换(乘以一个矩阵)和一次平移(加上一个向量),变换到另一个向量空间的过程。
仿射变换代表的是两幅图之间的映射关系,仿射变换矩阵为2x3的矩阵,如下图中的矩阵M,其中的B起着平移的作用,而A中的对角线决定缩放,反对角线决定旋转或错切。
98e59f0fd99846d6b0a28e4fb70d34f8.png#pic_center

 原像素点坐标(x,y),经过仿射变换后的点的坐标是T,则矩阵仿射变换基本算法原理:

6eb0ee97ef6c4e1ebbce68b6924c2b8d.png#pic_center

 (1)cv2.getAffineTransform

cv2.getAffineTransform() 是 OpenCV 中用于获取仿射变换矩阵的函数。

该函数接受三个点对,分别表示源图像中的三个点和目标图像中的三个点。通过这些点对,函数可以计算出一个 2 x 3 的仿射变换矩阵,该矩阵可以将源图像中的点映射到目标图像中的点。函数返回的矩阵可以用于 cv2.warpAffine() 函数中进行仿射变换。

(2)cv2.warpAffine()

cv2.warpAffine() 是 OpenCV 中用于执行仿射变换的函数。仿射变换是一种线性变换,可以通过平移、旋转和缩放来描述。该函数接受一个输入图像、一个仿射变换矩阵和一个输出图像大小。它使用指定的仿射变换矩阵对输入图像进行变换,并将变换后的图像作为输出。

import cv2
import numpy as np

# 定义源图像中的三个点和目标图像中的三个点
src_pts = np.float32([[50,50], [200,50], [50,200]])
dst_pts = np.float32([[10,100], [200,50], [100,250]])

# 计算仿射变换矩阵
M = cv2.getAffineTransform(src_pts, dst_pts)

# 对源图像进行仿射变换
img = cv2.imread('image.jpg')
img_out = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))

# 显示结果
cv2.imshow('Input', img)
cv2.imshow('Output', img_out)
cv2.waitKey(0)
cv2.destroyAllWindows()

(3)cv2.getRotationMatrix2D

cv2.getRotationMatrix2D() 是 OpenCV 中用于获取旋转矩阵的函数。该函数返回一个 2x3 的旋转矩阵,用于执行基于给定旋转中心和旋转角度的图像旋转。

该函数需要传递三个参数:旋转中心、旋转角度和缩放因子。其中,旋转中心是一个元组 (x,y),表示旋转中心的坐标。旋转角度是以度为单位的浮点数,表示要旋转的角度。缩放因子是一个浮点数,表示输出图像相对于输入图像的缩放因子。

import cv2
import numpy as np

# 读取图像
img = cv2.imread('image.jpg')

# 获取旋转矩阵
(h, w) = img.shape[:2]
center = (w // 2, h // 2)
angle = 45
scale = 1.0
M = cv2.getRotationMatrix2D(center, angle, scale)

# 对图像进行旋转
img_rotated = cv2.warpAffine(img, M, (w, h))

# 显示结果
cv2.imshow('Input', img)
cv2.imshow('Output', img_rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

5.Otsu’s 二值化

Otsu’s 二值化是一种自适应的图像二值化方法,它的核心思想是通过寻找最佳的阈值,将图像分割成前景和背景两个区域,使得分割后的图像的类间方差最大化,从而达到最佳的二值化效果。

具体来说,Otsu’s 二值化的实现过程可以分为以下几个步骤:

  1. 计算图像的灰度直方图,统计每个灰度级别的像素数目。

  2. 将灰度直方图归一化,得到每个灰度级别的像素出现概率。

  3. 从灰度级别 0 到 255,迭代计算每个灰度级别作为阈值时的类间方差,并找到最大的类间方差及其对应的阈值。

    具体来说,假设当前迭代到灰度级别 t,则将图像分为两个部分:灰度级别小于等于 t 的像素构成的前景部分和灰度级别大于 t 的像素构成的背景部分。设 W1和 W2 分别表示前景和背景部分所占比例,μ1​ 和 μ2​分别表示前景和背景部分的平均灰度值,G表示整幅图像的平均灰度值,则类间方差 var可以计算为:

    a266dcb1e188415ca7d9c0c45b92f8d2.png

    当 var 取最大值时,对应的阈值即为最佳阈值。

  4. 将图像根据最佳阈值进行二值化。

另一种解释:

“峰内方差最小”指的是基于 Otsu's 算法的另一种解释,即将灰度值分成两部分时,使得两部分的峰内方差最小。

在这种解释下,我们假设当前迭代到灰度级别 t,则将图像分为两个部分:灰度级别小于等于t的像素构成的前景部分和灰度级别大于 t的像素构成的背景部分。设eq?w_1eq?w_2分别表示前景和背景部分所占比例,

μ1​ 和 μ2分别表示前景和背景部分的平均灰度值,G表示整幅图像的平均灰度值,eq?%5Csigma_1%5E2eq?%5Csigma_2%5E2 分别表示前景和背景部分的灰度方差。那么,峰内方差可以表示为:6e56047bcc5f4794bbc3796a30d065ac.png

在 OpenCV 中,我们可以使用 cv2.threshold 函数来实现 Otsu’s 二值化,其具有以下参数:

  • src:输入图像。
  • thresh:手动指定的阈值。这里我们设为 0。(这时要把阈值设为 0。然后算法会找到最优阈值,这个最优阈值就是返回值 retVal。如果不使用 Otsu 二值化,返回的retVal 值与设定的阈值相等)
  • maxval:像素超过阈值时要赋的最大值。通常设置为 255。
  • type:阈值处理类型。在 Otsu’s 二值化中,我们应该使用cv2.THRESH_BINARY+cv2.THRESH_OTSU,其中 cv2.THRESH_OTSU 表示启用 Otsu’s 自动阈值确定方法。
  • dst:输出图像。在这里我们不需要输出图像,所以可以将其设为 None
    import cv2
    
    # 读取图像
    img = cv2.imread('image.jpg', 0)
    
    # 将图像进行 Otsu’s 二值化
    ret, img_thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    
    # 显示原始图像和处理后的图像
    cv2.imshow('Original', img)
    cv2.imshow('Otsu Threshold', img_thresh)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    6.cv2.filter2D

cv2.filter2D 是 OpenCV 中的一个函数,用于对图像进行二维卷积操作,也称为滤波操作。该函数可以对图像进行一般的线性滤波,包括平均滤波、高斯滤波、锐化等。

dst = cv2.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])

参数说明:

  • src:输入的图像。
  • ddepth:输出图像的深度,如果为-1,则输出图像的深度和输入图像相同。
  • kernel:卷积核,可以是 numpy 数组或者 Mat 对象。
  • dst:输出图像,可以为空。
  • anchor:锚点位置,默认为 (-1, -1) 表示中心点。
  • delta:可选的平移值,默认为0。
  • borderType:边界填充方式,可以是 cv2.BORDER_CONSTANT(常量填充)、cv2.BORDER_REPLICATE(复制边界)、cv2.BORDER_REFLECT(边界对称反射)等。

该函数的实现过程是,将卷积核作为一个滑动窗口,在图像上从左上角开始遍历,每次取窗口内的像素和卷积核对应位置的权值进行乘积累加,将结果写入输出图像中对应位置的像素值。

import cv2
import numpy as np

img = cv2.imread('test.jpg')
kernel = np.ones((5, 5), np.float32) / 25
dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('Original', img)
cv2.imshow('Filtered', dst)
cv2.waitKey(0)

7.cv2.GaussianBlur()

dst = cv2.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])

其中,参数说明如下:

  • src:输入图像,可以是灰度图像或彩色图像,数据类型为 uint8float32float64
  • ksize:高斯核的大小,必须为正奇数,如果为 (0, 0),则根据 sigma 值自动计算。
  • sigmaX:高斯核在水平方向上的标准差,如果为 0,则根据 ksize 自动计算。
  • dst:输出图像,与输入图像具有相同的尺寸和数据类型,可选参数。
  • sigmaY:高斯核在垂直方向上的标准差,如果为 0,则默认与 sigmaX 相同,可选参数。
  • borderType:边界填充方式,可选参数。
  • import cv2
    
    # 读取输入图像
    img = cv2.imread('input.png')
    
    # 对图像进行高斯平滑处理,sigmaX=sigmaY=3
    blur1 = cv2.GaussianBlur(img, (5, 5), 3, 3)
    
    # 对图像进行高斯平滑处理,sigmaX=5, sigmaY=1
    blur2 = cv2.GaussianBlur(img, (5, 5), 5, 1)
    
    # 对图像进行高斯平滑处理,sigmaX=1, sigmaY=5
    blur3 = cv2.GaussianBlur(img, (5, 5), 1, 5)
    
    # 显示结果图像
    cv2.imshow('input', img)
    cv2.imshow('output1', blur1)
    cv2.imshow('output2', blur2)
    cv2.imshow('output3', blur3)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    8.cv2.medianBlur

      是 OpenCV 库中的一个函数,用于对图像进行中值滤波。中值滤波是一种非线性滤波技术,用于从图像中去除噪声。它特别适用于去除椒盐噪声,这是一种可能在图像中出现随机黑白像素的噪声类型。

该函数接受以下参数:

  • src:要进行滤波的输入图像。
  • ksize:用于滤波的核的大小。它应该是一个正奇数。
  • dst:滤波后的输出图像。

该函数使用大小为 ksize 的核对输入图像应用中值滤波,并将滤波后的图像返回到 dst 中。中值滤波将图像中的每个像素替换为由核定义的邻域中像素的中值。邻域的大小由核的大小定义。

import cv2
import numpy as np

# 加载图像
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 应用中值滤波
filtered_img = cv2.medianBlur(img, 5)

# 显示滤波后的图像
cv2.imshow('Filtered Image', filtered_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

9.cv2.Laplacian

dst = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
  • src:需要进行拉普拉斯滤波的输入图像,可以是任何通道数的图像,数据类型为 uint8、float32 和 float64。
  • ddepth:输出图像的深度,通常设置为 -1(与输入图像相同)或 CV_64F(64 位浮点型)。
  • dst:输出图像,与 src 大小和数据类型相同,如果不指定,则会创建一个和 src 相同大小和数据类型的输出图像。
  • ksize:拉普拉斯算子的大小,必须是正的奇数(1、3、5、7 等),默认值为 
  • scale:拉普拉斯滤波器的比例因子,用于缩放拉普拉斯算子,默认值为 1。
  • delta:输出图像中的可选偏移量,默认值为 0。
  • borderType:像素填充方式,可以使用 cv2.BORDER_DEFAULT(默认)、cv2.BORDER_CONSTANTcv2.BORDER_REPLICATEcv2.BORDER_REFLECTcv2.BORDER_WRAP 等参数。
  • 例子
    import cv2
    
    # 读取图像
    img = cv2.imread('input_image.jpg')
    
    # 将图像转换为灰度图像
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 进行拉普拉斯滤波
    laplacian = cv2.Laplacian(gray, cv2.CV_64F, ksize=3)
    
    # 显示输出图像
    cv2.imshow('Laplacian Filter', laplacian)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    拉普拉斯滤波器的离散形式可以表示为一个二维的差分算子,如下所示:

    [0  1  0]
    [1 -4  1]
    [0  1  0]
    

    这个算子可以看作是一个圆形区域内像素值的二阶导数近似。在图像中,拉普拉斯滤波器的作用是找到像素值变化最快的地方,通常是边缘。

    在 OpenCV 中,cv2.Laplacian 函数会将图像与这个算子进行卷积,得到一个输出图像。在卷积的过程中,每个像素的值都是将其周围像素的值与拉普拉斯算子进行加权平均得到的。最后,输出图像中每个像素的值都是拉普拉斯算子在该像素位置的响应值。

    需要注意的是,拉普拉斯滤波器会增强图像中的高频噪声,因此在实际应用中,通常需要对其结果进行平滑处理。可以通过在拉普拉斯滤波之前先对图像进行高斯模糊处理,或者通过添加一个平滑的先验模型来实现。

10.cv2.Sobel

cv2.Sobel 函数是 OpenCV 中用于计算图像梯度的函数之一。它可以基于 Sobel 算子来计算图像在 x 方向和 y 方向的一阶导数,以及在两个方向上的二阶导数。

具体来说,cv2.Sobel 函数的参数包括:

  • 输入图像:可以是单通道灰度图像,也可以是多通道彩色图像。
  • 输出图像的深度:通常设置为 cv2.CV_64F,表示输出图像的像素值类型为浮点型。
  • x 方向和 y 方向的导数阶数:可以设置为 0、1 或 2,表示要计算的导数阶数。例如,设置为 1 表示计算一阶导数,设置为 2 表示计算二阶导数。
  • Sobel 算子的卷积核大小:可以通过 ksize 参数来指定。通常情况下,使用 3x3 或 5x5 的卷积核即可。如果设置为 -1,则表示使用默认的卷积核大小,即 3
  • 缩放因子和 delta 值:可以通过 scaledelta 参数来控制输出图像的缩放因子和偏置。默认情况下,scaledelta 都为 1,表示不进行缩放和偏置。
  • import cv2
    import numpy as np
    
    # 读取输入图像
    img = cv2.imread('lena.jpg', cv2.IMREAD_GRAYSCALE)
    
    # 计算 x 方向和 y 方向上的一阶导数
    sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
    sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
    
    # 将计算结果转换为 uint8 类型的图像
    sobelx = cv2.convertScaleAbs(sobelx)
    sobely = cv2.convertScaleAbs(sobely)
    
    # 将 x 方向和 y 方向上的导数相加,得到梯度图像
    sobel = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
    
    # 显示结果图像
    cv2.imshow('Sobel', sobel)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    在实际应用中,我们可以根据需要选择在 x 方向或 y 方向上计算导数,例如,如果我们要检测图像中水平方向上的边缘,就可以使用 Sobel 算子在 x 方向上计算导数,即 cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3),其中的 1 表示要在 x 方向上计算导数,0 表示不计算 y 方向上的导数。如果要检测垂直方向上的边缘,则需要交换这两个参数的位置,即 cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)

10.cv.scharr

如果 ksize=-1,会使用 3x3 的 Scharr 滤波器,它的的效果要 比 3x3 的 Sobel 滤波器好(而且速度相同,所以在使用 3x3 滤波器时应该尽量使用 Scharr 滤波器)。

cv2.Scharr() 函数的使用方式与 cv2.Sobel() 函数类似,它接受以下参数:

  • src:输入图像。
  • ddepth:输出图像的深度,可以使用 -1 表示与输入图像相同。
  • dx:表示要在 x 方向上计算导数的阶数。
  • dy:表示要在 y 方向上计算导数的阶数。
  • scale:缩放因子,可以用于缩放输出图像的像素值。
  • delta:偏移量,可以用于调整输出图像的亮度。
  • borderType:表示图像边界的处理方式,可以参考 cv2.Sobel() 中的参数。

下面是一个使用 cv2.Scharr() 函数进行边缘检测的示例代码:

import cv2

img = cv2.imread('image.jpg', 0)
sobelx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
sobely = cv2.Scharr(img, cv2.CV_64F, 0, 1)
sobel = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)

cv2.imshow('Scharr', sobel)
cv2.waitKey(0)
cv2.destroyAllWindows()

11.cv2.findContours

cv2.findContours是OpenCV中的一个函数,用于在二值化图像中查找轮廓。该函数返回图像中所有轮廓的信息,包括每个轮廓的坐标和层级关系等。其语法如下:

contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])

其中,参数说明如下:

  • image:输入的二值化图像,必须为8位单通道图像(如灰度图)。

  • mode:轮廓检索模式,指定如何检索轮廓。有以下四种模式可选:

    1.cv2.RETR_EXTERNAL:只检测外轮廓。

       2.cv2.RETR_LIST:检测所有轮廓,但不建立轮廓层级关系。

   3.cv2.RETR_CCOMP:检测所有轮廓,并将其组织成两层层级结构,顶层为物体的外轮廓,底层为物体内部的轮廓。

   4.cv2.RETR_TREE:检测所有轮廓,并重构轮廓层级关系。

  • method:轮廓逼近方法,指定如何逼近轮廓。有以下三种方法可选:

   1.cv2.CHAIN_APPROX_NONE:存储所有边界点。

   2.cv2.CHAIN_APPROX_SIMPLE:仅存储端点。

   3.cv2.CHAIN_APPROX_TC89_L1cv2.CHAIN_APPROX_TC89_KCOS:应用Teh-Chin链逼近算法,输出较少的点,但结果可能不太精确。

  • contours(可选):检测到的轮廓。这是一个由点组成的列表,每个点都表示轮廓上的一个坐标。如果不需要该参数,则可以省略。

  • hierarchy(可选):轮廓的层级信息。这是一个包含四个元素的列表,分别表示该轮廓的父轮廓、子轮廓、前一个轮廓和后一个轮廓。如果不需要该参数,则可以省略。

  • offset(可选):轮廓点坐标的偏移量。如果不需要该参数,则可以省略。

该函数返回两个值,分别为检测到的轮廓列表contours和轮廓的层级信息hierarchy。可以使用这些信息对轮廓进行进一步的处理,如绘制、裁剪等。

import cv2
import numpy as np

# load an image
image = cv2.imread('image.png')

# convert the image to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# threshold the image to obtain a binary image
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# find the contours
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# draw the contours on the original image
cv2.drawContours(image, contours, -1, (0, 255, 0), 3)

# display the image
cv2.imshow('image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

上面的代码首先使用 cv2.imread 函数加载一个图像,然后使用 cv2.cvtColor 函数将其转换为灰度图像。接下来,使用 cv2.threshold 函数对图像进行阈值处理,得到一个二值图像。该函数将所有像素值大于阈值的像素设置为白色(255),将所有像素值小于或等于阈值的像素设置为黑色(0)。在此示例中,阈值设为 127,这意味着所有像素值大于 127 的像素都将被设置为白色。

然后使用 cv2.findContours 函数查找图像中的轮廓。该函数需要一个二值图像作为输入,并返回一个轮廓列表和一个层次结构。轮廓列表包含所有找到的轮廓,每个轮廓是一个 Numpy 数组,包含轮廓的所有点的坐标。层次结构描述了轮廓之间的关系。在此示例中,使用 cv2.RETR_TREE 模式,这意味着将找到所有的轮廓,并且生成一个完整的轮廓层次结构。使用 cv2.CHAIN_APPROX_SIMPLE 方法对轮廓进行近似,这意味着仅存储水平、垂直和对角线段的端点,从而减少了存储轮廓点的数量。

最后,使用 cv2.drawContours 函数在原始图像上绘制所有的轮廓。该函数需要一个图像、一个轮廓列表、轮廓的索引(-1 表示绘制所有轮廓)、轮廓的颜色和线宽度作为参数。在此示例中,将轮廓绘制为绿色线条,线宽度为 3。最后使用 cv2.imshow 函数显示结果,并使用 cv2.waitKey 函数等待用户按下任意键,最后使用 cv2.destroyAllWindows 函数

猜你喜欢

转载自blog.csdn.net/weixin_63062756/article/details/130472181