创建显示窗口
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取不同的值会有不同的背景色
RGB人眼的色彩空间
每一个像素有三种颜色——红色、绿色和蓝色。通过不同光源的组合,形成真彩色,有暗的,有明亮的。
上图中每一个方格都代表一个像素。
OpenCV默认使用的是BGR,BGR跟RGB的区别就是排列顺序的不同。电脑上一般的排列顺序都是RGB。
HSV/HSB/HSL
HSV代表的是色相、饱和度、明亮度。HSB和HSV是一个意思。
该图中旋转一圈的过程中代表了不同的颜色。对于饱和度来说,以中心点为基础,底下是黑色,上面是白色,中间是黑与白之间的灰。越靠近于圆柱边缘的地方,颜色的纯度越高。而对于纵轴,底下是黑色的,越往上越来越亮,这个就是明亮度。
对于OpenCV来说更喜欢使用HSV,使用HSV在背景判断上要好过RGB,因为在一个背景中可能有各种绿色,使用HSV就可以统一将背景判断为绿色,而使用RGB就不太好判断,每一种成分都有。
判断背景是通过色度来进行判断的,上图中0度就是纯红,60度就是黄色,120度为绿色,180度为青色,240度为蓝色,300度为粉红。这里是不考虑从圆心到边缘的渐变的一些因素的。
HSL
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)
|