读取cv.VideoCapture(0)的frame帧转变为PIL.Image图片格式时遇到的坑

def read_frame_from_video(video_path, image_path):
    video_capture = cv2.VideoCapture(video_path)
    images = []
    idx = 0
    while True:
        ret, frame = video_capture.read()
        if ret:
            idx = idx + 1
            image = Image.fromarray(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB))
            image_file=image_path+'/image_'+str(idx)+'.jpg'
            print(image_file)
            image.save(image_file)
        else:
            break

 

 

 

在项目中遇到一个问题是想将VideoCapture()读到的frame图片转变成PIL的Image图片格式。

坑1:BGR还是RGB模式?
兴冲冲地在在网上找到一段代码,将opencv中的imread()图像转成PIL.Image格式,详见python中PIL.Image和OpenCV图像格式相互转换

OpenCV转换成PIL.Image格式:

import cv2  
from PIL import Image  
import numpy  

img = cv2.imread("plane.jpg")  
cv2.imshow("OpenCV",img)  
image = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))  
image.show()  
cv2.waitKey()  

于是将image = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))复制了一遍,结果得到

open cv error: (-215) scn == 3 || scn == 4 in function cvtColor

的错误,参考了下stackflow上类似的回答发觉应该是颜色空间的问题——意思是原来的颜色空间和要改的颜色空间是一样的,比如原来是灰度空间,就不用再cv.COLOR_BGR2GRAY了,于是这才意识到有可能VideoCapture(0)和imread()得到的颜色空间是不同的。

其实VideoCapture()与imread()得到图像的颜色空间并不相同,VideoCapture得到的图片是RGB空间的,而imread得到的图片是BGR空间的,因此这里不需要cv2.cvtColor(imgmcv2.COLOR_BGR2RGB),直接image = Image.fromarray(frame)即可,frame是VideoCapture读到的帧,Image.fromarray()可以将np.array转成image格式的图像。

坑2 : type(frame)的结果是 ‘Nonetype’
上一步改完后image = Image.fromarray(frame)后还是会报错,我寻思是不是frame的格式还是有问题,结果测试得到opencv读取的帧是Nonetype摄像头也没有画面。

报的错是Image.fromarray(object)没有Nonetype这种格式,仔细想了想,以前久遇到过这种问题,就是opencv的VideoCapture没有读到帧的时候frame就会返回Nonetype,而ret返回的是False,所以在读取视频的循环中加一个条件判断语句即可,if ret ==True:的时候进行操作:

cap = cv2.VideoCapture(0)
while(1):
    ret,frame =cap.read()
    if ret==True:
        print (type(frame))
        print (ret)#观察frame和ret的类型

        img = Image.fromarray(frame)#完成np.array向PIL.Image格式的转换

        cv2.imshow("frame", frame)#正常显示frame
        cv2.waitKey(1)

后面得到的结果就是ret为True,frame的type()为np.array。

总结
其实出现这么多的坑就是因为对opencv读取图片的颜色空间和数据格式不清楚,他们里面有BGR和RGB颜色空间,而一般cv2.imread()读取的图片都是BGR颜色空间的图片,cv2.VideoCapture()获取的视频帧是RGB颜色空间的图片。PIL(Python Image Library)读取的图片是RGB颜色空间的。 
opencv读取的图片不管是视频帧还是图片都是矩阵形式,即np.array,转PIL.Image格式用PIL.Image.fromarray()函数即可。
--------------------- 
作者:黄辣鸡 
来源:CSDN 
原文:https://blog.csdn.net/weixin_39449466/article/details/80370832 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值