opencv之图像基本操作
1、图像简介
图像主要是由一个个像素点组成。
计算机中的像素点的取值范围为0~255,数值大小表示该点的亮度。
RGB称为图像的颜色通道,其中R表示红色通道,G表示绿色通道,B表示蓝色通道。
灰度图只有一个通道,该通道主要用于表示亮度。
2、读取图像
OpenCV 提供了函数 cv2.imread() 来读取图像,该函数支持各种静态图像格式,比如 *.jpg、*.png、*.jp2、*.dib、*.bmp、*.sr、*.ras 等等。
语法格式为:
retval = cv2.imread( filename[, flags] )
retval :返回值,其值是读取到的图像。如果未读到图像,返回"None"。
filename :表示要读取的图像的完整文件名。
flags :读取标记。该标记用来控制读取文件的类型。

举例:
想要读取当前目录下文件名为 lena.bmp 的图像,并保持按照原有格式读入,则使用的语句为:
lena=cv2.imread( “lena.bmp”, -1)
实际写代码时,步骤如下:
第一步:首先将所需工具包导入;
import cv2 #在python中简称cv2,opencv读取的格式为BGR
import matplotlib.pyplot as plt #主要用于绘图展示
import numpy as np #基本数值计算工具包
%matplotlib inline #直接将图展示出来,不需要调用show()函数,仅适用于jupyter notebook
img=cv2.imread('G:/pic/ali_two.png') #读取照片,G:\pic\ali_two.png表示该图片所在目录
第二步:将读取的照片显示出来;
#图像的展示
cv2.imshow('image',img)
#等待时间按,0表示任意键终止
cv2.waitKey(0)
cv2.destroyAllWindows()
结果如下所示:

由于,每次展示图像都需要写以上三行代码,复用率较高,直接封装为函数便于重复使用,如下所示:
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
保存图像常用 cv2.imwrite() 函数,语法格式如下:
retval = cv2.imwrite( filename, img[ , params]) retval :返回值。如果保存成功,返回
TRUE ;否则,返回 FALSE 。 filename :要保存的目标文件的完整路径名,包含文件的扩展名。 img :被保存图像的名称。
params :保存类型参数,是可选的。
3、查看图像属性
彩色图和灰度图可以相互转换。在实际操作中,两种类型的图片经常转换。
彩色图像:cv2.IMREAD_COLOR;
- shape 属性:[h, w, c],h代表高度,w代表宽度,c代表BGR。
img.shape
该图片的属性如下图所示:

将彩色图转换为灰度图:在原读取基础上,添加 cv2.IMREAD_GARYSCALE。
img_gray=cv2.imread('G:/pic/ali_two.png',cv2.IMREAD_GRAYSCALE)
img_gray
#图像的展示
cv_show(img_gray)
结果如下:
灰度图像:cv2.IMREAD_GRAYSCALE;
注意:在读取过程中,可能会导致错误,如果将照片的路径写错,可能会出现如下情况:
error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-u4kjpz2z\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function ‘cv::cvtColor’
如果出现类似错误,请检查你的照片路径是否正确,切记在 Windows 中,要么使用 \\ 或者 / 、 // 都是可以的。自己存储照片的路径尽可能都是英文,照片名字尽量不要出现数字。如果出现上述两种情况,可能会报错。请按照自己的错误自行百度。
3、读取视频
视频是由多张图像组成。在读取视频时,将视频拆分为每一帧。
vc=cv2.VideoCapture('G:/pic/VID_sky.mp4')
#检查是否能正确打开
#open返回的布尔值,frame为当前帧的图像
if vc.isOpened():
open,frame=vc.read()
else:
open=False
#frame为截取的某一帧图像
while open:
ret, frame=vc.read()
#说明视频不为空
if frame is None:
break
if ret == True:
gray=cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('result',gray)
if cv2.waitKey(10) & 0xFF==27:
break
vc.release()
cv2.destroyAllWindows()
4、截取部分图像数据
在实际应用中,截取部分图像数据非常常见,也很常用。
img=cv2.imread('G:/pic/ali_two.png')
ali=img[150:500,100:800]
cv_show("image",ali)
对图像进行截取后,可以进行颜色通道的提取。
#颜色通道提取
b,g,r=cv2.split(img)
b
b.shape
#将分开的还原,合并一起
img=cv2.merge((b,g,r))
img.shape
#只保留R
cur_img=img.copy()
cur_img[:,:,0]=0
cur_img[:,:,1]=0
cv_show('R',cur_img)
#只保留B
cur_img=img.copy()
cur_img[:,:,1]=0
cur_img[:,:,2]=0
cv_show('B',cur_img)
#只保留G
cur_img=img.copy()
cur_img[:,:,0]=0
cur_img[:,:,2]=0
cv_show('G',cur_img)
效果展示如下:




5、边界填充
BORDER_REPLICATE :复制法,复制最边缘像素。
BORDER_REFLECT :反射法,对感兴趣的图像中的像素在两边进行复制。
BORDER_REFLECT_101 :反射法,以最边缘像素为轴,对称。
BORDER_WRAP :外包装法。
BORDER_CONSTANT :常量法,常数值填充。
#边界填充
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,cv2.BORDER_WRAP)
constant=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,cv2.BORDER_CONSTANT,value=0)
#将图片显示出来
import matplotlib.pyplot as plt
plt.subplot(231),plt.imshow(img,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
plt.show()
结果如下图所示:
