在 OpenCV 图像上绘制在 Tkinter Canvas 上绘制的相同线条
Draw same lines drawn on a Tkinter Canvas on an OpenCV image
使用鼠标,我让用户在 Tkinter 上绘制随机曲线 Canvas。这些曲线绘制为鼠标移动的点之间的短线。
我的目标是保存用于在 Canvas 上绘制线条的点,并在简单的 OpenCV window.
上使用相同的点绘制相同的曲线
Canvas 上的绘图工作完美,但是,无论我将 OpenCV window 放在何处,我都无法实现我的目标。我认为问题可能出在错误的函数调用顺序上?
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=[]
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
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.xold=event.x
self.yold=event.y
self.liste.append((self.xold,self.yold))
self.MC=MaClasse()
self.MC.dessiner_lignes()
self.MC.maclasse()
def get_points(self):
for i in range(len(self.liste)):
print self.liste[i]
return self.liste
class MaClasse:
def __init__(self):
self.s=600,600,3
self.les_points=[]# Empty list
self.ma=np.zeros(self.s,dtype=np.uint8)
def maclasse(self):
cv2.namedWindow("OpenCV",cv2.WINDOW_AUTOSIZE)
cv2.imshow("OpenCV",self.ma)
cv2.waitKey(0)
cv2.destroyAllWindows()
def dessiner_lignes(self):
self.voi=Test()
self.les_points=self.voi.get_points()
# It always displays 0
print "number of points: {}".format(len(self.les_points))
for i in range(len(self.les_points)):
print i
if i<len(self.les_points)-1:
print self.les_points[i]
self.first_point=self.les_points[i]
self.second_point=self.les_points[i+1]
cv2.line(self.ma,self.first_point,self.second_point,[255,255,255],2)
if __name__=="__main__":
root=Tk()
root.wm_title("Test")
v=Test()
v.test(root)
root.mainloop()
MC=MaClasse()
v.get_points() # I get the points here
您不应该在 Motion 事件期间创建一个 MaClasse
实例,因为这样您每次绘制一条新线时都会创建一个新的 MaClasse
。您只想创建一个 MaClasse
并将 Test
中的点数放入其中。因此,你完全可以把MaClasse
和Test
.
分开
您使用
获得积分
root = Tk()
v = Test()
v.test(root)
root.mainloop()
points = v.get_points()
这将设置 Test
应用程序,并在绘制完所有点后,使用 get_points()
获取点数。
然后,您可以设置一个 MaClasse
实例,但是您需要一种将点数传递给它的方法。最明智的方法(对我来说)似乎是将它们传递给 dessiner_lignes
函数,因为这样可以划清界线。如果您更改 dessiner_lignes
使其接受 les_points
变量 (def dessiner_lignes(self, les_points=[]):
),则您可以使用
绘制和显示图像
MC = MaClasse()
MC.dessiner_lignes(points)
MC.maclasse()
要分开单独绘制的曲线,您可以在释放鼠标按钮时放置一个(None, None)
"coordinate"(所以在b1up
中)。然后在 dessiner_lignes
中,在绘制线段之前检查两个坐标是否都不是 (None, None)
。
您的完整代码如下所示。请注意,我还从 les_points
中删除了 self
,dessiner_lignes
中的 first_point
和 second_point
因为它们仅在该方法中使用,所以没有必要将它们保存为 class 属性。
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=[]
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.xold=event.x
self.yold=event.y
self.liste.append((self.xold,self.yold))
def get_points(self):
#for i in range(len(self.liste)):
#print self.liste[i]
return self.liste
class MaClasse:
def __init__(self):
self.s=600,600,3
self.ma=np.zeros(self.s,dtype=np.uint8)
def maclasse(self):
cv2.namedWindow("OpenCV",cv2.WINDOW_AUTOSIZE)
cv2.imshow("OpenCV",self.ma)
cv2.waitKey(0)
cv2.destroyAllWindows()
def dessiner_lignes(self, les_points=[]):
print "number of points: {}".format(len(les_points))
for i in range(len(les_points)):
#print i
if i<len(les_points)-1:
#print les_points[i]
first_point=les_points[i]
second_point=les_points[i+1]
if not first_point == (None, None) and not second_point == (None, None):
cv2.line(self.ma,first_point,second_point,[255,255,255],2)
if __name__=="__main__":
root = Tk()
root.wm_title("Test")
v = Test()
v.test(root)
root.mainloop()
points = v.get_points()
MC = MaClasse()
MC.dessiner_lignes(points)
MC.maclasse()
使用鼠标,我让用户在 Tkinter 上绘制随机曲线 Canvas。这些曲线绘制为鼠标移动的点之间的短线。
我的目标是保存用于在 Canvas 上绘制线条的点,并在简单的 OpenCV window.
上使用相同的点绘制相同的曲线Canvas 上的绘图工作完美,但是,无论我将 OpenCV window 放在何处,我都无法实现我的目标。我认为问题可能出在错误的函数调用顺序上?
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=[]
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
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.xold=event.x
self.yold=event.y
self.liste.append((self.xold,self.yold))
self.MC=MaClasse()
self.MC.dessiner_lignes()
self.MC.maclasse()
def get_points(self):
for i in range(len(self.liste)):
print self.liste[i]
return self.liste
class MaClasse:
def __init__(self):
self.s=600,600,3
self.les_points=[]# Empty list
self.ma=np.zeros(self.s,dtype=np.uint8)
def maclasse(self):
cv2.namedWindow("OpenCV",cv2.WINDOW_AUTOSIZE)
cv2.imshow("OpenCV",self.ma)
cv2.waitKey(0)
cv2.destroyAllWindows()
def dessiner_lignes(self):
self.voi=Test()
self.les_points=self.voi.get_points()
# It always displays 0
print "number of points: {}".format(len(self.les_points))
for i in range(len(self.les_points)):
print i
if i<len(self.les_points)-1:
print self.les_points[i]
self.first_point=self.les_points[i]
self.second_point=self.les_points[i+1]
cv2.line(self.ma,self.first_point,self.second_point,[255,255,255],2)
if __name__=="__main__":
root=Tk()
root.wm_title("Test")
v=Test()
v.test(root)
root.mainloop()
MC=MaClasse()
v.get_points() # I get the points here
您不应该在 Motion 事件期间创建一个 MaClasse
实例,因为这样您每次绘制一条新线时都会创建一个新的 MaClasse
。您只想创建一个 MaClasse
并将 Test
中的点数放入其中。因此,你完全可以把MaClasse
和Test
.
您使用
获得积分root = Tk()
v = Test()
v.test(root)
root.mainloop()
points = v.get_points()
这将设置 Test
应用程序,并在绘制完所有点后,使用 get_points()
获取点数。
然后,您可以设置一个 MaClasse
实例,但是您需要一种将点数传递给它的方法。最明智的方法(对我来说)似乎是将它们传递给 dessiner_lignes
函数,因为这样可以划清界线。如果您更改 dessiner_lignes
使其接受 les_points
变量 (def dessiner_lignes(self, les_points=[]):
),则您可以使用
MC = MaClasse()
MC.dessiner_lignes(points)
MC.maclasse()
要分开单独绘制的曲线,您可以在释放鼠标按钮时放置一个(None, None)
"coordinate"(所以在b1up
中)。然后在 dessiner_lignes
中,在绘制线段之前检查两个坐标是否都不是 (None, None)
。
您的完整代码如下所示。请注意,我还从 les_points
中删除了 self
,dessiner_lignes
中的 first_point
和 second_point
因为它们仅在该方法中使用,所以没有必要将它们保存为 class 属性。
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=[]
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.xold=event.x
self.yold=event.y
self.liste.append((self.xold,self.yold))
def get_points(self):
#for i in range(len(self.liste)):
#print self.liste[i]
return self.liste
class MaClasse:
def __init__(self):
self.s=600,600,3
self.ma=np.zeros(self.s,dtype=np.uint8)
def maclasse(self):
cv2.namedWindow("OpenCV",cv2.WINDOW_AUTOSIZE)
cv2.imshow("OpenCV",self.ma)
cv2.waitKey(0)
cv2.destroyAllWindows()
def dessiner_lignes(self, les_points=[]):
print "number of points: {}".format(len(les_points))
for i in range(len(les_points)):
#print i
if i<len(les_points)-1:
#print les_points[i]
first_point=les_points[i]
second_point=les_points[i+1]
if not first_point == (None, None) and not second_point == (None, None):
cv2.line(self.ma,first_point,second_point,[255,255,255],2)
if __name__=="__main__":
root = Tk()
root.wm_title("Test")
v = Test()
v.test(root)
root.mainloop()
points = v.get_points()
MC = MaClasse()
MC.dessiner_lignes(points)
MC.maclasse()