问题
I am trying to draw text on Image where the user clicks. Getting this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/Users/Admin/PycharmProjects/ashish/td.py", line 35, in draw_text
cv2.putText(img, "OpenCV + Jurassic Park!!!", (event.x,event.y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
TypeError: Expected cv::UMat for argument 'img'
if __name__ == "__main__":
root = Tk()
frame = Frame(root, bd=2, relief=SUNKEN)
canvas = Canvas(frame, bd=0)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
frame.pack(fill=BOTH,expand=1)
#adding the image
File = filedialog.askopenfilename(parent=root, initialdir="F:/",title='Choose an image.')
img = ImageTk.PhotoImage(Image.open(File))
canvas.create_image(0,0,image=img,anchor="nw")
#function to be called when mouse is clicked
def draw_text(event):
cv2.putText(img, "OpenCV + Jurassic Park!!!", (event.x,event.y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
cv2.imshow("Text", img)
#mouseclick event
canvas.bind("<Button 1>",draw_text)
root.mainloop()
回答1:
Your img
is ImageTK
object from tkinter
but cv2
is not part of tkinter
and cv2.putText
doesn't work with ImageTK
. It needs something different. cv2
has own function to read image and it creates object which you can use with cv2.putText()
.
But canvas
has function to display text on top of image and you don't need cv2
. But it can't be saved in file as image with text.
But Image
has function to draw text on image and it can be saved in file.
So finally you don't need cv2
.
I use Image.Draw
to create object on which I can put text or draw line/square/etc.
After adding text I replace image on canvas.
This method create image with text which you can save in file (img.save()
)
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk, ImageDraw
# function to be called when mouse is clicked
def draw_text(event):
global imgtk
global cv_img
# create object for drawing
draw = ImageDraw.Draw(img)
# put text
draw.text((event.x,event.y), "ImageDraw + Jurassic Park!!!")
# replace old image
canvas.delete(cv_img_id)
imgtk = ImageTk.PhotoImage(img)
cv_img_id = canvas.create_image(0, 0, image=imgtk, anchor="nw")
if __name__ == "__main__":
root = Tk()
frame = Frame(root, bd=2, relief=SUNKEN)
frame.pack(fill=BOTH, expand=1)
canvas = Canvas(frame, bd=0)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
#adding the image
file = filedialog.askopenfilename(parent=root, initialdir="F:/",title='Choose an image.')
img = Image.open(file)
imgtk = ImageTk.PhotoImage(img)
cv_img_id = canvas.create_image(0, 0, image=imgtk, anchor="nw")
#mouseclick event
canvas.bind("<Button 1>", draw_text)
root.mainloop()
Using canvas.create_text
you can put text on top of image which you can move/remove later but it doesn't create image with text which you can save in file.
from tkinter import *
from tkinter import filedialog
from PIL import Image, ImageTk
# function to be called when mouse is clicked
def draw_text(event):
canvas.create_text((event.x,event.y), text="Canvas + Jurassic Park!!!")
if __name__ == "__main__":
root = Tk()
frame = Frame(root, bd=2, relief=SUNKEN)
frame.pack(fill=BOTH, expand=1)
canvas = Canvas(frame, bd=0)
canvas.grid(row=0, column=0, sticky=N+S+E+W)
#adding the image
file = filedialog.askopenfilename(parent=root, initialdir="F:/",title='Choose an image.')
imgtk = ImageTk.PhotoImage(Image.open(file))
canvas.create_image(0, 0, image=imgtk, anchor="nw")
#mouseclick event
canvas.bind("<Button 1>", draw_text)
root.mainloop()
来源:https://stackoverflow.com/questions/55548811/unable-to-write-text-on-mouseclick-area-on-image