同时显示TkInter和OpenCV窗口

时间:2015-05-20 10:14:59

标签: python opencv tkinter

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

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

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

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

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

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

我要让MaClasse课只制作一张空白图像,打开一个窗口并在启动时显示它,然后给它一个方法来绘制一条线并再次显示图像。然后你可以在MaClasse中创建一个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 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()