OpenCv
1.图像的读取
import cv2
img = cv2.imread('car.jpg')
print(type(img))
opencv中读取图像的函数是cv2.imread()
- filename:文件的路径
- flags:指定读写的读取方式
flags是可选参数:
- cv2.IMREAD_COLOR:默认参数,以彩色图像的方式加载图像,忽略任何透明度。(可用 1)
- cv2.IMREAD_GRAYSCALE:以灰度图像的方式加载图像。(可用 0)
- cv2.IMREAD_UNCHANGED以原始图像的方式加载图像。(可用-1)
注意:OpenCv以彩色图像读取的时候是BGR
2.图像的显示
import cv2
img = cv2.imread('../png/01_cat.jpg' , 1)
cv2.imshow('cat',img)
# 等待时间,毫秒级,0表示任意键终止,5000ms表示5s
cv2.waitKey(0)
# 销毁图像窗口
cv2.destroyAllWindows()
- winname:展示图像的窗口名字
- mat:所展示的图像
这里我们封装一个函数,方便展示图像
# 绘图显示(封装函数)
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
下文所用的的cv_show(),就是这边封装的函数。
3.图像的保存
img = cv2.imread('cat01.jpg' , 1)
cv2.imwrite('cat02.jpg',img)
- filename:保存的路径。
- img:保存的图像。
- params:用于指定保存图像的特定格式参数。它可以是 JPEG、PNG 等图像格式的特定参数。
4.视频处理
vc = cv2.VideoCapture(0)
if vc.isOpened():
open,img = vc.read()# 这里的 vc.read() 相当于读取图像的第一帧
# 若循环不断的执行 vc.read,则不断的读取第二帧、第三帧....
#open:是否被打开 img:图像
cv_show('img',img)
cv2.VideoCapture
函数可以捕获摄像头,或读取视频文件。
cv2.VideoCapture 函数入口参数:
- 用数字来控制不同的设备(摄像头),例如 0、1。
- 如果是视频文件,直接指定好路径即可。
5.ROI区域
5.1 位置提取
img = cv2.imread('cat.jpg')
cat = img[0:200,0:200] # 选择图片感兴趣的区域
cv_show('cat',cat)
切片显示图片中左上角的一个 200x200 大小的区域,
5.2 通道提取
img = cv2.imread('cat.jpg')
b,g,r = cv2.split(img)
cv_show('cat_b',b)
print('b.shape:',b.shape) # B通道,单通道,灰度图
cv_show('cat_g',g)
print('g.shape:',g.shape) # G通道,单通道,灰度图
cv_show('cat_r',r)
print('r.shape:',r.shape) # R通道,单通道,灰度图
img = cv2.merge((b,g,r))
print('img.shape:',img.shape) # 3 通道,彩色图
6.边界填充
img = cv2.imread('cat.jpg')
top_size,bottom_size,left_size,right_size = (50,50,50,50) # 填充多少区域
# 最后一个入口参数为填充方式
# 方式一:复制法
replicate = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REPLICATE)
# 方式二:反射法
reflect = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT)
# 方式三:反射法二(不要最边缘的像素)
reflect101 = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_REFLECT_101)
# 方式四:外包装法
wrap = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_WRAP)
# 方式五:常量法
constant = cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_CONSTANT,value=0)
src
:图像top
、bottom
、left
、right
:分别指定了上、下、左、右四个方向上的边框大小。- borderType:
- BORDER_REPLICATE:复制法,也就是复制最边缘像素。
- BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
- BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
- BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
- BORDER_CONSTANT:常量法,常数值填充。
7.图像的加法
7.1 直接相加
img_cat = cv2.imread('cat.jpg')
img_dog = cv2.imread('dog.jpg')
img_cat2 = img_cat + 10 # 将 img_cat 矩阵中每一个值都加 10
print(img_cat[:5,:,0])
print(img_cat2[:5,:,0])
print((img_cat+img_cat2)[:5,:,0]) # 0-255 若相加越界后 294 用 294%256 获得余数 38
7.2 add()
src1
:第一幅输入图像。src2
:第二幅输入图像。dst
:可选参数,用于指定输出图像。如果不提供此参数,函数会创建一个与输入图像相同大小和类型的输出图像。mask
:可选参数,用于指定掩码图像。只有掩码中对应位置的像素才会参与运算。dtype
:可选参数,指定输出图像的数据类型。
cv2.add()
函数将两幅输入图像的对应像素值相加,并将结果写入输出图像中。如果相加的结果超出了像素值的范围,会进行截断(即超出 255 的部分会被截断为 255)。
8.图像的融合
8.1 图像变化
不同数据大小的图像不能进行数值操作
src
:输入图像。dsize
:输出图像的尺寸,可以是一个元组(width, height)
或者一个整数。dst
:可选参数,用于指定输出图像。如果不提供此参数,函数会创建一个与指定尺寸相同的输出图像。fx
、fy
:可选参数,用于指定沿水平和垂直方向的缩放比例。如果指定了fx
和fy
,则忽略dsize
参数。interpolation
:可选参数,指定插值方法。可以是以下值之一:cv2.INTER_NEAREST
:最近邻插值。cv2.INTER_LINEAR
:双线性插值(默认值)。cv2.INTER_CUBIC
:三次样条插值。cv2.INTER_AREA
:区域插值。cv2.INTER_LANCZOS4
:Lanczos 插值。
import cv2
# 读取图像
img = cv2.imread('image.jpg')
# 指定输出图像的尺寸
resized_img = cv2.resize(img, (400, 300))
cv_show(resized_img)
8.2 图像融合
res = cv2.addWeighted(img_cat,0.4,img_dog,0.6,0) # img_cat 的权重为 0.4,img_dog 的权重为 0.6
print(img_dog.shape)
cv_show(res)
cv2.addWeighted()
是 OpenCV 中用于图像混合的函数。它可以将两幅图像按照权重进行线性组合,生成一幅新的图像。
src1
:第一幅输入图像。alpha
:第一幅图像的权重。src2
:第二幅输入图像。beta
:第二幅图像的权重。gamma
:图像的亮度增益。dst
:可选参数,用于指定输出图像。dtype
:可选参数,指定输出图像的数据类型。
d s t = s r c 1 ∗ a l p h a + s r c 2 ∗ b e t a + g a m m a dst = src1 * alpha + src2 * beta + gamma dst=src1∗alpha+src2∗beta+gamma
alpha
和 beta
分别指定了两幅图像的权重,gamma
指定了图像的亮度增益。如果 gamma
为零,则不进行亮度调整。
9.图像的缩放
9.1 倍数缩放
img = cv2.imread('cat.jpg')
res = cv2.resize(img,(0,0),fx=3,fy=1) # (0,0)表示不确定具体值,fx=3 相当于行像素 x 乘 3,fy=1 相当于 y 乘 1
cv_show('res',res)
9.2 等比例缩放
res = cv2.resize(img,(0,0),fx=1.5,fy=1.5) # 同比例放缩
cv_show('res',res)
10.图像的阈值
img = cv2.imread('cat.jpg',cv2.IMREAD_COLOR)
img_gray = cv2.imread('01_Picture/01_cat.jpg',cv2.IMREAD_GRAYSCALE)
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
print(ret)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV) # THRESH_BINARY_INV 相对 THRESH_BINARY 黑的变成白的,白的变成黑的
print(ret)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
print(ret)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
print(ret)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
print(ret)
titles = ['original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2,3,i+1), plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
src
:输入图像,必须是单通道图像(灰度图)。thresh
:设定的阈值,用于将像素值分为两类。maxval
:当像素值高于阈值时,设置的最大值。type
:阈值化类型,包括以下几种:cv2.THRESH_BINARY
:二值化,大于阈值的像素值设为maxval
,小于等于阈值的像素值设为 0。cv2.THRESH_BINARY_INV
:反二值化,大于阈值的像素值设为 0,小于等于阈值的像素值设为maxval
。cv2.THRESH_TRUNC
:截断,大于阈值的像素值设为阈值,小于等于阈值的像素值不变。cv2.THRESH_TOZERO
:设为零,大于阈值的像素值不变,小于等于阈值的像素值设为 0。cv2.THRESH_TOZERO_INV
:反设为零,大于阈值的像素值设为 0,小于等于阈值的像素值不变。
dst
:可选参数,用于指定输出图像。
11.图像的平滑处理
图像的平滑处理是一种常见的图像处理技术,用于减少图像中的噪声并模糊图像。常见的平滑处理方法包括均值滤波、方框滤波、高斯滤波、中值滤波等。
11.1 均值滤波
将图像中每个像素的值替换为其周围像素值的平均值。这种方法对去除轻微的噪声很有效,但可能会使图像变得模糊。
# 均值滤波
# 简单的平均卷积操作,方框中的值相加,取平均,替换掉中心204的值
blur = cv2.blur(img,(3,3)) # (3,3) 为核的大小,通常情况核都是奇数 3、5、7
11.2 方框滤波
使用一个归一化的方形卷积核对图像进行平滑处理。该滤波器的每个元素都具有相同的权重,即均值滤波器
# 方框滤波
# 基本和均值一样,可以选择归一化
# 在 Python 中 -1 表示自适应填充对应的值,这里的 -1 表示与颜色通道数自适应一样
box = cv2.boxFilter(img,-1,(3,3),normalize=True) # 方框滤波如果做归一化,得到的结果和均值滤波一模一样
11.3 高斯滤波
在均值滤波的基础上,不同的像素具有不同的权重,距离越近的像素权重越高。这种方法更有效地保留图像的边缘信息。
# 高斯函数,越接近均值时,它的概率越大。
# 离中心值越近的,它的权重越大,离中心值越远的,它的权重越小。
aussian = cv2.GaussianBlur(img,(5,5),1)
11.4 中值滤波
将每个像素的值替换为其邻域像素的中值。对于去除椒盐噪声(即图像中突然出现的白点或黑点)非常有效。
# 中值滤波
# 排序后拿中值替代中间元素值的大小
median = cv2.medianBlur(img,5)
11.5 效果
12. 腐蚀与膨胀
12.1 腐蚀操作
腐蚀操作会将图像中的前景对象(白色区域)进行收缩,即使前景对象变小或者消失。这种操作可以移除小的白色噪声,断开图像中的连接部分,以及消除窄的通道。
12.2 膨胀操作
膨胀操作与腐蚀相反,会将图像中的前景对象进行膨胀,使得前景对象变大或者连接。这种操作可以填充图像中的孔洞、连接被断开的对象,以及扩展对象的大小。
eroded_img = cv2.erode(src, kernel, iterations=1)
dilated_img = cv2.dilate(src, kernel, iterations=1)
src
:输入图像,通常为二值图像,其中前景为白色,背景为黑色。kernel
:形态学操作的内核,控制操作的形状和大小。iterations
:形态学操作的迭代次数,默认为1
。
腐蚀和膨胀操作通常是拿二值图像做腐蚀操作
# 读取图像
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 创建腐蚀和膨胀的内核
kernel = np.ones((5, 5), np.uint8)
# 腐蚀操作
eroded_img = cv2.erode(img, kernel, iterations=1)
# 膨胀操作
dilated_img = cv2.dilate(img, kernel, iterations=1)
13.开运算与闭运算
13.1 开运算与闭运算
开运算(Opening)和闭运算(Closing)是图像处理中常用的形态学操作,通常用于去除图像中的噪声、填充孔洞或连接图像中的断裂部分。
- 开运算(Opening):先对图像进行腐蚀操作,再进行膨胀操作。开运算能够消除小的白色噪声,同时保持图像中较大对象的形状和结构。它通常用于去除图像中的噪声和细小的对象,以及分离连接的对象。
- 闭运算(Closing):先对图像进行膨胀操作,再进行腐蚀操作。闭运算能够填充图像中的孔洞,连接断裂的对象,以及平滑图像中对象的边界。它通常用于填充图像中的小孔洞和连接断裂的对象。
在 OpenCV 中,可以使用 cv2.morphologyEx()
函数来应用开运算和闭运算。这个函数提供了一个 op
参数,用于指定所需的形态学操作。
src
:输入图像,通常为二值图像。op
:指定形态学操作的类型,可以是cv2.MORPH_OPEN
(开运算)或cv2.MORPH_CLOSE
(闭运算)。kernel
:形态学操作的内核,控制操作的形状和大小。
13.2 梯度运算
形态学梯度是膨胀图像减去腐蚀图像的结果,用于检测图像中的边缘。它可以通过以下方式进行计算:
g r a d i e n t = d i l a t e d i m g − e r o d e d i m g gradient=dilated_img−eroded_img gradient=dilatedimg−erodedimg
# 梯度 = 腐蚀-膨胀
pie = cv2.imread('pie.png')
kernel = np.ones((7,7),np.uint8)
dilate = cv2.dilate(pie,kernel,iterations=5)
erosion = cv2.erode(pie,kernel,iterations=5)
14.礼帽与黑帽
14.1 礼帽
礼帽操作是原始图像与图像的开运算之间的差值。开运算能够消除图像中的噪声,平滑图像的背景,因此礼帽操作可以用来突出图像中的小亮点和细微结构。礼帽操作通常用于检测图像中的亮度变化或者局部结构。
# 读取图像
img = cv2.imread('Dige.jpg', cv2.IMREAD_GRAYSCALE)
# 创建形态学操作的内核
kernel = np.ones((5, 5), np.uint8)
# 礼帽操作
tophat_img = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
14.2 黑帽
黑帽操作是图像的闭运算与原始图像之间的差值。闭运算能够填充图像中的孔洞,连接断裂的对象,因此黑帽操作可以用来突出图像中的暗部分或者凹陷结构。黑帽操作通常用于检测图像中的暗度变化或者局部结构。
# 黑帽操作
blackhat_img = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
-
op
:-
cv2.MORPH_OPEN
:开运算(Opening)操作。 -
cv2.MORPH_CLOSE
:闭运算(Closing)操作。 -
cv2.MORPH_GRADIENT
:形态学梯度(Morphological Gradient)操作。 -
cv2.MORPH_TOPHAT
:礼帽(Top Hat)操作。
-