本篇文章,我们将聊一聊利用opencv进行的一些基本操作,以便后续我们利用opencv进行更加复杂的处理。
1、图像的读取、显示与保存
opencv中利用cv2.imread 读取RGB图像,利用cv2.imshow() 进行图像的显示。
# 注意: cv2.imread读取RGB图像时, 返回的图像格式的通道为(b, g, r)
# 默认为cv2.IMREAD_COLOR
img = cv2.imread("disney.jpg")
# 彩图
img1 = cv2.imread('disney.jpg', cv2.IMREAD_COLOR)
# 读取灰度图
img2 = cv2.imread('disney.jpg', cv2.IMREAD_GRAYSCALE)
# 第一个参数为显示窗口名称,第二个参数为需要显示的图像
cv2.imshow('image', img)
# 等待时间,毫秒级,0表示任意键终止,没有的话显示的图像会一闪而逝
cv2.waitKey(0)
#销毁我们创建的所有窗口。如果要销毁任何特定窗口,请使用函数cv2.destroyWindow(),其中传递确切的窗口名称作为参数
cv2.destroyAllWindows()
最终显示的图像如下所示:
若我们需要保存图像,可以使用下面的函数:
# 第一个参数为图像保存的路径,第二个参数为需要保存的图像
cv2.imshow(save_path, img)
2、通道的拆分与合并
有些时候当我们需要对图像的通道进行单独的操作,这个时候就需要进行通道拆分,此时我们用到cv2.split() 函数。
b,g,r=cv2.split(img) # 拆分通道,顺序为b,g,r
b # 此时若显示则为灰度图
array([[16, 22, 16, ..., 11, 25, 15],
[19, 26, 18, ..., 19, 22, 19],
[ 5, 15, 18, ..., 16, 20, 19],
...,
[24, 30, 32, ..., 2, 6, 10],
[27, 27, 28, ..., 10, 10, 7],
[26, 29, 32, ..., 9, 4, 2]], dtype=uint8)
当我们需要把独立的通道合并成一张图像的时候,可以用cv2.merge() 函数。
img1 = cv2.merge((r,g,b)) #合并通道,这里我们按照PIL的读取方式将通道顺序变成r,g,b
若我们只想保留红波段的值,不必先拆分再赋值。你可以直接使用 Numpy 索引。
# 只保留 R通道
img_Rband = img1.copy()
img_Rband[:,:,1] = 0
img_Rband[:,:,2] = 0
这里我们看下img_Rband与原图像的区别:
plt.figure(figsize=(10,5))
plt.subplot(121), plt.title('image')
plt.imshow(img1), plt.axis('off')
plt.subplot(122), plt.title('image_r')
plt.imshow(img_Rband), plt.axis('off')
plt.savefig("disney01.jpg")
plt.show()
3、调整图像大小与裁剪图像
当我们需要改变图像大小时,可以使用cv2.resize() 函数。
# 第一个参数为需要resize的图像,第二个参数为改变后的图像大小(width,height)
img_resize = cv2.resize(img1,(800,600))
img.shape, img_resize.shape
# ((3023,4086,3),(600,800,3))
# 也可以不指定输出大小,而是利用fx,fy来使图像沿x轴或y轴缩放
img_resize1 = cv2.resize(img1,(0,0),fx = 3,fy=1)
plt.imshow(img_resize1), plt.axis('off')
有时我们需要对一幅图像的特定区域进行操作。此时也是可以使用 Numpy 索引来获得的。
img_crop = img_resize[200:400,200:400]
plt.imshow(img_crop), plt.axis('off')
4、图像边界填充
如果需要在图像周围创建一个边框,此时可以使用cv2.copyMakeBorder() 函数。
img = cv2.imread(r"E:\01_Qython\source\image_processing\tangyue.jpg")
img = cv2.resize(img,(800,600))
#这里为了展示方便,先对通道进行拆分重组成rgb顺序
b,g,r = cv2.split(img)
img = cv2.merge((r,g,b))
top_size,bottom_size,left_size,right_size =(200,200,200,200)
# 复制法,复制最边缘的像素
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size,right_size, borderType=cv2.BORDER_REPLICATE)
# 反射法,对感兴趣的图像中的像素在两边进行复制,例如 dcba|abcdefgh|hgfe
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size,right_size, borderType=cv2.BORDER_REFLECT)
# 反射法,以最边缘像素为轴,对称,edcb|abcdefgh|gfed
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size,right_size, borderType=cv2.BORDER_REFLECT_101)
# 外包装法,efgh|abcdefgh|abcd
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size,right_size, borderType=cv2.BORDER_WRAP)
# 常量法,常数值填充,这里我们指定为0,显示为黑色
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size,right_size, borderType=cv2.BORDER_CONSTANT,value = 0)
plt.figure(figsize=(10,5))
plt.subplot(231),plt.imshow(img),plt.title("ORIGINAL"), plt.axis('off')
plt.subplot(232),plt.imshow(replicate),plt.title("REPLICATE"), plt.axis('off')
plt.subplot(233),plt.imshow(reflect),plt.title("REFLECT"), plt.axis('off')
plt.subplot(234),plt.imshow(reflect101),plt.title("REFLECT_101"), plt.axis('off')
plt.subplot(235),plt.imshow(wrap),plt.title("WRAP"), plt.axis('off')
plt.subplot(236),plt.imshow(constant),plt.title("CONSTANT"), plt.axis('off')
plt.show()
总结
本篇文章,我们利用opencv进行的一些图像基本操作,学会了读取、保存图像,通道的拆分与合并,图像的大小改变与裁剪以及怎么实现图像的边缘填充。下一篇文章我们将利用opencv进行一些更为深入的学习。
本文由mdnice多平台发布