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 :读取标记。该标记用来控制读取文件的类型。

flags标记值

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()

结果如下所示:
图片1

由于,每次展示图像都需要写以上三行代码,复用率较高,直接封装为函数便于重复使用,如下所示:

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

该图片的属性如下图所示:
结果2

将彩色图转换为灰度图:在原读取基础上,添加 cv2.IMREAD_GARYSCALE。

img_gray=cv2.imread('G:/pic/ali_two.png',cv2.IMREAD_GRAYSCALE)
img_gray

#图像的展示
cv_show(img_gray)

结果如下:
结果3灰度图像: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)

效果展示如下:
结果4结果5结果6结果7

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()

结果如下图所示:
结果八