我正在使用Python 2.7和OpenCV 3.2开发Ubuntu 18.04。我的应用程序是视频管道的前端,需要从摄像头中提取视频帧,可能会对其进行裁剪和/或旋转(90、180、270度),然后将其分发给一个或多个其他代码段,以进行进一步处理处理。整个系统会尝试在每个步骤上最大化效率,例如,为以后增加功能(改进计算功率和带宽)而改进选项。
从功能上讲,我正在前端工作,但是我想通过处理从相机的MJPEG流中提取的JPEG帧来提高其效率。这将允许在JPEG域中进行高效,无损的裁剪和旋转,例如使用jpegtran-cffi,并分配小于相应解码帧的压缩帧。 JPEG解码将在必要时/在必要时以整体预期增益进行。另外一个好处是,这种方法可以有效保存网络摄像头视频,而不会由于解码+重新编码而损失图像质量。
我遇到的问题是OpenCV的VideoCapture类似乎不允许访问MJPEG流:
import cv2
cam = cv2.VideoCapture()
cam.open(0)
if not cam.isOpened():
print("Cannot open camera")
else:
enabled = True
while enabled:
enabled, frame = cam.read()
# do stuff
在这里,frame
始终采用分量(即已解码)格式。我看过使用cam.grab() + cam.retrieve()
而不是cam.read()
得到相同的结果(与OpenCV文档一致)。我也尝试过cam.set(cv2.CAP_PROP_CONVERT_RGB, False)
,但是只能将解码后的视频转换为RGB(如果它是另一种分量格式),并且不会阻止解码。顺便说一句,我验证了相机使用MJPEG编解码器(通过cam.get(cv2.CAP_PROP_FOURCC)
)。
所以我的问题是:我是否缺少某些东西,或者这种方法行不通?如果是后者,还有其他选择吗?
最后一点:应用程序必须能够在其功能范围内控制网络摄像头;例如,帧大小,帧速率,曝光,增益等等。cv2.VideoCapture很好地支持了这一点。
谢谢!
===
跟进:在没有我要寻找的解决方案的情况下,我添加了显式JPEG编码:
jpeg_frame = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), _JPEG_QUALITY])[1]
,其中_JPEG_QUALITY
设置为90(满分100)。虽然这增加了计算量并降低了图像质量,但从原则上讲都是多余的,但它使我可以进行权衡试验。 --KvZ