我只是一名搬砖工,无意侵犯各位大佬知识产权。
最近因项目组需要,开始学 图像处理
所以记录一下这个过程以及经验,希望能帮到大家学习参考资料:
《图像处理的数学修养》 github 上的 OpenCV-Python-Tutorial 若想系统地学习,麻烦移步到 github或买书啃一下
这部分主要讲两个函数
cv2.VideoCapture 创建视频对象,负责获取视频内容 cv2.VideoWriter() 创建视频写入对象,用来录制/保存视频 cv2.cvtColor() 将 BGR 彩色图片转为 灰度图片 imwrite() 保存图片 cv2.VideoCapture().isOpened() 检测视频读取状态是否正常 cv2.VideoCapture().read() 获取视频某一帧,返回两个值,第一个是布尔值,表示“这一帧”是否获取正确;第二个值是这一帧的内容,是一个矩阵。 接下来看例子
cv2.VideoCapture()
如果传的参数是数字,表示使用摄像头。如 cv2.VideoCapture(0),表示使用计算机第一个摄像头。 如果传的是一个视频的地址,则表示读取本地视频。这里我只用第二种,给一个视频的绝对路径并读取它 比如:我希望读取一个视频,截取每一帧图像并将其转为灰度图像,并播放
import cv2 capture = cv2.VideoCapture('/Users/0.mp4') ##假设我有个视频放在(/Users/ 目录下,我是 mac 玩家,win 玩家自行修改) while(capture.isOpened()): ## 检测视频打开是否有问题 ret,frame = capture.read() ## 逐帧读取视频 gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) ## 灰度转换 cv2.imshow('frame', gray) ## (播放)看图 if cv2.waitKey(30) == ord('q'): ## 控制退出,选中窗口按'q' (大写不行) break capture.release() ## 清内存,好习惯 cv2.destroyAllWindows() ## 后面这两句不写,看图的窗口就关不了 cv2.waitKey(1) ### 为了上面好看点,我把注释写在下面了 ### capture.isOpened()返回的是布尔值,如果成功读取这一帧,则为 True; 反之为 False ### ret 其实就是capture.isOpened(), 而 frame 这是获取的这一帧图像的内容,是矩阵格式 ### cv2.cvtColor() 将 BGR 彩色图片转为 灰度图片 ### cv2.imshow() 第一个参数是打开播放图像窗口的名字,自己随便命名;第二个参数是要看的图像名称,就是 gray ### cv2.waitKey(),它的参数表示暂停时间,所以这个值越大,视频播放速度越慢,反之,播放速度越快,通常设置为25或30。 ord 是转码,因为 opencv 内核是 C++,用的是 ASCⅡ (我不知道这里说的对不对)
如果我想截取某个时间点的图片。
首先我们得知道,视频中的每一帧对应多少时间, 通过使用的函数capture.get(propId),可以获取视频(/摄像头的一些属性),如 分辨率、亮度、对比度等,我们想知道的帧速度也在这里 传入的参数是数字或关键词都可以。propId是从0~18的数字,代表不同的属性,完整的属性列表可以参考: VideoCaptureProperties 。 如果想修改视频的属性,可以用 capture.set(propId,value)来修改属性值 capture = cv2.VideoCapture('/Users/0.mp4') timepoint = 10 ###(单位:秒) 想截取视频中 10s 那一帧 timer = 0 ### 用来计算帧数, fps = round(capture.get(5)) ### 1 秒有多少帧, 使用的参数是5,表示帧速 (要用怎么自己查表) ### 一般来说,1 秒 约等于 24 帧,我这个视频是 23.976023976023978, 所以直接用round(), 四舍五入,将其约等于 24. while(capture.isOpened()): ## 检测视频打开是否有问题 timer += 1 ## 开始计算过去了多少帧 ret,frame = capture.read() ## 逐帧读取视频 if timer == timepoint * fps: ## 10秒的时候,开始截图 cv2.imwrite('/Users/10s.jpg',frame) ## 存图,第一个参数递质,第二个要存的图是哪个 break ## 退出 capture.release() ## 清内存,好习惯如果我看视频看到某一帧想截图 (这个更简答了是不是,和第一个很像)
我们来个暗号,比如 按下键盘 ‘s’ 就截图
import cv2 capture = cv2.VideoCapture('/Users/0.mp4') while(capture.isOpened()): ## 检测视频打开是否有问题 ret,frame = capture.read() ## 逐帧读取视频 gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) ## 灰度转换 cv2.imshow('frame', gray) ## (播放)看图 if cv2.waitKey(30) == ord('s'): ## 控制退出,选中窗口按'q' (大写不行) cv2.imwrite('/Users/10s.jpg',frame) ### 其实就多了这个 break capture.release() ## 清内存,好习惯 cv2.destroyAllWindows() ## 后面这两句不写,看图的窗口就关不了 cv2.waitKey(1)
如果我觉得截图不过瘾,想截一段动画(gif) 或 截一段视频
这次要加上存视频的函数 cv2.VideoWriter()
思路还是一样,假设我们想截 第 5 秒到第 10 秒的视频cv2.VideoWriter()
先说说这个函数,它需要四个参数
cv2.VideoWriter(filename, fourcc, fps, resolution)第一个参数 是文件名,如‘output.avi’ (绝对路径,你保存文件的位置) 第二个参数 是编码方式,这里选的是 FourCC码 (我也没搞懂,反正先用着吧) 第三个参数是帧率 FPS (又叫帧速),一般和原视频一样,24,有兴趣的可以试试更大或更小的数字,发现新世界 第四个是分辨率 (每英寸像素Pixel per inch, ppi) 480P: 720×480 (宽 × 高 720p: 1280×720 1080p: 1920×1080 可以试试原画是 480P 转 1080P 输出会变什么样子 (查原视频分辨率用 .get(3) 宽,.get(4) 高 还有一个FourCC是用来指定视频编码方式的四字节码,所有的编码可参考 Video Codecs 。如MJPG编码可以这样写: cv2.VideoWriter_fourcc(*’MJPG’)或cv2.VideoWriter_fourcc(‘M’,’J’,’P’,’G’)
(这个我也不懂,先用着吧)那开始干吧
import cv2 capture = cv2.VideoCapture('/Users/test.mp4') time1 = 5 ###(单位:秒) 截取开始时间 第5秒 time2 = 10 ###(单位:秒) 截取结束时间 第10秒 timer = 0 ### 用来计算帧数, fps = round(capture.get(5)) ### 获取 1 秒有多少帧 ### 定义编码方式并创建VideoWriter对象 fourcc = cv2.VideoWriter_fourcc(*'MJPG') outfile = cv2.VideoWriter('/Users/test_5s.avi',fourcc, 24, (640, 360)) ###我这边测试视频 帧频是24,分辨率是640×360, 可以分别用.get(5), .get(3)和.get(4)获取, 当然你也可以改动一下试试看什么效果 while(capture.isOpened()): ## 检测视频打开是否有问题 timer += 1 ## 开始计算过去了多少帧 ret,frame = capture.read() ## 逐帧读取视频 if time1 * fps >= timer: ## 小于 5 秒时,跳过 (为什么要? 因为没有这个会直接跳到 else,break 就结束了) elif time1 * fps < timer and timer < time2 * fps: ## 大于 5 秒,小于 10 秒时,开始截视频 outfile.write(frame) ## outfile 就是创建VideoWriter对象 else: ## 大于 10 秒的时候,停止 print('finished') break ## 退出 capture.release() ## 清内存,好习惯
OK 啦,是不是很简单,快来试试吧