opencv-python 一: 图像和视频的读取、保存等基本操作


一 图片读取保存及通道转换

1. 彩色图像的读取和显示

import cv2
import numpy as np
import matplotlib.pyplot as plt
import imageio

def cv_show_image(name, img):   # 显示图像,这个函数在下面会一直用到
    cv2.imshow(name, img)   # img 通道顺序为BGR
    # 等待的时间以毫秒ms为单位,0表示无限等待,按任意键退出
    cv2.waitKey(0)
    cv2.destroyAllWindows()  # 销毁所有窗口

filename = './tools/shiyuan.jpeg'

img = cv2.imread(filename)  # opencv读取的图片格式为 BGR
print('img.shape: ', img.shape)
cv_show_image('color_image', img)

2. 得到灰度图的两种方法

# 设定imread()函数的参数,直接返回灰度图
img2 = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
print('img2.shape: ', img2.shape)
cv_show_image('gray_image', img2)

# 已读取彩色图像,需要将彩色图转换为灰度图
# 标准转换公式如下: gray = 0.299 * Red + 0.587 * Green + 0.114 * Blue (加权平均)
# 还有: 完全均值、最大值法、最小值法、photoshop转灰度图法,此处略去
img3 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print('img3.shape: ', img3.shape)
cv_show_image('color2gray', img3)

3. 三种从BGR到RGB的通道转换方法

  opencv读取的图像通道顺序为BGR,和常用的RGB通道顺序不一致,这在图像的显示上存在差异,小编习惯于使用matplotlib显示图像,故matplotlib显示图像前需要进行通道转换 (面对灰度图就不需要转换了,反正只有一个通道,只是plt显示灰度图时, plt.imshow(img, cmap='gray')),记得设置cmap参数为gray。

# 图像转换 三种由 BGR 转变为 RGB 通道的方法
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))  # 返回一个新的修改后的图像
plt.axis('off')
plt.show()

# split 分别获得图像的 Blue、Green、Red 通道,之后重新merge组合
b, g, r = cv2.split(img) 
plt.imshow(cv2.merge([r, g, b]))
plt.axis('off')
plt.show()

new_img = img[:, :, ::-1]
# [::-1] 表示顺序相反的意思,图像shape是[H, W, C] 其中C表示通道,开始为BGR顺序,将C维度顺序逆转,就变成了RGB
plt.imshow(new_img)  # 返回一个新的修改后的图像
plt.axis('off')
plt.show()

  啰嗦一句,plt显示图像,要求图像的通道顺序为RGB,所以面对opencv读取的图像,需要将图像的通道顺序由BGR转换为RGB;反过来,若使用opencv中的cv2.imshow() 函数显示图像,由于该函数要求图像的通道顺序为BGR,所以面对plt.imread()、imageio.imread(), PIL.imread()等函数读取的图像,也需要将图像的通道顺序从RGB转换为BGR。转换方法类似如下:cv2.cvtColor(img, cv2.COLOR_BGR2RGB)。cv2.cvtColor()函数中第二个参数有多种,涉及到BGR、RGB、GRAY、HSV等多种类型,此处不赘述。

4. ROI区域

  图像的ROI区域看起来高大上,其实就是Region of Interest 图像中感兴趣的部分,一般先将图像中感兴趣的部分提取出来,然后进行操作。例如若想要截取图像中某方形区域,可以使用np.array的切片操作,演示代码如下。

import numpy as np
import cv2
import matplotlib.pyplot as plt

def cv_show_image(name, image):
    cv2.imshow(name, image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

filename = './tools/shiyuan.jpeg'
img = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
cv_show_image('gray_img', img)

img2 = img[100: 400, 200: 600]  # 切片操作
cv_show_image('img_roi', img2)

5. 图像融合

  将两张图像进行融合,函数为cv2.addWeighted(img1, alpha, img2, beta, bias),例如cv2.addWeighted(img1, 0.6, img2, 0.4, 0)其中第一个图像的权重为0.6,第二张图像的权重为0.4,bias偏置项为0,bias主要对图像亮度上的调整。进行图像融合需要保证融合的两个图像有相同的shape,通常通过cv2.resize()进行调整。

filename1 = './tools/shiyuan.jpeg'
img1 = cv2.imread(filename1)

filename2 = './tools/shiyuan2.jpeg'
img2 = cv2.imread(filename2)
img2 = cv2.resize(img2, img1.shape[:2])

img3 = cv2.addWeighted(img1, 0.6, img2, 0.4, 0)
cv_show_image('shiyuan', img3)

  融合结果如下:
在这里插入图片描述
  补充一句,cv2.resize()常用的方法有两种:cv2.resize(img, (500, 400))cv2.resize(img, (0, 0), fx=3, fy=2),前者将图像img变换为指定大小(500, 400),后者没有规定变换后的图像大小,只是要求将图像宽度变为原来的3倍(fx=3),高度变为原来的2倍(fy=2)。
  还有一个小知识点,将两个shape相同的图像相加,有两种常用方法:(1) 使用+号直接相加。(2) 使用cv2.add()函数相加;前者对应像素点像素值相加,若超过了255,则对255取余,后者若超过255,直接截断,取值为255。

二 读取并显示视频

1. 读取视频

  视频本质上就是一张一张的图像,称为帧。单位时间内显示的帧的数量,我们称之为帧率,帧率越高,视频越流畅,若帧率低于某一范围,就会视频出现卡顿现象。读取视频的代码如下(想运行代码但手上没视频文件的小伙伴,可以使用电脑录屏功能自己生成):

# 捕获摄像头
vc = cv2.VideoCapture('./tools/test.mp4')

# 若视频正确打开,则isOpened()函数返回True,反之False
while vc.isOpened():
    is_open, frame = vc.read()  # read()读视频,is_open 为布尔值,frame为图像帧
    if frame is None:  # frame == None 表示视频读完了,break退出
        break
    if is_open:
        gray_img = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        cv2.imshow('test.mp4', gray_img)
        # cv2.waitKey(50)表示帧持续的时间,时间越短,视频播放的速度越快
        if cv2.waitKey(50) & 0xFF == 27:  # 27是Esc键的ASCII码,也可以换为q键,如: oxFF == ord('q')
            break

vc.release()  # 释放摄像头
cv2.destroyAllWindows()

2. get()方法获取视频属性

  VideoCapture对象常用的还有get()方法,可以获得诸如:帧的高度、帧的宽度、帧率、视频总帧数、视频时长等属性。代码如下:

# 宽度
width = vc.get(cv2.CAP_PROP_FRAME_WIDTH)  

# 高度
height = vc.get(cv2.CAP_PROP_FRAME_HEIGHT)  

 # 帧率
fps = vc.get(cv2.CAP_PROP_FPS) 
 # 总帧数
frame_count = vc.get(cv2.CAP_PROP_FRAME_COUNT) 

# 总秒数
time_count = int(frame_count / fps)  '

print('width: ', width)
print('height: ', height)
print('fps: ', fps)
print('frame_count: ', frame_count)
print('time_count: ', time_count)

参考文献:

  1. https://www.bilibili.com/video/BV1PV411774y?p=5
  2. https://xercis.blog.csdn.net/article/details/90295866
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值