在 Pygame 表面内显示 cv2.VideoCapture 图像 [英] display cv2.VideoCapture image inside Pygame surface

查看:150
本文介绍了在 Pygame 表面内显示 cv2.VideoCapture 图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆