【问题标题】:Converting cv2 images to PySDL2 surfaces for blitting to screen将 cv2 图像转换为 PySDL2 表面以进行位图传输到屏幕
【发布时间】:2019-08-21 23:33:55
【问题描述】:

我正在使用新的 PySDL2 包,试图将它与我现有的 OpenCV 代码接口。我想通过 cv2 python 接口从网络摄像头捕捉到 OpenCV 的图像,并使用 PySDL2 在屏幕上的窗口中显示它。我想我想出了如何正确地将 cv2 图像格式转换为 PySDL2 表面,但是在下面的代码末尾,我得到的只是一个黑色窗口。任何关于我出错的地方的指示将不胜感激!

#grab a frame from a webcam
import cv2
vc = cv2.VideoCapture(0)
junk,image = vc.read()

#convert image to sdl format (?)
import sdl2
sbuf = image.tostring()
simage = sdl2.SDL_CreateRGBSurfaceFrom(sbuf,image.shape[0],image.shape[1],24,3*image.shape[0],sdl2.SDL_PIXELFORMAT_BGRA8888,0xff0000, 0x00ff00, 0x0000ff, 0)

#create a window
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
windowSize = (640,480)
window = sdl2.SDL_CreateWindow(b"Hello World",sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED,windowSize[0], windowSize[1], sdl2.SDL_WINDOW_SHOWN)
windowSurface = sdl2.SDL_GetWindowSurface(window)

#try to blit the sdl-formatted image to the window
sdl2.SDL_BlitSurface(simage,None,windowSurface,None)
sdl2.SDL_UpdateWindowSurface(window)
sdl2.SDL_FreeSurface(simage)

# pump events to get the window to show and update
while True:
    sdl2.SDL_PumpEvents()

【问题讨论】:

    标签: python opencv sdl pysdl2


    【解决方案1】:

    解决了!

    #import necessary modules
    import cv2
    import sdl2
    import sdl2.ext
    import numpy
    
    windowSize = (640,480)
    
    #initialize the camera
    vc = cv2.VideoCapture(0)
    vc.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, windowSize[0])
    vc.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, windowSize[1])
    
    #grab and show a first frame from the camera
    junk,image = vc.read()
    cv2.imshow('0',image)
    
    #initialize sdl2
    sdl2.ext.init()
    window = sdl2.ext.Window("test", size=windowSize)
    window.show()
    windowSurf = sdl2.SDL_GetWindowSurface(window.window)
    windowArray = sdl2.ext.pixels3d(windowSurf.contents)
    
    while True: #keep reading to have a live feed from the cam
        junk,image = vc.read()
        image = numpy.insert(image,3,255,axis=2) #add alpha
        image = numpy.rot90(image) #rotate dims
        numpy.copyto(windowArray, image)
        window.refresh()
    

    我不知道为什么需要使用 cv2.imshow 显示来自相机的第一帧,但没有这部分,sdl2 窗口永远不会出现。

    【讨论】:

    • 您忘记每帧轮询事件,导致窗口无法出现。 for event in sdl2.ext.get_events(): if event.type == sdl2.SDL_QUIT: exit()
    【解决方案2】:

    这条线可以帮助你:

    windowArray[:,:,0:3] = img.swapaxes(0,1)


    #!python3
    import cv2
    import sdl2
    import sdl2.ext
    
    def process_frame(img):
        # --- initialize
        sdl2.ext.init()
        window = sdl2.ext.Window("sdl",size=('width','height'))
        window.show()
        events = sdl2.ext.get_events()
        for event in events:
            if event.type == sdl2.SDL_QUIT:
                exit(0)
        # --- initialize
        windowArray = sdl2.ext.pixels3d(window.get_surface()) 
    
        # --- convert cv2 frame to sdl windowArray
        windowArray[:,:,0:3] = img.swapaxes(0,1)
    
    
    vc = cv2.VideoCapture(0)     
    while vc.isOpened():
        ret,frame = cap.read()
        if ret == True:
            process_frame(frame)
        else:
            break
    

    【讨论】:

      【解决方案3】:

      我没有足够的声誉来添加评论,虽然它是很久以前的事了, 希望这可以帮助某人,

      您可以为创建窗口添加一个标志

      window = sdl2.ext.Window("test", size=windowSize, flag=sdl2.SDL_WINDOW_SHOWN)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-03
        • 2016-07-23
        • 2021-05-27
        相关资源
        最近更新 更多