我正在尝试使用opencv(cv2)将网络摄像头源流式传输到pygame表面对象中。问题是颜色没有正确显示。我认为这是类型转换,但我无法理解pygame表面文档以了解它的期望。
此代码演示了我正在谈论的内容
import pygame
from pygame.locals import *
import cv2
import numpy
color=False#True#False
camera_index = 0
camera=cv2.VideoCapture(camera_index)
camera.set(3,640)
camera.set(4,480)
#This shows an image the way it should be
cv2.namedWindow("w1",cv2.CV_WINDOW_AUTOSIZE)
retval,frame=camera.read()
if not color:
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
cv2.flip(frame,1,frame)#mirror the image
cv2.imshow("w1",frame)
#This shows an image weirdly...
screen_width, screen_height = 640, 480
screen=pygame.display.set_mode((screen_width,screen_height))
def getCamFrame(color,camera):
retval,frame=camera.read()
if not color:
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
frame=numpy.rot90(frame)
frame=pygame.surfarray.make_surface(frame) #I think the color error lies in this line?
return frame
def blitCamFrame(frame,screen):
screen.blit(frame,(0,0))
return screen
screen.fill(0) #set pygame screen to black
frame=getCamFrame(color,camera)
screen=blitCamFrame(frame,screen)
pygame.display.flip()
running=True
while running:
for event in pygame.event.get(): #process events since last loop cycle
if event.type == KEYDOWN:
running=False
pygame.quit()
cv2.destroyAllWindows()
我的最终目标是为明年的DIY婚礼创建一个小型照相亭应用程序。我是编程新手,但我已经设法将它拼凑在一起。我也试图用VideoCapture来完成这个,它输出一个PIL,我也无法使用表面对象。我想使用pygame表面,以便我可以设置动画并叠加倒计时文本,边框等。
更新:问题是cv2函数camera.read()返回BGR图像,但pygame.surfarray需要RGB图像。这是用行
修复的frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
此外,转换为灰度时,以下代码有效:
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
frame=cv2.cvtColor(frame,cv2.COLOR_GRAY2RGB)
因此,函数getCamFrame现在应该是
def getCamFrame(color,camera):
retval,frame=camera.read()
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
if not color:
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
frame=cv2.cvtColor(frame,cv2.COLOR_GRAY2RGB)
frame=numpy.rot90(frame)
frame=pygame.surfarray.make_surface(frame)
return frame
答案 0 :(得分:1)
这里没有颜色错误
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
因此,对于正常的屏幕颜色,您只需将其更改为
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
这样做会因为它对我有用
答案 1 :(得分:1)
我尝试了你的代码,但我只是拍照而不是电影,所以我复制了
frame=getCamFrame(color,camera)
screen=blitCamFrame(frame,screen)
pygame.display.flip()
进入while循环,它工作但是视频被翻转,修复它我添加了cv2.flip(frame,1,frame) # mirror the image
之前
frame=numpy.rot90(frame)
函数中getcamFrame
,现在一切正常。
抱歉英语不好。
答案 2 :(得分:0)
这对我有用
在您的代码中对其进行调整...
windowSurface = screen #or use directly variable screen
# convert windowSurface to cv2 ------------------------------------
view = pygame.surfarray.array3d(windowSurface)
# convert from (width, height, channel) to (height, width, channel)
view = view.transpose([1, 0, 2])
# convert from rgb to bgr
img_bgr = cv2.cvtColor(view, cv2.COLOR_RGB2BGR)
cv2.imshow('windowname',img_bgr)
cv2.waitKey(10)