在 Pygame 表面内显示 cv2.VideoCapture 图像 [英] display cv2.VideoCapture image inside Pygame surface
问题描述
我正在尝试使用 opencv (cv2) 将网络摄像头输入流传输到 pygame 表面对象中.问题是颜色显示不正确.我认为这是类型转换,但我无法理解 pygame 表面文档以了解它的期望.
I'm trying to use opencv (cv2) to stream a webcam feed into a pygame surface object. The problem is the colors aren't displaying correctly. I think it is the type casting, but I'm having trouble understanding the pygame surface documentation to know what it expects.
这段代码演示了我在说什么
This code demonstrates what I'm talking about
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 表面,以便我可以设置动画并覆盖倒计时文本、边框等.
The ultimate goal I have is to create a small photo booth application for a DIY wedding next year. I'm new to programming, but I've managed to cobble this together. I was also trying to accomplish this with VideoCapture, which outputs a PIL, which I also couldn't get to work with the surface object. I want to use a pygame surface so I can animate and overlay count-down text, borders, etc.
更新:问题是 cv2 函数 camera.read() 返回 BGR 图像,但 pygame.surfarray 需要 RGB 图像.这是固定的线
Update: The issue was that the cv2 function camera.read() returns a BGR image, but the pygame.surfarray expects a RGB image. This is fixed with the line
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
此外,当转换为灰度时,以下代码有效:
Also, when converting to grayscale, the following code works:
frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
frame=cv2.cvtColor(frame,cv2.COLOR_GRAY2RGB)
所以,函数 getCamFrame 现在应该是
So, the function getCamFrame should now be
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
推荐答案
我试过你的代码,但我只得到一张图片而不是电影,所以我复制了
I tried your code, but I'm only getting a picture not a movie, so i copied
frame=getCamFrame(color,camera)
screen=blitCamFrame(frame,screen)
pygame.display.flip()
进入 while 循环,它工作但随后视频被翻转,为了修复它,我添加了 cv2.flip(frame,1,frame) # 镜像图像
前frame=numpy.rot90(frame)
在 getcamFrame
函数中,现在一切正常.
into a while loop, it worked but then the video was flipped, to fix it i added cv2.flip(frame,1,frame) # mirror the image
before
frame=numpy.rot90(frame)
in getcamFrame
function and now everything works fine.
抱歉英语不好.
这篇关于在 Pygame 表面内显示 cv2.VideoCapture 图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!