Python 同时显示TkInter和OpenCV窗口

Python 同时显示TkInter和OpenCV窗口,python,opencv,tkinter,Python,Opencv,Tkinter,我正在努力扩展以前给我的这个 用户可以在TkInter画布小部件上使用鼠标随机绘制,然后在OpenCV窗口上绘制具有相同像素坐标的相同曲线 我想修改该解决方案,以便TkInter画布和OpenCV窗口必须同时显示:每次suer在TkInter上完成绘制一条曲线时,它都会立即在OpenCV窗口上重新绘制 有没有办法实现这个目标 提前感谢您的帮助。这可能比以后在OpenCV中绘制所有线条更容易 我会让MaClasse类只生成一个空白图像,打开一个窗口并在初始化时显示,然后给它一个方法来画一条线并再次

我正在努力扩展以前给我的这个

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

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

有没有办法实现这个目标


提前感谢您的帮助。

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

我会让MaClasse类只生成一个空白图像,打开一个窗口并在初始化时显示,然后给它一个方法来画一条线并再次显示图像。然后你可以在测试中创建一个MaClasse对象,每次在Tkinter中画一条线时都在OpenCV中画一条线。然后,您甚至不需要保存所绘制的所有线条,就可以完全删除self.liste

由于上面使用Tkinter窗口和OpenCV窗口的代码不适用于您,因此您也可以在Tkinter Toplevel窗口中显示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顶级窗口中显示OpenCV图像,让我试着做一个这样的例子。奇怪的是,我使用的OpenCV 3.0.0-rc与测试版和相同的Tkinter没有太大区别,也许它与操作系统有关?我在Windows7上。但我很高兴你也喜欢第二种方法。它显然更安全。
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()