【OpenCV】Mango的OpenCV学习笔记【二】

本文主要参考自 OpenCV官方文档

一、图像的基本操作

  1. 访问、修改像素值

    import cv2
    
    img = cv2.imread('../../Resources/messi15.jpg')
    px = img[100, 100]
    print(px)
    
    # 仅访问单一通道像素值
    blue = img[100, 100, 0]
    print(blue)
    
    # 修改像素值
    img[100, 100] = [255, 255, 255]
    print(img[100, 100])
    
    # 更好的像素访问和编辑方法,返回标量
    # 访问 RED 值
    print(img.item(10, 10, 2))
    
    # 修改RED值
    img.itemset((10, 10, 2), 100)
    print(img.item(10, 10, 2))
    
  2. 访问图像属性

    # 图像形状
    print(img.shape)
    
    # 图像像素值总数
    print(img.size)
    
    # 图像数据类型
    print(img.dtype)
    
  3. 图像感兴趣区域ROI
    使用Numpy索引获得ROI,选择球并将其复制到图像中的另一个区域:

    import cv2
    
    img = cv2.imread('../../Resources/messi15.jpg')
    ball = img[280:340, 330:390]
    img[273:333, 100:160] = ball
    
    cv2.imshow('messi', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

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

  4. 为图像设置边框(了解即可)
    如果要在图像周围创建边框(如相框),则可以使用 cv.copyMakeBorder()
    其参数如下:
    src:输入图像

    topbottomleftright:边界宽度(以相应方向上的像素数为单位)

    borderType:定义要添加哪种边框的标志。它可以是以下类型:

    cv.BORDER_CONSTANT:添加恒定的彩色边框。该值应作为下一个参数给出。

    cv.BORDER_REFLECT:边框将是边框元素的镜像,如下所示: fedcba | abcdefgh | hgfedcb

    cv.BORDER_REFLECT_101cv.BORDER_DEFAULT 与上述相同,但略有变化,例如: gfedcb | abcdefgh | gfedcba

    cv.BORDER_REPLICATE:最后一个元素被复制,像这样: aaaaaa | abcdefgh | hhhhhhh

    cv.BORDER_WRAP:难以解释,它看起来像这样: cdefgh | abcdefgh | abcdefg

    value:边框的颜色,如果边框类型为 cv.BORDER_CONSTANT

    import cv2
    from matplotlib import pyplot as plt
    
    BLUE = [255, 0, 0]
    img1 = cv2.imread('../../Resources/opencv-logo.jpg')
    replicate = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_REPLICATE)
    reflect = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_REFLECT)
    reflect101 = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_REFLECT_101)
    wrap = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_WRAP)
    constant = cv2.copyMakeBorder(img1, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value=BLUE)
    print(img1, reflect)
    plt.subplot(231), plt.imshow(img1, '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()
    

    效果图如下(图像是采用matplotlib显示的,因此红色和蓝色通道将互换):在这里插入图片描述

二、图像运算

  1. 图像加法
    注意: OpenCV 加法和 Numpy 加法之间有区别
    ① OpenCV 加法是饱和运算
    ② 而 Numpy 加法是模运算
    import cv2
    
    img1 = cv2.imread('../../Resources/3D-Matplotlib.png')
    img2 = cv2.imread('../../Resources/mainsvmimage.png')
    
    add = img1 + img2  # 模运算,250+10 = 260 % 256 = 4
    cv_add = cv2.add(img1, img2)  # 像素点值相加,所以图片变白,50+10 = 260 => 255
    
    cv2.imshow('add', add)
    cv2.imshow('cv_add', cv_add)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    在这里插入图片描述
  2. 图像融合
    公式: d s t = s r c 1 ∗ α + s r c 2 ∗ β + γ dst = src1 * α + src2 * β + γ dst=src1α+src2β+γ
    import cv2
    
    img1 = cv2.imread('./Image/3D-Matplotlib.png')
    img2 = cv2.imread('./Image/mainsvmimage.png')
    weighted = cv2.addWeighted(img1, 0.6, img2, 0.4, 0)  # 设置权重进行叠加
    cv2.imshow('weighted', weighted)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    效果图如下
    在这里插入图片描述
  3. 按位运算
    ① 或运算,求并集,加法:cv2.bitwise_or(img1, img2)
    ② 与运算,求交集,重叠部位: cv2.bitwise_and(img1, img2)
    ③ 非运算,求空集,取反色:cv2.bitwise_not(img1)
    ④ 异或运算,相同为0,不同为1:
    cv2.bitwise_xor(img1, img1)cv2.bitwise_xor(img1, img2)
    img1 = cv2.imread('../../Resources/3D-Matplotlib.png')
    img2 = cv2.imread('../../Resources/mainlogo.png')
    
    rows, cols, channels = img2.shape
    roi = img1[0:rows, 0:cols]
    
    img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    ret, mask = cv2.threshold(img2_gray, 220, 255, cv2.THRESH_BINARY_INV)
    
    mask_inv = cv2.bitwise_not(mask)
    img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
    img2_fg = cv2.bitwise_and(img2, img2, mask=mask)
    
    dst = cv2.add(img1_bg, img2_fg)
    img1[0:rows, 0:cols] = dst
    
    # cv2.imshow('img_', img2_gray)
    # cv2.imshow('img_1', mask)
    # cv2.imshow('img_2', mask_inv)
    # cv2.imshow('img_3', img1_bg)
    # cv2.imshow('img_4', img2_fg)
    # cv2.imshow('mask', mask)
    cv2.imshow('new_img', img1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    效果图如下在这里插入图片描述

三、视频练习

  1. 要求:向视频中添加动态字幕、矩形…
    import cv2
    import random
    import numpy as np
    import pandas as pd
    from PIL import Image, ImageDraw, ImageFont
    import time
    
    
    # 颜色
    def rand_color():
        font_r = random.randint(128, 255)
        font_g = random.randint(128, 255)
        font_b = random.randint(128, 255)
        return font_r, font_g, font_b
    
    
    # 矩形坐标读取
    def rectangle_point(index):
        data = pd.read_table("coordinate.txt", sep=",", header=None)
        point_x, point_y = [], []
        for i_ in range(len(data)):
            point_1 = (data[0][i_], data[1][i_])
            point_2 = (data[2][i_], data[3][i_])
            point_x.append(point_1)
            point_y.append(point_2)
        return point_x[index], point_y[index]
    
    
    # 画矩形框
    def draw_rectangle(frame_, point1, point2):
        cv2.rectangle(frame_, point1, point2, rand_color(), random.randint(1, 2))
    
    
    # 中文读取
    def chinese_text():
        data_1 = pd.read_table("text.txt", header=None)
        text_list = []
        for i_ in range(len(data_1)):
            text_list.append(data_1[0][i_])
        return text_list
    
    
    # 绘制中文字体
    def paint_chinese(frame_, chinese, pos, color):
        img_ = Image.fromarray(cv2.cvtColor(frame_, cv2.COLOR_BGR2RGB))
        draw = ImageDraw.Draw(img_)
    
        font = ImageFont.truetype(r'./msyh.ttc', 20, encoding='utf-8')
        fill_color = color  # (255,0,0)
        position = pos  # (100,100)
    
        draw.text(position, chinese, font=font, fill=fill_color)
        image_ = cv2.cvtColor(np.array(img_), cv2.COLOR_RGB2BGR)
        return image_
    
    
    # 视频保存
    def save_video(cap_):
        width_ = int(cap_.get(3))
        height_ = int(cap_.get(4))
        fps_ = cap.get(cv2.CAP_PROP_FPS)
        fourcc_ = cv2.VideoWriter_fourcc(*'mp4v')
        new_video = cv2.VideoWriter(r'./new_video.mp4', fourcc_, fps_, (width_, height_))
        return new_video
    
    
    if __name__ == '__main__':
        start = time.time()
        path = r'../../Resources/cat.mp4'
        cap = cv2.VideoCapture(path)
        new_video_ = save_video(cap)
    
        fps = cap.get(cv2.CAP_PROP_FPS)
        total_fps = cap.get(cv2.CAP_PROP_FRAME_COUNT)
    
        current_frame = 0
        while True:
            ret, frame = cap.read()
            if cv2.waitKey(int(np.ceil(total_fps / fps)) // 2) & 0xFF == ord('q'):
                break
            elif ret is False:
                break
    
            for i in range(len(chinese_text())):
                start_frame = i * (total_fps / 5)
                end_frame = (i + 1) * (total_fps / 5)
                # print(current_frame, start_frame, end_frame, rectangle_point(i)[0], rectangle_point(i)[1])
                if start_frame <= current_frame <= end_frame:
                    draw_rectangle(frame, rectangle_point(i)[0], rectangle_point(i)[1])
                    new_img = paint_chinese(frame, chinese_text()[i], (200, 750), rand_color())
    
                    new_video_.write(new_img)
                    cv2.imshow('cat', new_img)
    
                if current_frame > total_fps:
                    break
    
            current_frame += 1
    
        cap.release()
        new_video_.release()
        cv2.destroyAllWindows()
        end = time.time()
        print(end - start)
    
    
    实现的部分视频效果如下在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值