学习日志023---初始opencv
一、二值化
功能
二值化图:就是将图像中的像素改成只有两种值,其操作的图像必须是灰度图
1.1、阈值法(THRESH_BINARY)
通过设置一个阈值,将灰度图中的每一个像素值与该阈值进行比较,小于等于阈值的像素就被设置为0(黑),大于阈值的像素就被设置为maxval。
1.2、反阈值法(THRESH_BINARY_INV)
与阈值法相反。反阈值法是当灰度图的像素值大于阈值时,该像素值将会变成0(黑),当灰度图的像素值小于等于阈值时,该像素值将会变成maxval。
1.3、截断阈值法(THRESH_TRUNC):
指将灰度图中的所有像素与阈值进行比较,像素值大于阈值的部分将会被修改为阈值,小于等于阈值的部分不变。换句话说,经过截断阈值法处理过的二值化图中的最大像素值就是阈值。
1.4、低阈值零处理(THRESH_TOZERO)
就是像素值小于等于阈值的部分被置为0(也就是黑色),大于阈值的部分不变。
1.5、超阈值零处理(THRESH_TOZERO_INV)
就是将灰度图中的每个像素与阈值进行比较,像素值大于阈值的部分置为0(也就是黑色),像素值小于等于阈值的部分不变。
1.6、OTSU阈值法
在介绍OTSU阈值法之前,我们首先要了解一下双峰图片的概念。
双峰图片就是指灰度图的直方图上有两个峰值,直方图就是对灰度图中每个像素值的点的个数的统计图
OTSU算法是通过一个值将这张图分前景色和背景色(也就是灰度图中小于这个值的是一类,大于这个值的是一类),通过统计学方法(最大类间方差)来验证该值的合理性,当根据该值进行分割时,使用最大类间方差计算得到的值最大时,该值就是二值化算法中所需要的阈值。通常该值是从灰度图中的最小值加1开始进行迭代计算,直到灰度图中的最大像素值减1,然后把得到的最大类间方差值进行比较,来得到二值化的阈值
参数
@_typing.overload
def threshold(src: cv2.typing.MatLike,
thresh: float,
maxval: float,
type: int, dst: cv2.typing.MatLike | None = ...)
-> tuple[float, cv2.typing.MatLike]: ...
- src: 输入图像,这应该是一个灰度图像(即单通道图像)。如果你有一个彩色图像,你需要先使用 cv2.cvtColor() 将其转换为灰度图。
- thresh: 阈值,用于将像素划分为两部分。这个值是一个浮点数或整数,取决于图像的数据类型。
- maxVal: 最大值,用于设置高于阈值的像素值。这个值通常是一个整数,表示你想要将高于阈值的像素设置为的具体数值。
- type: 阈值类型,这是一个标志,用于指定如何应用阈值。OpenCV 提供了几种不同的阈值类型,如 cv2.THRESH_BINARY、cv2.THRESH_BINARY_INV、cv2.THRESH_TRUNC、cv2.THRESH_TOZERO 和 cv2.THRESH_TOZERO_INV。
- dst: 输出图像,与输入图像具有相同的大小和类型。这是一个可选参数,如果不提供,函数会创建一个新的图像来存储二值化结果。
函数返回值:
- ret: 实际使用的阈值。在某些情况下(如使用 cv2.THRESH_OTSU 或 cv2.THRESH_TRIANGLE 标志时),这个值可能会与输入的 thresh 不同。
- dst: 二值化后的图像。
应用
import cv2
# 读取图像
img = cv2.imread('./1.png')
# 将图像灰度化
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 设置阈值为200 ,最高值为255
thresh = 200
maxval = 255
ret,img_binary = cv2.threshold(img_gray,thresh=thresh,maxval=maxval,type=cv2.THRESH_OTSU)# 设置用otsu
# 展示成果
# 原图
cv2.imshow("img",img)
# 灰度图
cv2.imshow("img_gray",img_gray)
# 二值图
cv2.imshow("img_binary",img_binary)
# 阻塞
cv2.waitKey(0)
二、自适应二值化
功能
与二值化算法相比,自适应二值化更加适合用在明暗分布不均的图片,因为图片的明暗不均,导致图片上的每一小部分都要使用不同的阈值进行二值化处理,这时候传统的二值化算法就无法满足我们的需求了,于是就出现了自适应二值化。
自适应二值化方法会对图像中的所有像素点计算其各自的阈值,这样能够更好的保留图片里的一些信息。
@_typing.overload
def adaptiveThreshold(src: cv2.typing.MatLike, # 图像数组
maxValue: float, # 最大值
adaptiveMethod: int, # 小区域内阈值的运算方法
thresholdType: int, # 二值化类型 有阈值法和反阈值法
blockSize: int, # 核的大小
C: float, # 自设阈值误差
dst: cv2.typing.MatLike | None = ...)
-> cv2.typing.MatLike: ... #返回一个二值化数组
参数
其中各个参数的含义如下:
maxval:最大阈值,一般为255
adaptiveMethod:小区域阈值的计算方式:
ADAPTIVE_THRESH_MEAN_C:小区域内取均值
ADAPTIVE_THRESH_GAUSSIAN_C:小区域内加权求和,权重是个高斯核
thresholdType:二值化方法,只能使用THRESH_BINARY、THRESH_BINARY_INV,也就是阈值法和反阈值法
blockSize:选取的小区域的面积,如7就是7*7的小块。
c:最终阈值等于小区域计算出的阈值再减去此值
应用
import cv2
img = cv2.imread('./1.png')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img_binary = cv2.adaptiveThreshold(img_gray,255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
7,
5)
cv2.imshow("img",img)
cv2.imshow('img_gray',img_gray)
cv2.imshow('img_binary',img_binary)
cv2.waitKey(0)
三、腐蚀
功能
- 去掉毛刺和孤立像素:通过腐蚀操作,可以去除图像中的细小毛刺和孤立的像素点,从而提取出图像的骨干信息。
- 边缘检测:腐蚀与膨胀操作结合使用,可以更有效地提取二值图像中的边缘信息。先膨胀再腐蚀可以使边缘更加明显。
- 去除噪声:在二值图像中,可能存在一些噪声点或孤立的像素点。通过一定次数的腐蚀操作,可以消除这些噪声点,使图像更加清晰。
- 提取文本区域:在图像处理中,通过腐蚀和膨胀操作可以方便地提取出文本区域,这对于文本识别等应用非常有用。
参数
def erode(src: cv2.typing.MatLike,
kernel: cv2.typing.MatLike,
dst: cv2.typing.MatLike | None = ...,
anchor: cv2.typing.Point = ...,
iterations: int = ...,
borderType: int = ...,
borderValue: cv2.typing.Scalar = ...)
-> cv2.typing.MatLike: ...
参数:
- src: 输入图像,这可以是一个二值图像、灰度图像或彩色图像。对于二值图像,通常使用 0 和 255 表示像素值;对于灰度图像和彩色图像,像素值范围可能更广。
- kernel: 结构元素,核。
- dst: 输出图像,是一个可选参数,如果不提供,函数会创建一个新的图像来存储腐蚀结果。
- anchor: 锚点,这是一个可选参数,通常不需要修改。
- iterations: 迭代次数,表示腐蚀操作应该应用的次数。默认值为 1,但你可以通过增加这个值来应用多次腐蚀,从而得到更强的效果。
- borderType: 边界类型,用于指定图像边界的像素外推方法。这通常是一个可选参数,默认值为 cv2.BORDER_DEFAULT,表示使用默认的边界填充方法。
- borderValue: 边界值,当 borderType 为 cv2.BORDER_CONSTANT 时使用,表示边界像素应该被设置的值。这也是一个可选参数。
函数返回值:
- dst: 腐蚀后的图像,这是一个包含腐蚀操作结果的 NumPy 数组。
def getStructuringElement(shape: int, # 创建核的形状
ksize: cv2.typing.Size, # 创建核的大小
anchor: cv2.typing.Point = ...) \
-> cv2.typing.MatLike: ... # 返回一个核
- shape: 结构元素的形状,这是一个整数标识符,表示你想要生成的结构元素的形状。OpenCV 提供了几种预定义的形状,如矩形(cv2.MORPH_RECT)、椭圆形(cv2.MORPH_ELLIPSE)和十字形(cv2.MORPH_CROSS)。
- ksize: 结构元素的尺寸,这是一个元组,表示结构元素的宽度和高度(通常是相同的,即正方形)。例如,(5, 5) 表示一个 5x5 的结构元素。
- anchor: 锚点,这是一个可选参数,表示结构元素的中心点(或称为锚点)相对于结构元素左上角的偏移量。默认情况下,锚点位于结构元素的中心。
函数返回值:
- 返回一个结构元素,这是一个 NumPy 数组,其数据类型通常为 uint8,并且数组中的元素值通常为 0 或 255(对于二值结构元素)。结构元素的形状和尺寸由 shape 和 ksize 参数决定。
应用
import cv2
img = cv2.imread('./1.png')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img_binary = cv2.adaptiveThreshold(img_gray,
255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
7,
5)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
img_binary_erode = cv2.erode(img_binary,kernel=kernel)
cv2.imshow('img_binary',img_binary)
cv2.imshow('img_binary_erode',img_binary_erode)
cv2.waitKey(0)
四、膨胀
功能
膨胀操作主要用于增大图像中的物体,使物体的边缘向外扩展,同时也可以填补物体内部的细小空洞。
参数
def dilate(src: cv2.typing.MatLike,
kernel: cv2.typing.MatLike,
dst: cv2.typing.MatLike | None = ...,
anchor: cv2.typing.Point = ...,
iterations: int = ...,
borderType: int = ...,
borderValue: cv2.typing.Scalar = ...) \
-> cv2.typing.MatLike: ...
- src: 输入图像,这可以是一个二值图像、灰度图像或彩色图像。
- kernel: 结构元素,。
- dst: 输出图像,是一个可选参数,如果不提供,函数会创建一个新的图像来存储膨胀结果。
- anchor: 锚点。
- iterations: 迭代次数,表示膨胀操作应该应用的次数。默认值为 1,但可以通过增加这个值来应用多次膨胀,从而得到更强的效果。
- borderType: 边界类型,用于指定图像边界的像素外推方法。默认值为 cv2.BORDER_DEFAULT。
- borderValue: 边界值,当 borderType 为 cv2.BORDER_CONSTANT 时使用,表示边界像素应该被设置的值。
函数返回值:
- dst: 膨胀后的图像,这是一个包含膨胀操作结果的 NumPy 数组
应用
- 增大物体:通过膨胀操作,可以增大图像中的物体,使其更加显眼。
- 填补空洞:对于图像中物体内部的细小空洞或裂缝,膨胀操作可以将其填补,使物体看起来更加完整。
- 连接物体:如果图像中的物体之间距离较近,膨胀操作可以将它们连接起来,形成一个更大的物体。
- 形态学重建:在图像分割、物体检测等任务中,膨胀操作可以作为形态学重建的一部分,帮助恢复或增强图像中的结构信息。
import cv2
img = cv2.imread('./1.png')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img_binary = cv2.adaptiveThreshold(img_gray,
255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
7,
5
)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
img_binary_erode = cv2.erode(img_binary,kernel=kernel)
img_binary_erode_dilate = cv2.dilate(img_binary_erode,kernel=kernel)
cv2.imshow('img_binary_erode',img_binary_erode)
cv2.imshow('img_binary_erode_dilate',img_binary_erode_dilate)
cv2.waitKey(0)
五、仿射变换
功能
仿射变换是图像处理中的一种重要几何变换方法,它具有以下功能:
-
改变图像的形状和位置:通过线性变换和平移,仿射变换可以灵活地调整图像的形状和位置,满足不同的图像处理需求。
-
保持图像的平直性和平行性:仿射变换后的图像仍然能够保持直线的平直性和平行线的平行性,这是仿射变换的一个重要特性
-
实现多种图像变换操作:仿射变换可以包含平移、旋转、缩放和剪切等多种操作,通过调整变换矩阵的参数,可以实现这些操作的组合,从而对图像进行复杂的几何变换
-
应用于图像校正和对象识别:仿射变换在图像校正、对象识别以及增强现实等领域有广泛应用。例如,在图像校正中,可以利用仿射变换来校正图像的倾斜或变形;在对象识别中,可以通过仿射变换对图像进行预处理,提高识别的准确率
-
易于实现和计算:在OpenCV等图像处理库中,仿射变换的实现非常简单。只需获取仿射变换的矩阵,并通过相应的函数应用变换即可。同时,变换矩阵的计算也相对容易,可以通过选择源图像和目标图像上的对应点来求解。
参数
def getRotationMatrix2D(center: cv2.typing.Point2f,
angle: float,
scale: float) \
-> cv2.typing.MatLike: ...
center: 旋转的中心点,通常是一个二元元组 (x, y),表示旋转中心的坐标。
angle: 旋转的角度,以度为单位。正值表示逆时针旋转,负值表示顺时针旋转。
scale: 缩放因子。默认情况下,这个值是 1.0,表示不缩放。如果你想要同时旋转和缩放图像,可以通过调整这个参数来实现。
def warpAffine(src: cv2.typing.MatLike,
M: cv2.typing.MatLike,
dsize: cv2.typing.Size,
dst: cv2.typing.MatLike | None = ...,
flags: int = ...,
borderMode: int = ...,
borderValue: cv2.typing.Scalar = ...) \
-> cv2.typing.MatLike: ...
src: 输入图像。
M: 变换矩阵,一个 2x3 的数组。这个矩阵是通过其他函数(如 cv2.getRotationMatrix2D())计算得到的,用于描述仿射变换。
dsize: 输出图像的大小,以 (width, height) 的形式表示。这个参数决定了变换后图像的尺寸。
dst: 输出图像,与输入图像有相同的大小和类型。这是一个可选参数,如果提供,则变换的结果会存储在这个图像中;如果未提供,则会创建一个新的图像来存储结果。
flags: 插值方法。常用的插值方法包括 cv2.INTER_LINEAR(线性插值)、cv2.INTER_NEAREST(最近邻插值)、cv2.INTER_CUBIC(三次样条插值)等。这是一个可选参数,如果未提供,则默认使用线性插值。
borderMode: 边缘填充方法。常用的方法包括 cv2.BORDER_CONSTANT(常量填充)、cv2.BORDER_REFLECT(反射)、cv2.BORDER_REFLECT_101(反射101)等。这是一个可选参数,如果未提供,则默认使用常量填充。
borderValue: 边界颜色,当 borderMode 为 cv2.BORDER_CONSTANT 时使用。这个参数是一个表示颜色的元组或数组,如 (255, 255, 255) 表示白色。这是一个可选参数,如果未提供,则默认使用黑色 (0, 0, 0)。
应用
import cv2
img = cv2.imread('./1.png')
M = cv2.getRotationMatrix2D((img.shape[1]/2,img.shape[0]/2),45,0.8)
img_new = cv2.warpAffine(img,M,dsize=None,flags=cv2.INTER_LINEAR,borderMode=cv2.BORDER_REFLECT_101)
cv2.imshow("img",img)
cv2.imshow('img_new',img_new)
cv2.waitKey(0)
六、 透视变换
功能
透视变换(Perspective Transformation)是图像处理中的一种几何变换,它模拟了人眼从某一特定角度观察物体时所产生的透视效果。
-
模拟透视效果:透视变换能够模拟现实世界中物体由于距离和观察角度不同而产生的透视效果,使二维图像呈现出三维的立体感。
-
改变图像的视角:通过透视变换,可以改变图像的视角,仿佛是从不同的位置或角度观察同一个场景。
-
校正透视畸变:在拍摄照片或视频时,由于镜头或拍摄角度的原因,可能会产生透视畸变。透视变换可以用于校正这种畸变,使图像更加真实和准确。
-
图像拼接和合成:在图像拼接或合成时,如果不同图像之间的透视关系不一致,可以使用透视变换将它们调整到相同的透视角度,从而实现无缝拼接或合成。
-
增强现实应用:在增强现实(AR)应用中,透视变换用于将虚拟物体与现实世界中的场景相结合,使虚拟物体看起来像是真实存在于场景中一样。
参数
def getPerspectiveTransform(src: cv2.typing.MatLike,
dst: cv2.typing.MatLike,
solveMethod: int = ...) \
-> cv2.typing.MatLike: ...
src: 源图像中的四个点,通常是一个形状为 (4, 2) 的 numpy 数组或类似的数据结构,表示四个点的坐标。这四个点应该按照某种顺序排列(例如,顺时针或逆时针),因为变换矩阵的计算依赖于这个顺序。
dst: 目标图像中的四个点,与 src 参数类似,也是一个形状为 (4, 2) 的 numpy 数组或类似的数据结构,表示变换后四个点应该位于的位置。
函数返回一个 3x3 的变换矩阵,可以使用 cv2.warpPerspective() 函数将这个矩阵应用于图像,从而执行透视变换。
def warpPerspective(src: cv2.typing.MatLike,
M: cv2.typing.MatLike,
dsize: cv2.typing.Size,
dst: cv2.typing.MatLike | None = ...,
flags: int = ...,
borderMode: int = ...,
borderValue: cv2.typing.Scalar = ...) \
-> cv2.typing.MatLike: ...
src: 输入图像,即你想要进行透视变换的源图像。
M: 透视变换矩阵,通常是一个 3x3 的矩阵,可以通过 cv2.getPerspectiveTransform() 函数计算得到。这个矩阵定义了源图像中的点如何映射到目标图像中的点。
dsize: 输出图像的尺寸,以 (width, height) 的形式表示。这是变换后图像的尺寸。
dst: 输出图像,这是一个可选参数。
flags: 插值方法。
borderMode: 边界填充方法。
borderValue: 边界颜色【可选】。
应用
import cv2
import numpy as np
img = cv2.imread('./card.png')
points1 = np.array([[200,120],[700,170],[140,400],[650,460]],dtype=np.float32)
points2 = np.array([[0,0],[img.shape[1],0],[0,img.shape[0]],[img.shape[1],img.shape[0]]],dtype=np.float32)
M = cv2.getPerspectiveTransform(points1,points2)
img_warp= cv2.warpPerspective(img,M,(img.shape[1],img.shape[0]))
cv2.imshow("img",img)
cv2.imshow('img_warp',img_warp)
cv2.waitKey(0)
小练习:
1.识别某一颜色,并进行替换·。
import cv2
import numpy as np
img = cv2.imread("./1.png")
img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
hsv_min = np.array([35,43,46])
hsv_max = np.array([77,255,255])
img_mask = cv2.inRange(img,hsv_min,hsv_max)
for i in range(img_mask.shape[0]):
for j in range(img_mask.shape[1]):
if img_mask[i,j] == 255:
img[i,j,:] = (203,192,255)
cv2.imshow("image",img)
cv2.imshow("image_mask_color",img_mask)
cv2.waitKey(0)
2.切割图片
import cv2
import numpy as np
img = cv2.imread('./card.png')
w,h = img.shape[1],img.shape[0]
x_min = 350
x_max = 490
y_min = 200
y_max = 370
if x_min<0 or x_max>w or y_min<0 or y_max>h:
print("切割的区域不合法")
else:
# 圈出要切割的内容
cv2.rectangle(img,(x_min-2,y_min-2),(x_max+2,y_max+2),(0,0,255),2)
# 保存要切割的内容
img_roi = img[y_min:y_max,x_min:x_max]
cv2.imshow('image',img)
cv2.imshow('image_roi',img_roi)
cv2.waitKey(0)
原文地址:https://blog.csdn.net/Z211613347/article/details/144407103
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!