Невозможно написать текст в области щелчка мышью на изображении - PullRequest
0 голосов
/ 06 апреля 2019

Я пытаюсь нарисовать текст на изображении там, где пользователь нажимает. Получение этой ошибки:

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 Ответ

0 голосов
/ 06 апреля 2019

Ваш img является ImageTK объектом из tkinter, но cv2 не является частью tkinter и cv2.putText не работает с ImageTK.Это нужно что-то другое.cv2 имеет собственную функцию для чтения изображения и создает объект, который вы можете использовать с cv2.putText().

Но canvas имеет функцию для отображения текста в верхней части изображения, и вам не нужно cv2.Но это не может быть сохранено в файле как изображение с текстом.

Но Image имеет функцию рисования текста на изображении, и его можно сохранить в файл.

Так, наконец, вам не нужно cv2.


Я использую Image.Draw, чтобы создать объект, на котором я могу поместить текст или нарисовать линию / квадрат / и т. Д.
После добавления текста я заменяю изображение на холсте.

Этот метод создает изображение с текстом, который вы можете сохранить в файле (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()

Используя canvas.create_text, вы можете поместить текст поверх изображения, которое вы можетепереместить / удалить позже, но это не создает изображение с текстом, который вы можете сохранить в файле.

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()
...