【发布时间】:2015-08-01 12:39:16
【问题描述】:
我正在努力扩展之前给我的solution。
用户可以在 TkInter Canvas 小部件上使用鼠标随机绘制,然后在 OpenCV 窗口上绘制具有相同像素坐标的相同曲线。
我想修改该解决方案,以便 TkInter Canvas 和 OpenCV 窗口必须同时显示:每次用户在 TkInter 上完成绘制一条曲线时,它会立即在 OpenCV 窗口上重新绘制。
有没有办法实现这个目标?
提前感谢您的帮助。
【问题讨论】:
我正在努力扩展之前给我的solution。
用户可以在 TkInter Canvas 小部件上使用鼠标随机绘制,然后在 OpenCV 窗口上绘制具有相同像素坐标的相同曲线。
我想修改该解决方案,以便 TkInter Canvas 和 OpenCV 窗口必须同时显示:每次用户在 TkInter 上完成绘制一条曲线时,它会立即在 OpenCV 窗口上重新绘制。
有没有办法实现这个目标?
提前感谢您的帮助。
【问题讨论】:
这可以说比以后在 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()
【讨论】:
cv2.waitKey()),但它阻止了我
cv2.waitkey 确实阻止了进一步的执行,所以你不应该使用它。不过,您可以尝试在 Tkinter Toplevel 窗口中显示 OpenCV 图像,让我尝试做一个示例。
3.0.0-rc(与测试版并没有太大区别)和相同的 Tkinter,也许它与操作系统相关?我在 Windows 7 上。但我很高兴你也喜欢第二种方法。这显然更安全。