1.opencv—图像处理基础

读,写,显示图像

\qquad OpenCV中的imread(),imwrite()和imshow()函数分别用于读,写和显示图像。其中imread()函数用于将文件中的图像读入内存,它支持各种静态图像文件格式,如BMP,PNG,JPEG,TIFF等。
\qquad imread()函数返回一个 numpy.ndarray 对象(即 NumPy 数组),数组元素为图像的像素。OpenCV 使用 NumPy 数组来保存图像,数组的 shape(数组形状)、dtype(数据类型)、size(数组元素个数)等属性表示图像的相关属性。下面的代码使用的图像为彩色 JPG 图像,img.shape 的输出结果为(512, 512,3),说明表示彩色图像的数组是一个三维数组,3 个值依次表示图像的高度、宽度和通道数;图像的分辨率为 512×512。代码中 img.dtype的输出结果为 uint8,说明每个数组元素用一个字节(8 位)保存,每个数组元素为一个像素B,G和R通道的颜色。颜色取值范围为[0, 255]。

1.读取图像

import cv2


img = cv2.imread('lena.jpg', cv2.IMREAD_REDUCED_GRAYSCALE_4)  	# 读取图像
print(type(img))            	# 输出数据类型
print(img)                  	# 输出图像数组
print(img.shape)			    # 输出数组形状
print(img.dtype)			    # 输出数组元素的数据类型
print(img.size)				    # 输出数组元素的个数

在这里插入图片描述

2.写入图像

import cv2
import numpy

img = numpy.zeros((300, 300), dtype=numpy.uint8)  # 创建300*300的黑色正方形图像
cv2.imwrite('text_2.jpg', img)  # 保存图像

在这里插入图片描述

3.显示图像

\qquad inshow()函数的第一个参数为窗口名称,第二个参数为图像数组。其中,在使用时,这两个参数缺一不可,如果缺了一个会报错,如果窗口名称输入的是中文,会显示乱码,因为imshow函数的窗口标题是gbk编码,而Python3默认UTF-8编码。因而窗口标题包含中文时,会显示乱码。解决这个问题,最直接就是从标题的编码入手,在参数后面加这行代码.encode(“gbk”).decode(errors=“ignore”)强制转换编码方式,如:

cv2.imshow('lena'.encode("gbk").decode(errors="ignore"), img)

但转换有风险,不一定百分之百正确,也不一定可以显示出来,最好还是使用英文。
\qquad 在显示图像时,程序创建的图像窗口会在显示后立即关闭,所以为了图像显示更久一点,可使用waitKey()函数等待用户输入来控制窗口的关闭,其中该函数的基本格式如下:

rv = cv2.waitkey([delay])

其中,rv 保存函数返回值,如果没有键被按下,返回-1;如果有键被按下,返回键的 ASCII码。参数 delay 表示等待按键的时间(单位为毫秒),负数或 0 表示无限等待,默认值为 0;设置了delay参数时,等待时间结束时结束等待,函数返回-1。

import cv2


img = cv2.imread('lena.jpg')  	# 读取图像,缩小为原来的1/2
cv2.imshow('lena', img)         # 显示图像
cv2.waitKey(0)

在这里插入图片描述

读,写,播放视频

\qquad OpenCV 的 VideoCapture 类和 VideoWriter 类提供了视频处理功能,支持各种格式的视频文件。
视频处理的基本操作步骤如下。
(1)将视频文件或者摄像头作为数据源来创建 VideoCapture 对象。
(2)调用 VideoCapture 对象的 read()方法获取视频中的帧,每一帧都是一幅图像。
(3)调用 VideoWriter 对象的 write()方法将帧写入视频文件,或者调用 cv2.imshow()函数在窗口中显示帧(即播放视频)。

播放视频

在播放视频时,一般会使用cv2.waitKey()函数来设置延迟时间,如果不设置延迟时间,视频的播放速度会非常快,一般设置延迟时间为25毫秒。

扫描二维码关注公众号,回复: 13150073 查看本文章
import cv2


vc = cv2.VideoCapture('test2-5.mp4')  	  # 创建VideoCapture对象
fps = vc.get(cv2.CAP_PROP_FPS)            # 读取视频帧率
size = (vc.get(cv2.CAP_PROP_FRAME_WIDTH),
      vc.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 读取视频大小
print('帧率:', fps)
print('大小:', size)
success, frame = vc.read()                # 读第1帧
while success:                            # 循环读视频帧,直到视频结束
    cv2.imshow('myvideo', frame)          # 在窗口中显示帧图像
    success, frame = vc.read()            # 读下一帧
    key = cv2.waitKey(25)
    if key == 27:                         # 按Esc键退出
        break
vc.release()                              # 关闭视频

将视频写入文件

将视频写入文件与播放视频类似,需要逐帧将视频写入文件。在创建 VideoWhiter 对象时,可指定保存视频的文件名、视频解码器格式、帧速率和大小。cv2.VideoWhiter_ fourco()函数用 4 个字符来指定解码器格式,通过解码器格式生成相应格式的视
频文件。常用的解码器格式如下:

函数 解码器格式
cv2.VideoWrter_ fourco(‘P’,‘I’,‘M’,‘1’) XVID的 MPEG-1 编码格式,视频文件扩展名为.avi
cv2.VideoW/riter_fourco(‘M’,‘P’,‘4’,‘2’) Microsoit的MPEG-4 编码格式,视频文件扩展名为,avi
c2.VideoWriter_fourco(‘X’,‘V’,‘I’,‘D’) XVID 的 MPEG-4 编码格式,视频文件扩展名为,avi
c2.VideoWriter_fourco(‘F’,‘L’,‘V’,‘1’) XVID 的 MPEG-4 编码格式,视频文件扩展名为,flv
import cv2


vc = cv2.VideoCapture('test2-5.mp4')  			# 创建VideoCapture对象
fps = vc.get(cv2.CAP_PROP_FPS)            		# 读取视频帧率
size = (int(vc.get(cv2.CAP_PROP_FRAME_WIDTH)),
        int(vc.get(cv2.CAP_PROP_FRAME_HEIGHT))) 	# 读取视频大小
vw = cv2.VideoWriter('test2-6out.avi',			# 设置保存视频的文件名
                    cv2.VideoWriter_fourcc('X', 'V', 'I', 'D'),  # 设置视频解码器格式
                    fps,size)							 # 设置帧速率和大小
success, frame = vc.read()                 		    # 读第1帧
while success:                          			# 循环读视频帧,直到视频结束    
    vw.write(frame)                     			# 将帧写入文件
    success, frame = vc.read()             		    # 读下一帧
vc.release()                            			# 关闭视频

捕获摄像头视频并将视频写入文件

要捕获摄像头视频,需要将摄像头的ID作为参数来创建VideoCapture对象。通常0表示默认摄像头。

import cv2


vc = cv2.VideoCapture(0)  			# 创建VideoCapture对象,视频源为默认摄像头
fps = 30            		                # 预设视频帧率
size = (int(vc.get(cv2.CAP_PROP_FRAME_WIDTH)),
        int(vc.get(cv2.CAP_PROP_FRAME_HEIGHT))) 	# 读取视频大小
vw = cv2.VideoWriter('test2-7out.avi',			    # 设置保存视频的文件名
                     cv2.VideoWriter_fourcc('X', 'V', 'I', 'D'),  # 设置视频解码器格式
                     fps, size)				    # 设置帧速率和大小
success, frame = vc.read()                 	# 读第1帧
while success:                          	# 循环读视频帧,直到视频结束    
    vw.write(frame)                     	# 将帧写入文件
    cv2.imshow('MyCamera', frame)           # 显示帧
    key = cv2.waitKey(25)
    if key == 27:                          # 按Esc键结束
        break
    success, frame = vc.read()             # 读下一帧
vc.release()                               # 关闭视频

操作灰度,色彩图像

操作灰度图像

通常,计算机将灰度处理为256级(0~255),0表示黑色,255表示白色,用一个字节来存储一个像素的值。OpenCV使用单通道的二维数组来表示灰度图像。
代码中的“img[:,:]=n”语句将图像的全部像素值修改为 n,n 的值在程序运行过程中不断增大。从运行结果可看到输出的像素值不会大于 255。当 n 大于 255 时,因为数组元素的数据类型为numpy.uint8,所以 OpenCV 会自动按 256 取模。

import cv2
import numpy


img = numpy.zeros((240, 320), dtype=numpy.uint8)  	 # 创建图像
n = 0
while True:
    cv2.imshow('GrayImg', img)
    n += 20
    img[:, :] = n                               # 更改图像灰度
    print(img[1, 1])                            # 输出一个像素值
    key = cv2.waitKey(1000)                     # 延迟1秒
    if key == 27:
        break                                   # 按【Esc】键结束


在这里插入图片描述

操作彩色图像

不同色彩空间中,颜色的表示方法有所不同,但不同色彩空间之间可根据公式进行转换。下面我们简单介绍 RGB 色彩空间中图像的表示方法。RGB 中的R 指红色(Red),G指绿色(Green),B 指蓝色(Blue)。在表示图像时,有 R、G 和 B 3 个通道,分别对应红色、绿色和蓝色。每个通道中像素的取值范围为[0,255]),用 3 个通道的像素组合表示彩色图像。RGB色彩空间颜色通道依次为 B、G、R,但 OpenCV 默认的图像格式为 BGR,即颜色通道依次为B,G,R。

import cv2
import numpy


img = numpy.zeros((240, 320, 3), dtype=numpy.uint8)  # 创建图像,图像的上、中、下三个部分依次为蓝色、绿色和红色.
r0 = 0
r1 = 1
r2 = 2
while True:
    img[:80, :, r0] = 255                       # 通道r0上三分之一颜色值设为255
    img[80:160, :, r1] = 255                    # 通道r1中部三分之一颜色值设为255
    img[160:, :, r2] = 255                      # 通道r2下三分之一颜色值设为255
    cv2.imshow('ColorImg', img)
    key = cv2.waitKey(1000)                     # 延迟1秒
    img[:, :, :] = 0                            # 像素全部置0
    t = r0                                      # 轮换通道序号
    r0 = r1
    r1 = r2
    r2 = t
    if key == 27:
        break                                   # 按【Esc】键结束       

在这里插入图片描述

图像通道操作

通过数组索引拆分通道

OpenCV中BGR格式的图像是一个三维数组,可用数组的索引操作来拆分3个色彩通道。

import cv2

img = cv2.imread('lena.jpg', cv2.IMREAD_REDUCED_COLOR_2)  	# 读取图像,缩小为原来的1/2
cv2.imshow('lena', img)             # 显示原图像
b = img[:, :, 0]                    # 获得B通道图像
g = img[:, :, 1]                    # 获得G通道图像
r = img[:, :, 2]                    # 获得R通道图像
cv2.imshow('lena_B', b)             # 显示B通道图像
cv2.imshow('lena_G', g)             # 显示G通道图像
cv2.imshow('lena_R', r)             # 显示R通道图像
cv2.waitKey(0)

在这里插入图片描述

使用cv.split()函数来拆分通道

import cv2


img = cv2.imread('lena.jpg', cv2.IMREAD_REDUCED_COLOR_2)  	# 读取图像,缩小为原来的1/2
cv2.imshow('lena', img)          # 显示原图像
b, g, r = cv2.split(img)         # 按通道拆分图像
cv2.imshow('lena_B', b)          # 显示B通道图像
cv2.imshow('lena_G', g)          # 显示G通道图像
cv2.imshow('lena_R', r)          # 显示R通道图像
cv2.waitKey(0)

合并图像通道

import cv2


img = cv2.imread('lena.jpg', cv2.IMREAD_REDUCED_COLOR_2)  # 读图像,缩小为原来的1/2
cv2.imshow('lena', img)          	    # 显示原图像
b, g, r = cv2.split(img)            	# 按通道拆分图像
rgb = cv2.merge([r, g, b])          	# 按新顺序合并
gbr = cv2.merge([g, b, r])          	# 按新顺序合并
cv2.imshow('lena_RGB', rgb)        	    # 显示合并图像
cv2.imshow('lena_GBR', gbr)        	    # 显示合并图像
cv2.waitKey(0)

在这里插入图片描述

图像运算

OpenCV使用的是NumPy数组来表示图像,所以我们可以很方便的执行基于数组的图像运算。

加法运算

加法运算符“+”和 cv2.add()函数可用于执行图像加法运算。
用“+”运算符执行两个图像数组加法时,如果两个像素相加大于 256,则会将其按 256 取模。CV2.add()函数执行两个图像数组加法时,如果两个像素相加大于 256,则取 255。

import cv2


img1 = cv2.imread('lena.jpg', cv2.IMREAD_REDUCED_COLOR_2)  	     # 读取图像
img2 = cv2.imread('opencvlog.jpg', cv2.IMREAD_REDUCED_COLOR_2)	 # 读取图像
img3 = img1+img2
img4 = cv2.add(img1, img2)
cv2.imshow('lena', img1)          		# 显示原图像
cv2.imshow('log', img2)          		# 显示原图像
cv2.imshow('lena+log', img3)         	# 显示“+”图像
cv2.imshow('lenaaddlog', img4)     		# 显示add()图像
cv2.waitKey(0)

在这里插入图片描述

加权加法运算

cv2.addWeighted()函数可执行图像的加权加法运算,其基本格式如下。

dst = cv2.addweighted(src1, alpha, srcz, beta, gamma)

其中,变量 dst 保存结果,src1 和 src2 为执行加权加法运算的两个图像数组,alpha和 beta 为权重,gamma为附加值。OpenCV 按下面的公式执行图像数组的加权加法运算。

dst = src1*alpha + src2*beta + gamma 
import cv2


img1 = cv2.imread('lena.jpg', cv2.IMREAD_REDUCED_COLOR_2)  	     # 读取图像
img2 = cv2.imread('opencvlog.jpg', cv2.IMREAD_REDUCED_COLOR_2)	 # 读取图像
img3 = cv2.addWeighted(img1, 0.5, img2, 0.5, 0)
cv2.imshow('lena', img1)          		# 显示原图像
cv2.imshow('log', img2)          		# 显示原图像
cv2.imshow('lena+log', img3)         	# 显示addWeighted()图像
cv2.waitKey(0)

在这里插入图片描述

位运算

在学习OpenCV中对图像的位运算前,我们先回顾下位运算
程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。比如,&运算本来是一个逻辑运算符,但整数与整数之间也可以进行&运算。举个例子,6的二进制是110,11的二进制是1011,那么6 & 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。
在这里插入图片描述

下面是位运算的规则:
在这里插入图片描述

OpenCV 提供了如下图像位运算函数:

函数 解释
cv2.bitwise_and(src1,src2[,mask]) mask 对应的位不为 0时,图像src1 和 src2 执行按位与操作
cv2.bitwise_orsrc1,src2[,mask]) mask对应的位不为 0时,图像 sic1 和 sic2执行按位或操作
cv2.btwise _not(src1[,mask]) mask对应的位不为0时,图像 sic1执行按位取反操作
cv2.btwise _xor(src1,src2[,mask]) mask 对应的位不为 0时,图像 src1 和 sic2执行按位异或操作
import cv2


src1 = cv2.imread('lena.jpg', cv2.IMREAD_REDUCED_COLOR_2)  	     # 读取图像
src2 = cv2.imread('opencvlog.jpg', cv2.IMREAD_REDUCED_COLOR_2)	 # 读取图像
img3 = cv2.bitwise_and(src1, src2)           # 按位与
img4 = cv2.bitwise_or(src1, src2)            # 按位或
img5 = cv2.bitwise_not(src1)                 # 按位取反
img6 = cv2.bitwise_xor(src1, src2)           # 按位异或                     
cv2.imshow('lena', src1)          		     # 显示原图像
cv2.imshow('log', src2)          		     # 显示原图像
cv2.imshow('lenaandlog', img3)         		 # 显示按位与图像
cv2.imshow('lenaorlog', img4)         		 # 显示按位或图像
cv2.imshow('lenanotlog', img5)         		 # 显示按位取反图像
cv2.imshow('lenaxorlog', img6)         		 # 显示按位异或图像
cv2.waitKey(0)

在这里插入图片描述

代码素材

请添加图片描述
请添加图片描述

猜你喜欢

转载自blog.csdn.net/weixin_47166032/article/details/120612944