美文网首页
图像处理库OpenCV安装与使用

图像处理库OpenCV安装与使用

作者: Byte猫 | 来源:发表于2019-05-09 13:15 被阅读0次

    OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
    官方文档

    安装

    pip install opencv-python 
    pip install opencv-contrib-python  # 安装opencv-contrib,包含一些其它库,比如xfeature2d
    

    在安装后通过在python控制台中输入"import cv2"命令可以验证是否成功安装

    使用OpenCV

    1、图像的存取

    import cv2 as cv
    # 读取彩色图像
    img = cv.imread('test.jpg')  # 读取后直接就是numpy数组的形式
    # 直接读取单通道灰度图
    gray_img = cv.imread('test.jpg', cv.IMREAD_GRAYSCALE)
    # 彩色图变为灰度图
    # gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    # 灰度图像二值化
    # threshold = 155
    # _, binary_image = cv.threshold(gray_img, threshold, 255, cv.THRESH_BINARY)  # 超过阈值的像素值修改成设定值,其他值为0
    
    # 输出图片信息
    print('彩色图片尺寸:', img.shape)
    print('彩色图片数据:', type(img), img)
    print('灰度图片尺寸:', gray_img.shape)
    print('灰度图片数据:', type(gray_img), gray_img)
    

    把单通道图片保存后,再读取,仍然是3通道,相当于把单通道值复制到3个通道保存

    cv.imwrite('test_gray.jpg', gray_img)
    reload_grayimg = cv.imread('test_gray.jpg')
    print(reload_grayimg.shape)
    

    保存图像时还可以根据需要控制文件大小

    # IMWRITE_JPEG_QUALITY指定jpg质量,范围0到100,默认95,越高画质越好,文件越大
    cv.imwrite('test_imwrite.jpg', color_img, (cv.IMWRITE_JPEG_QUALITY, 80))
    # IMWRITE_PNG_COMPRESSION指定png质量,范围0到9,默认3,越高文件越小,画质越差
    cv.imwrite('test_imwrite.png', color_img, (cv.IMWRITE_PNG_COMPRESSION, 5))
    

    2、图像显示

    cv.imshow('picture show', img)
    cv.waitKey(0)
    if k == 27:          # wait for ESC key to exit
        cv.destroyAllWindows()
    elif k == ord('s'):   # wait for 's' key to save and exit
        cv.imwrite('mypic.png', img)
        cv.destroyAllWindows()
    

    需要注意的是opencv加载的图像色彩通道是BGR不是RGB,如果想要用matplotlib进行显示,需要进行转换

    import matplotlib.pyplot as plt
    
    # 改变颜色 (from BGR to RGB)
    img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
    plt.imshow(img)
    plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
    plt.show()
    

    3、色度、饱和度、明度

    调整色度

    # 通过cvtColor把图像从BGR转换到HSV
    img_hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
    
    # H空间中,绿色比黄色的值高一点,所以给每个像素+15,黄色的树叶就会变绿
    turn_green_hsv = img_hsv.copy()
    turn_green_hsv[:, :, 0] = (turn_green_hsv[:, :, 0]+15) % 180
    turn_green_img = cv.cvtColor(turn_green_hsv, cv.COLOR_HSV2BGR)
    

    调整饱和度

    # 减小饱和度会让图像损失鲜艳,变得更灰
    colorless_hsv = img_hsv.copy()
    colorless_hsv[:, :, 1] = 0.5 * colorless_hsv[:, :, 1]
    colorless_img = cv.cvtColor(colorless_hsv, cv.COLOR_HSV2BGR)
    

    调整明度

    # 减小明度为原来一半
    darker_hsv = img_hsv.copy()
    darker_hsv[:, :, 2] = 0.5 * darker_hsv[:, :, 2]
    darker_img = cv.cvtColor(darker_hsv, cv.COLOR_HSV2BGR)
    

    4、图像变换

    图像缩放

    # 指定大小,缩放成 (width, height)的图像
    img_resize = cv.resize(img, (200, 200))
    
    # 按照50%比例缩放, interpolation表示使用何种差值方式对图像进行缩放
    # INTER_NEAREST为采用最近邻插值
    # INTER_LINEAR为双线性插值,默认情况使用
    # INTER_NEAREST为最邻近插值
    # INTER_AREA使用像素区域关系重新采样,和INTER_NEAREST相似
    # INTER_CUBIC采用4x4像素邻域内的双立方插值
    img_resize = cv.resize(img, (0, 0), fx=0.5, fy=0.5, interpolation=cv.INTER_NEAREST)
    

    图像旋转

    def rotate_bound(image, angle):
        '''
        图像旋转
        INPUT -> 图像数组, 旋转角度(顺时针)
        '''
        (h, w) = image.shape[:2]
    
        # 旋转中心点
        (cX, cY) = (w // 2, h // 2)
    
        # 获得旋转矩阵
        M = cv.getRotationMatrix2D((cX, cY), -angle, 1.0)
        #theta = angle * np.pi / 180
        #M = np.array([
        #    [np.cos(theta), -np.sin(theta), 0],
        #    [np.sin(theta), np.cos(theta), 0]
        #], dtype=np.float32)
    
        cos = np.abs(M[0, 0])
        sin = np.abs(M[0, 1])
    
        # 计算图像新外接框
        nW = int((h * sin) + (w * cos))
        nH = int((h * cos) + (w * sin))
    
        M[0, 2] += (nW / 2) - cX
        M[1, 2] += (nH / 2) - cY
    
        return cv.warpAffine(image, M, (nW, nH))
    
    img2 = rotate_bound(img, 45)
    

    图像截取

    # 直接截取
    dst = img[10:600, 10:400]
    
    # 沿着横纵轴放大1.6倍,然后平移(-150,-240),最后按原图大小截取,等效于裁剪并放大
    M = np.array([
        [1.6, 0, -150],
        [0, 1.6, -240]
    ], dtype=np.float32)
    dst = cv.warpAffine(img, M, (img.shape[1], img.shape[0]))
    

    图像移位

    M = np.array([
        [1, 0, -150],
        [0, 1, -240]
    ], dtype=np.float32)
    dst = cv2.warpAffine(img, M, (height,width))
    

    5、摄像头、视频的读取以及保存

    打开摄像头并保存视频

    # coding = utf-8
    import numpy as np
    import cv2 as cv
    import time
    
    def video_save(num_frames, filepath, out_fps):
        '''
        打开摄像头并保存视频
        INPUT -> 捕获总帧数, 视频保存路径, 输出帧率
        '''
        
        cap = cv.VideoCapture(0)  # VideoCapture(0)表示打开默认的相机
        if cap.isOpened() is False:   # 确认摄像头是否成功打开
            print('Error')
            exit(1)
    
        # 获取捕获的分辨率
        size = (int(cap.get(cv.CAP_PROP_FRAME_WIDTH)),
                int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)))
        # 设置要保存视频的编码,分辨率和帧率
        video = cv.VideoWriter(
            filepath,
            cv.VideoWriter_fourcc('M', 'P', '4', '2'),   # 视频编码格式参考:http://www.fourcc.org/codecs.php
            out_fps,   # 输出文件的帧率
            size
        )
    
        for i in range(num_frames):
            ret, frame = cap.read()
            video.write(frame)
            # time.sleep(interval)  捕获图像的间隔(秒)
    
        # 释放资源并写入视频文件
        video.release()
        cap.release()
    
    
    video_save(100, '100000.avi', 24)
    
    def video_save2(key, window_name, path, out_fps):
        '''
        打开摄像头并保存视频(不限定总帧数,直到按下某键)
        INPUT -> 按键, 窗口名, 视频保存路径, 输出帧率
        '''
        cv.namedWindow(window_name) # 创建一个窗口
    
        cap = cv.VideoCapture(0)  # VideoCapture(0)表示打开默认的相机
        if cap.isOpened() is False:   # 确认摄像头是否成功打开
            print('Error')
            exit(1)
    
        # 获取捕获的分辨率
        size = (int(cap.get(cv.CAP_PROP_FRAME_WIDTH)),
                int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)))
        # 设置要保存视频的编码,分辨率和帧率
        video = cv.VideoWriter(
            path,
            cv.VideoWriter_fourcc('M', 'P', '4', '2'),   # 视频编码格式参考:http://www.fourcc.org/codecs.php
            out_fps,   # 输出文件的帧率
            size
        )
    
        while True:
            ret, frame = cap.read()
            video.write(frame)
    
            cv.imshow(window_name, frame) # 将图像矩阵显示在一个窗口中
            if cv.waitKey(20) & 0xFF == ord(key): # 每隔20ms采集一帧,按某键退出采集
                break
    
        # 释放资源并写入视频文件
        video.release()
        cap.release()
        cv.destroyWindow(window_name)
    
    video_save2('k', 'test window', '100001.avi', 24)
    

    间隔读取视频文件中的每帧的图片

    def video_extraction(filepath, interval):
        '''
        视频帧提取
        INPUT -> 视频地址, 帧间隔
        '''
        if not os.path.exists(os.path.abspath(filepath) +"_extraction"):
            os.mkdir(os.path.abspath(filepath) +"_extraction")
        cap = cv.VideoCapture()
    
        cap.open(filepath)
        # 获取视频帧数
        num_frames = int(cap.get(cv.CAP_PROP_FRAME_COUNT))
    
        for i in range(num_frames):
            ret, frame = cap.read()
            if i % interval == 0:  # 每隔interval帧进行一次截屏操作
                imagepath = os.path.abspath(filepath) +"_extraction\ " + str(i)+".jpg"
                print('导出 {}!'.format(imagepath))
                cv.imwrite(imagepath, frame)
    
        # 执行结束释放资源
        cap.release()
    
    video_extraction('100001.avi', 10)
    

    相关文章

      网友评论

          本文标题:图像处理库OpenCV安装与使用

          本文链接:https://www.haomeiwen.com/subject/puzioqtx.html