您的位置:  首页 > 技术杂谈 > 正文

OpenCV计算机视觉整理

2021-11-14 10:00 https://my.oschina.net/u/3768341/blog/5308567 算法之名 次阅读 条评论

图像、视频加载与显示

创建显示窗口

import cv2

if __name__ == "__main__":

    # 创建窗口
    cv2.namedWindow('new', cv2.WINDOW_NORMAL)
    # 调整窗口大小
    cv2.resizeWindow('new', 640, 480)
    # 显示窗口
    cv2.imshow('new', 0)
    # 显示时长
    key = cv2.waitKey(0)
    if key == 'q':
        exit()
    # 销毁窗口
    cv2.destroyWindow()

运行结果

载入图片

import cv2

if __name__ == "__main__":

    cv2.namedWindow('img', cv2.WINDOW_NORMAL)
    img = cv2.imread("/Users/admin/Documents/WechatIMG12.jpeg")
    cv2.imshow('img', img)
    while True:
        key = cv2.waitKey(0)
        if key & 0xFF == ord('q'):
            break
    cv2.destroyAllWindows()

运行结果

保存文件

import cv2

if __name__ == "__main__":

    cv2.namedWindow('img', cv2.WINDOW_NORMAL)
    img = cv2.imread("/Users/admin/Documents/WechatIMG12.jpeg")
    cv2.imshow('img', img)
    while True:
        key = cv2.waitKey(0)
        if key & 0xFF == ord('q'):
            break
        elif key & 0xFF == ord('s'):
            cv2.imwrite("/Users/admin/Documents/帅照.png", img)
    cv2.destroyAllWindows()

当我们点击键盘"s"键的时候,运行结果

进入/Users/admin/Documents文件夹

(base) -bash-3.2$ ls | grep 帅照
帅照.png

摄像头视频采集

import cv2

if __name__ == "__main__":

    # 创建窗口
    cv2.namedWindow('video', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('video', 640, 480)
    # 获取视频设备
    cap = cv2.VideoCapture(0)
    while True:
        # 从摄像头读视频桢
        ret, frame = cap.read()
        # 将视频帧在窗口中显示
        cv2.imshow('video', frame)
        key = cv2.waitKey(1)
        if key & 0xFF == ord('q'):
            break
    # 释放资源
    cap.release()
    cv2.destroyAllWindows()

运行结果

这里可以看到摄像头已经打开,并开始采集视频。

读取视频文件

我们这里使用一段鹦鹉的视频,使用命令ffplay查看每秒播放帧数

./ffplay cockatoo.mp4
ffplay version N-104454-gd92fdc7144-tessus  https://evermeet.cx/ffmpeg/  Copyright (c) 2003-2021 the FFmpeg developers
  built with Apple clang version 11.0.0 (clang-1100.0.33.17)
  configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libmysofa --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvmaf --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-version3 --pkg-config-flags=--static --enable-librtmp --enable-ffplay --enable-sdl2 --disable-ffmpeg --disable-ffprobe
  libavutil      57.  7.100 / 57.  7.100
  libavcodec     59. 12.100 / 59. 12.100
  libavformat    59.  8.100 / 59.  8.100
  libavdevice    59.  0.101 / 59.  0.101
  libavfilter     8. 16.100 /  8. 16.100
  libswscale      6.  1.100 /  6.  1.100
  libswresample   4.  0.100 /  4.  0.100
  libpostproc    56.  0.100 / 56.  0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'cockatoo.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf56.4.101
  Duration: 00:00:14.00, start: 0.000000, bitrate: 416 kb/s
  Stream #0:0[0x1](und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p(progressive), 1280x720, 387 kb/s, 20 fps, 20 tbr, 10240 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: mp3 (mp4a / 0x6134706D), 16000 Hz, mono, fltp, 24 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
  13.63 A-V: -0.031 fd=   0 aq=    0KB vq=    0KB sq=    0B f=0/0   

我们可以看到有这么一段

Stream #0:0[0x1](und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p(progressive), 1280x720, 387 kb/s, 20 fps, 20 tbr, 10240 tbn (default)

这里有一个20 fps,说明该视频是每秒播放20桢

import cv2

if __name__ == "__main__":

    # 创建窗口
    cv2.namedWindow('video', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('video', 640, 480)
    # 获取视频文件
    cap = cv2.VideoCapture("/Users/admin/Downloads/cockatoo.mp4")
    while True:
        # 从文件读视频桢
        ret, frame = cap.read()
        # 将视频帧在窗口中显示
        cv2.imshow('video', frame)
        # 此处不能设为1,否则会过快,可以设的比播放视频每秒帧数长一点
        key = cv2.waitKey(40)
        if key & 0xFF == ord('q'):
            break
    # 释放资源
    cap.release()
    cv2.destroyAllWindows()

运行结果

摄像头采集数据输出为媒体文件

import cv2

if __name__ == "__main__":

    fourcc = cv2.VideoWriter_fourcc(*'MJPG')
    # 25为帧率,(1280, 720)为分辨率,该分辨率必须与设备摄像头分辨率保持一致
    vw = cv2.VideoWriter("/Users/admin/Documents/out.mp4", fourcc, 25, (1280, 720))
    # 创建窗口
    cv2.namedWindow('video', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('video', 640, 480)
    # 获取摄像头资源
    cap = cv2.VideoCapture(0)
    # 判断摄像头是否打开
    while cap.isOpened():
        # 从摄像头读视频桢
        ret, frame = cap.read()
        if ret:
            # 将视频帧在窗口中显示
            cv2.imshow('video', frame)
            # 写数据到多媒体文件
            vw.write(frame)
            key = cv2.waitKey(1)
            if key & 0xFF == ord('q'):
                break
        else:
            break
    # 释放资源
    cap.release()
    vw.release()
    cv2.destroyAllWindows()

运行结果

(base) -bash-3.2$ ls | grep out
out.mp4

控制鼠标

import cv2
import numpy as np

def mouse_callback(event, x, y, flags, userdata):
    print(event, x, y, flags, userdata)

if __name__ == "__main__":

    cv2.namedWindow('mouse', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('mouse', 640, 360)
    # 设置鼠标回调
    cv2.setMouseCallback('mouse', mouse_callback, '123')
    # 设置背景为黑色
    img = np.zeros((360, 640, 3), np.uint8)
    while True:
        cv2.imshow('mouse', img)
        key = cv2.waitKey(1)
        if key & 0xFF == ord('q'):
            break
    cv2.destroyAllWindows()

运行结果

当鼠标在黑色区域滑动的时候,控制台会将鼠标的坐标给打印出来

0 272 156 0 123
0 272 155 0 123
0 272 155 0 123
0 271 155 0 123
0 271 155 0 123

TrackBar的使用

TrackBar就是一种滑动条,滑动到不同的位置,获取相应的值做不同的处理。

import cv2
import numpy as np

def callback():
    pass

if __name__ == "__main__":

    cv2.namedWindow('trackbar', cv2.WINDOW_NORMAL)
    # 创建trackbar,R是trackbar的名字,0是默认当前值,255是最大值
    cv2.createTrackbar('R', 'trackbar', 0, 255, callback)
    cv2.createTrackbar('G', 'trackbar', 0, 255, callback)
    cv2.createTrackbar('B', 'trackbar', 0, 255, callback)
    # 纯黑色背景
    img = np.zeros((480, 640, 3), np.uint8)
    while True:
        cv2.imshow('trackbar', img)
        r = cv2.getTrackbarPos('R', 'trackbar')
        g = cv2.getTrackbarPos('G', 'trackbar')
        b = cv2.getTrackbarPos('B', 'trackbar')
        img[:] = [b, g, r]
        key = cv2.waitKey(10)
        if key & 0xFF == ord('q'):
            break
    cv2.destroyAllWindows()

运行结果

trackbar取不同的值会有不同的背景色

OpenCV的色彩空间

RGB人眼的色彩空间

每一个像素有三种颜色——红色、绿色和蓝色。通过不同光源的组合,形成真彩色,有暗的,有明亮的。

上图中每一个方格都代表一个像素。

OpenCV默认使用的是BGR,BGR跟RGB的区别就是排列顺序的不同。电脑上一般的排列顺序都是RGB。

HSV/HSB/HSL

HSV代表的是色相、饱和度、明亮度。HSB和HSV是一个意思。

  1. Hue:色相,即色彩,如红色、蓝色
  2. Saturation:饱和度,颜色的纯度,值越大,纯度越高,最开始的时候是灰的,逐渐增大就纯度越高,如果是红色就是纯红,蓝色就是纯蓝
  3. Value:明度,代表更暗一些还是更亮一些,当更暗的时候,黑色的程度越高;更亮一些就黑色成分少一些。

该图中旋转一圈的过程中代表了不同的颜色。对于饱和度来说,以中心点为基础,底下是黑色,上面是白色,中间是黑与白之间的灰。越靠近于圆柱边缘的地方,颜色的纯度越高。而对于纵轴,底下是黑色的,越往上越来越亮,这个就是明亮度。

对于OpenCV来说更喜欢使用HSV,使用HSV在背景判断上要好过RGB,因为在一个背景中可能有各种绿色,使用HSV就可以统一将背景判断为绿色,而使用RGB就不太好判断,每一种成分都有。

判断背景是通过色度来进行判断的,上图中0度就是纯红,60度就是黄色,120度为绿色,180度为青色,240度为蓝色,300度为粉红。这里是不考虑从圆心到边缘的渐变的一些因素的。

HSL

  1. Hue:色相,即色彩,如红色、蓝色
  2. Saturation:饱和度
  3. Ligthness:亮度

HSL与HSV看起来差不多,但存在着不同。

这里左图是HSL的,右图是HSV的,对于HSL到最顶成的时候就是纯白,无论色相是什么,饱和度是什么。而HSV就没有这么夸张。我们基本上使用的都是HSV,HSL几乎是不使用的。

YUV

YUV主要用在视频领域。Y代表的是灰色图像,UV代表的是颜色。YUV来自于电视节目,以前的电视只有黑白电视,就只有这个Y,后来有了彩色电视,但是要兼容黑白电视剧,当彩色电视机播放黑白电视剧的时候就只播放这个Y。一般的YUV包含YUV4:2:0、YUV4:2:2、YUV4:4:4。

YUV4:2:0

上图中,4个Y对应2个U或者V。不同的间隔,U或者V都是不一定的。

色彩空间转换

import cv2

def callback():
    pass

if __name__ == "__main__":

    cv2.namedWindow('color', cv2.WINDOW_NORMAL)
    img = cv2.imread("/Users/admin/Documents/111.jpeg")
    colorspaces = [cv2.COLOR_BGR2RGBA, cv2.COLOR_BGR2BGRA, cv2.COLOR_BGR2GRAY,
                   cv2.COLOR_BGR2HSV_FULL, cv2.COLOR_BGR2YUV]
    cv2.createTrackbar('curcolor', 'color', 0, len(colorspaces) - 1, callback)
    while True:
        index = cv2.getTrackbarPos('curcolor', 'color')
        # 颜色空间转换
        cvt_img = cv2.cvtColor(img, colorspaces[index])
        cv2.imshow('color', cvt_img)
        key = cv2.waitKey(10)
        if key & 0xFF == ord('q'):
            break
    cv2.destroyAllWindows()

运行结果

trackbar取值为0的时候

trackbar取值为1的时候

trackbar取值为2的时候

trackbar取值为3的时候

trackbar取值为4的时候

ROI(Region of Image)

  • 0
    感动
  • 0
    路过
  • 0
    高兴
  • 0
    难过
  • 0
    搞笑
  • 0
    无聊
  • 0
    愤怒
  • 0
    同情
热度排行
友情链接