图像与视频

欢迎访问我的博客首页


1. 读取图像并保存为 MP4


  逐帧读取图像,把该帧旋转 180°,再保存为 mp4。读取视频时,可以设置起始帧序号或起始毫秒。代码除旋转帧外,还可以裁剪帧。由于写视频前需要指定每帧宽高,所以裁剪后的宽高要和指定的宽高一致。

import os
import cv2
from tqdm import tqdm


def video_reader(video_input, video_output):
    # 1. 获取输入视频的句柄和属性。
    cap = cv2.VideoCapture(video_input)
    fps = round(cap.get(cv2.CAP_PROP_FPS))
    frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
    wh = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
    fourcc = int(cap.get(cv2.CAP_PROP_FOURCC))
    # 2. 设置起始帧或起始毫秒时间。
    # cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
    # cap.set(cv2.CAP_PROP_POS_MSEC, 0)
    # 3. 设置输出视频的属性。
    # fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    writer = cv2.VideoWriter()
    # 4. 逐帧处理。
    idx = 0
    pbar = tqdm(total=frame_count)
    while cap.isOpened():
        rec, im = cap.read()
        if not rec:
            break
        im = cv2.rotate(im, cv2.ROTATE_180)
        # im = im[ymin:ymax, xmin:xmax]
        # 每 4 秒保存成一个视频。
        if idx % (fps * 4) == 0:
            writer.release()
            path_video = os.path.join(video_output, str(int(idx // (fps * 4))) + '.mp4')
            writer.open(path_video, fourcc, fps, wh)
        writer.write(im)
        idx += 1
        pbar.update(1)
    pbar.close()
    writer.release()
    cap.release()


if __name__ == '__main__':
    path2input = r"assets/1.mp4"
    path2output = r"assets"
    video_reader(path2input, path2output)

  fourcc 全称 Four-Character Codes,使用四个字符表示视频格式。fourcc 要和 cv2.VideoWriter 保存的视频格式对应。具体如下表:

fourcc格式
PIMI较旧的MPEG-1编码,文件名后缀为.avi
MP42MPEG-2编码,产生的文件不会特别大,文件名后缀为.avi
DIV3MPEG-3编码,产生的文件不会特别大,文件名后缀为.avi
XVID较旧的MPEG-4编码,产生的文件不会特别大,文件名后缀为.avi
MP4V较旧的MPEG-4编码,产生的文件不会特别大,文件扩展名应为.m4v
DIVXMPEG-4编码,产生的文件不会特别大,文件名后缀为.avi
X264较新的MPEG-4编码,产生的文件较小,文件扩展名应为.mp4
THEOOgg Vorbis,产生的文件相对较大,文件名后缀为.ogv
FLV1Flash视频,产生的文件相对较大,文件名后缀为.flv
MJPGmotion-jpeg编码,产生的文件较大,文件名后缀为.avi
I420未压缩的YUV编码,4:2:0色度子采样,这种编码广泛兼容,但会产生特别大的文件,文件扩展名应为.avi

2. 读取图像


2.1 读取与格式


  opencv-python 读取图形的函数如下。

img = cv2.imread(filename, flags)
  • filename:指定图像的路径。
  • flags:用来控制读取文件的类型,flages的参数值如下表。表中第一列参数与第三列是等价的。在设置参数时,既可以使用第一列的参数值,也可以使用第三列的参数值。

在这里插入图片描述

图 2.1 opencv-python 读取图像的参数

该函数可以读取多种格式的图像,具体如下。

在这里插入图片描述

图 2.2 opencv-python 支持的图像格式

下面是例子。

if __name__ == '__main__':
    im = cv2.imread(filename=r'assets/woman.jpg', flags=cv2.IMREAD_UNCHANGED)
    print(im.shape)
    im = cv2.resize(im, (im.shape[1] // 2, im.shape[0] // 2), interpolation=cv2.INTER_AREA)
    print(im.shape)
    cv2.putText(img=im,
                text='DEFGH',
                org=(100, 200),
                fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                fontScale=1,
                color=(255, 0, 0),
                thickness=3,
                lineType=cv2.LINE_4,
                bottomLeftOrigin=True)
    cv2.imwrite(r'assets/woman2.jpg', im)

2.2 中文路径


  opencv 对中文的支持不够好,读取或保存中文路径的图像可以出现异常。这时可以使用下面的方法:

def imread(filename, flags=cv2.IMREAD_UNCHANGED):
    return cv2.imdecode(np.fromfile(filename, dtype=np.uint8), flags)

def imwrite(path, im):
    ext = os.path.splitext(path)[1]
    cv2.imencode(ext, im)[1].tofile(path)

2.3 添加文本


  2.1 节已经展示了怎么添加字体,现在我们说一下参数的作用。

  • image:要在其上绘制文本的图像。
  • text:要绘制的文本字符串。
  • org:它是图像中文本字符串左下角的坐标。坐标表示为两个值的元组,即(X坐标值,Y坐标值)。
  • font:它表示字体类型。一些字体类型是FONT_HERSHEY_SIMPLEX,FONT_HERSHEY_PLAIN等。
  • fontScale:字体比例因子乘以font-specific基本大小。
  • color:它是要绘制的文本字符串的颜色。对于BGR,我们通过一个元组。例如:(255,0,0)为蓝色。
  • thickness:它是线的粗细像素。
  • lineType:这是一个可选参数,它给出了要使用的行的类型。
  • bottomLeftOrigin:这是一个可选参数。如果为true,则图像数据原点位于左下角。否则,它位于左上角。

可选字体如下:

字体含义
cv.FONT_HERSHEY_SIMPLEXnormal size sans-serif font
cv.FONT_HERSHEY_PLAINsmall size sans-serif font
cv.FONT_HERSHEY_DUPLEXnormal size sans-serif font (more complex than FONT_HERSHEY_SIMPLEX)
cv.FONT_HERSHEY_COMPLEXnormal size serif font
cv.FONT_HERSHEY_TRIPLEXnormal size serif font (more complex than FONT_HERSHEY_COMPLEX)
cv.FONT_HERSHEY_COMPLEX_SMALLsmaller version of FONT_HERSHEY_COMPLEX
cv.FONT_HERSHEY_SCRIPT_SIMPLEXhand-writing style font
cv.FONT_HERSHEY_SCRIPT_COMPLEXmore complex variant of FONT_HERSHEY_SCRIPT_SIMPLEX
cv.FONT_ITALICflag for italic font

2.4 几何图形


  画圆、线、矩形、四边形、椭圆。

# im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.circle(img=im, center=(100, 100), radius=9, color=(255, 0, 0), thickness=-1, lineType=8)
cv2.line(img=im, pt1=(100, 100), pt2=(500, 400), color=(0, 255, 0), thickness=2, lineType=8)
cv2.rectangle(img=im, pt1=(100, 100), pt2=(500, 400), color=(0, 0, 255), thickness=2, lineType=8)
polygon_1 = np.array([[300, 100], [500, 400], [100, 400]])
polygon_2 = np.array([[300, 100], [500, 250], [300, 400], [100, 250]])
cv2.polylines(img=im, pts=[polygon_1, polygon_2], isClosed=True, color=(0, 255, 255), thickness=2, lineType=8)
cv2.ellipse(img=im, center=(300, 250), axes=(200, 150), angle=0, startAngle=-45, endAngle=225, color=(255, 0, 255), thickness=2, lineType=8)

3. 图像切片


  下面的代码使用参数 n_yx 把一副图像切割成大小相等的 n_yx[0] 行,n_yx[1] 列。

def slice_image(image, n_yx: list = None):
    if not n_yx:
        n_yx = [4, 4]
    h = image.shape[0] // n_yx[0]
    w = image.shape[1] // n_yx[1]
    for i in range(n_yx[0]):
        for j in range(n_yx[1]):
            image_ij = image[i * h:(i + 1) * h, j * w:(j + 1) * w]
            cv2.imwrite(str(i) + str(j) + '.jpg', image_ij)

4. 绘制直方图


  绘制三个通道和灰度图的直方图,并显示 rgb 图像。

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


def show_hist(path_im: str):
    # 1.获取图像。
    im_bgr = cv2.imread(path_im, 1)
    im_gra = cv2.cvtColor(im_bgr, cv2.COLOR_BGR2GRAY)
    count_pixel = im_bgr.shape[0] * im_bgr.shape[1]
    # 2.统计直方图。
    hist_b = cv2.calcHist([im_bgr], [0], None, [256], [0, 255]) * 100 / count_pixel
    hist_g = cv2.calcHist([im_bgr], [1], None, [256], [0, 255]) * 100 / count_pixel
    hist_r = cv2.calcHist([im_bgr], [2], None, [256], [0, 255]) * 100 / count_pixel
    hist_a = cv2.calcHist([im_gra], [0], None, [256], [0, 255]) * 100 / count_pixel
    # 3.绘图。
    fig, ax = plt.subplots(2, 1, figsize=(10.24, 7.68), dpi=100)
    # 3.1 绘制直方图。
    ax[0].plot(hist_b, color='b')
    ax[0].plot(hist_g, color='g')
    ax[0].plot(hist_r, color='r')
    ax[0].plot(hist_a, color='gray')
    # 3.2 绘制 OpenCV 图像。
    im_rgb = cv2.cvtColor(im_bgr, cv2.COLOR_BGR2RGB)
    ax[1].imshow(im_rgb)
    # 4.显示与保存。
    plt.grid()
    # plt.show()
    plt.savefig('1.jpg')


if __name__ == '__main__':
    path_input = r'assets/example.jpg'
    show_hist(path_input)

  效果如下。
在这里插入图片描述

图 4 图像直方图

5. 参考


  1. VideoCapture 属性,OpenCV document。
  2. fourcc,OpenCV document。
  3. fourcc,CSDN,2021。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值