【问题标题】:Displaying TkInter and OpenCV windows on the same time同时显示 TkInter 和 OpenCV 窗口
【发布时间】:2015-08-01 12:39:16
【问题描述】:

我正在努力扩展之前给我的solution

用户可以在 TkInter Canvas 小部件上使用鼠标随机绘制,然后在 OpenCV 窗口上绘制具有相同像素坐标的相同曲线。

我想修改该解决方案,以便 TkInter Canvas 和 OpenCV 窗口必须同时显示:每次用户在 TkInter 上完成绘制一条曲线时,它会立即在 OpenCV 窗口上重新绘制。

有没有办法实现这个目标?

提前感谢您的帮助。

【问题讨论】:

    标签: python opencv tkinter


    【解决方案1】:

    这可以说比以后在 OpenCV 中绘制所有线条更容易。

    我会让MaClasse类只制作一个空白图像,打开一个窗口并在启动时显示它,并给它一个方法来绘制一条线并再次显示图像。然后你可以创建一个@987654322 @Test 中的对象并在每次在 Tkinter 中绘制一条线时在 OpenCV 中绘制一条线。然后你甚至不需要保存你绘制的所有线条(你可以完全删除self.liste)。

    from Tkinter import *
    import numpy as np
    import cv2
    
    class Test:
        def __init__(self):
            self.b1="up"
            self.xold=None
            self.yold=None
            self.liste=[]
            self.maclasse = MaClasse()
        def test(self,obj):
            self.drawingArea=Canvas(obj)
            self.drawingArea.pack() 
            self.drawingArea.bind("<Motion>",self.motion)
            self.drawingArea.bind("<ButtonPress-1>",self.b1down)
            self.drawingArea.bind("<ButtonRelease-1>",self.b1up)
        def b1down(self,event):
            self.b1="down"
        def b1up(self,event):
            self.b1="up"
            self.xold=None
            self.yold=None
            self.liste.append((self.xold,self.yold))
        def motion(self,event):
            if self.b1=="down":
                if self.xold is not None and self.yold is not None:
                    event.widget.create_line(self.xold,self.yold,event.x,event.y,fill="red",width=3,smooth=TRUE)
                    self.maclasse.dessiner_ligne(self.xold,self.yold,event.x,event.y)
                self.xold=event.x
                self.yold=event.y
                self.liste.append((self.xold,self.yold))
    
    class MaClasse:
        def __init__(self):   
            self.s=600,600,3
            self.ma=np.zeros(self.s,dtype=np.uint8)
            cv2.namedWindow("OpenCV",cv2.WINDOW_AUTOSIZE)
            cv2.imshow("OpenCV",self.ma)
    
        def dessiner_ligne(self, xold, yold, x, y):
            cv2.line(self.ma,(xold, yold),(x,y),[255,255,255],2)
            cv2.imshow("OpenCV",self.ma)
    
    if __name__=="__main__":
        root = Tk()
        root.wm_title("Test")
        v = Test()
        v.test(root)
        root.mainloop()
    

    由于上面使用 Tkinter 窗口和 OpenCV 窗口的代码对您不起作用,您还可以在 Tkinter 顶层窗口中显示 OpenCV 图像。

    from Tkinter import *
    import numpy as np
    import cv2
    import Image, ImageTk
    
    class Test:
        def __init__(self, parent):
            self.parent = parent
            self.b1="up"
            self.xold=None
            self.yold=None
            self.liste=[]
            self.maclasse = MaClasse(self.parent)
        def test(self):
            self.drawingArea=Canvas(self.parent)
            self.drawingArea.pack() 
            self.drawingArea.bind("<Motion>",self.motion)
            self.drawingArea.bind("<ButtonPress-1>",self.b1down)
            self.drawingArea.bind("<ButtonRelease-1>",self.b1up)
        def b1down(self,event):
            self.b1="down"
        def b1up(self,event):
            self.b1="up"
            self.xold=None
            self.yold=None
            self.liste.append((self.xold,self.yold))
        def motion(self,event):
            if self.b1=="down":
                if self.xold is not None and self.yold is not None:
                    event.widget.create_line(self.xold,self.yold,event.x,event.y,fill="red",width=3,smooth=TRUE)
                    self.maclasse.dessiner_ligne(self.xold,self.yold,event.x,event.y)
                self.xold=event.x
                self.yold=event.y
                self.liste.append((self.xold,self.yold))
    
    class MaClasse:
        def __init__(self, parent):   
            self.s=600,600,3
            self.ma=np.zeros(self.s,dtype=np.uint8)
            self.top = Toplevel(parent)
            self.top.wm_title("OpenCV Image")
            self.label = Label(self.top)
            self.label.pack()
            self.show_image()
    
        def dessiner_ligne(self, xold, yold, x, y):
            cv2.line(self.ma,(xold, yold),(x,y),[255,255,255],2)
            self.show_image()
    
        def show_image(self):
            self.im = Image.fromarray(self.ma)
            self.imgtk = ImageTk.PhotoImage(image=self.im)
            self.label.config(image=self.imgtk)
    
    
    if __name__=="__main__":
        root = Tk()
        root.wm_title("Test")
        v = Test(root)
        v.test()
        root.mainloop()
    

    【讨论】:

    • 谢谢。但是从不显示 OpenCV 窗口(没有错误)。我尝试再次阅读您的代码
    • 这很奇怪,当你从字面上复制这段代码并运行它时,你看不到 OpenCV 窗口吗?
    • 我复制/粘贴你的代码是的。没有修改,只显示 TkInter 窗口。我认为它已显示但很快消失,因此人眼看不到它。我试图添加一个要等待的事件(cv2.waitKey()),但它阻止了我
    • 我不明白为什么它应该关闭。 cv2.waitkey 确实阻止了进一步的执行,所以你不应该使用它。不过,您可以尝试在 Tkinter Toplevel 窗口中显示 OpenCV 图像,让我尝试做一个示例。
    • 奇怪,我使用 OpenCV 3.0.0-rc(与测试版并没有太大区别)和相同的 Tkinter,也许它与操作系统相关?我在 Windows 7 上。但我很高兴你也喜欢第二种方法。这显然更安全。
    猜你喜欢
    • 2016-03-06
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多