如何根据 tkinter 窗口调整来自 cv2 的视频流的大小

问题描述

这是一个代码,我只想在 Tkinter 标签显示来自摄像机的流。现在的问题是当有人尝试调整 Tkinter 窗口的大小时,流应该相应地调整大小以保持相同的纵横比。我尝试了一些调整,但没有奏效。下面是我的代码

root.bind( "<Configure>",resize )

width = cap. get(cv2. CAP_PROP_FRAME_WIDTH )
height = cap. get(cv2. CAP_PROP_FRAME_HEIGHT )
k = int(compute_hcf(int(width),int(height)))
w_ratio = width//k
h_ratio = height//k

def resize(event):
    h = root.winfo_height()
    w = root.winfo_width()
    k = min(h,w)
    print(k)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH,k//w_ratio)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT,k//h_ratio)

在尝试调整窗口大小时,这给了我以下错误

[ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (436) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB 终止异步回调

如果有人可以帮忙,谢谢。

解决方法

因此,在阅读您的代码后,您似乎试图创建一个为您调整大小的事件,使问题过于复杂。

所以我回到了基础,刚刚创建了一个网络摄像头流,只要您调整窗口大小,同时保持纵横比,它就会调整大小。

这是我找到并修改过的一些代码,它不使用 tkinter,但这并不重要,因为您可以将其合并到任何您认为合适的地方。

我遇到的唯一主要问题是,在调整大小时,您可能会发现您的窗口会冻结,但只有几秒钟,它会在一段时间后恢复,您实际上不会冻结图像,只是窗口控制。

您可能需要使用 python multithreading,我今晚可能会尝试这样做,因为我觉得这很有趣。

import cv2

def main():

    windowName = "Top"
    cv2.namedWindow(windowName)
    cap = cv2.VideoCapture(0)

    cap.set(3,650)
    cap.set(4,750)
    
    if cap.isOpened():
        ret,frame = cap.read()
    else:
        ret = False

    while ret:
        ret,frame = cap.read()
        cv2.imshow(windowName,frame)
        if cv2.waitKey(1) == 27:
            break

    cv2.destroyAllWindow()

    cap.release()   
if __name__== "__main__":

    main() 

但就实际功能而言,这将使您可以流式传输相机并调整窗口大小而不会被裁剪,保持相同的纵横比。

如果您有任何问题,请告诉我