同时显示TkInter和OpenCV窗口 [英] Displaying TkInter and OpenCV windows on the same time
问题描述
I am working to extend this solution given to me previously.
用户可以使用鼠标在TkInter Canvas小部件上随机绘制,然后在OpenCV窗口上绘制具有相同像素坐标的相同曲线.
The user can draw randomly using the mouse on a TkInter Canvas widget, after that, the same curves with the same pixels coordinates are drawn on the OpenCV window.
我想修改该解决方案,以便必须同时显示TkInter画布和OpenCV窗口:每次用户在TkInter上完成绘制一条曲线时,它都会立即在OpenCV窗口上重新绘制.
I want to modify that solution so that the TkInter Canvas and the OpenCV window must be shown in the same time: each time the suer finishes drawing one curve on TkInter it is immediately redrawn on the OpenCV window.
有没有办法实现这个目标?
Is there a way to fulfill this goal ?
在此先感谢您的帮助.
推荐答案
可以说,这比以后在OpenCV中绘制所有线要容易得多.
This is arguably even easier to do than to draw all lines in OpenCV later.
我将使MaClasse
类仅生成空白图像,打开一个窗口并在启动时显示它,并为其提供一种绘制单行并再次显示图像的方法,然后可以创建一个Test
中的>对象,并且每次在Tkinter中绘制一条线时都在OpenCV中绘制一条线.这样,您甚至不需要保存所有绘制的线条(可以完全删除self.liste
).
I'd make the MaClasse
class only make a blank image, open a window and show it on initiation, and give it a method to draw a single line and show the image again.Then you can create a MaClasse
object in Test
and draw a line in OpenCV each time you draw a line in Tkinter. Then you won't even need to save all lines you've drawn (you can completely remove 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图像.
Since the above code using a Tkinter window and a OpenCV window does not work for you, you could also show the OpenCV image in a Tkinter Toplevel window.
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()
这篇关于同时显示TkInter和OpenCV窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!