簡體   English   中英

Tkinter window 中 cv2 圖像上的鼠標事件

[英]Mouse events on cv2 images in Tkinter window

我正在開發一個程序,該程序允許您自由裁剪圖像並同時向您顯示生成的圖像。 下面的代碼實現了這一點。

import numpy as np
import cv2

def crop(pts):
    global res
    pts = np.array(pts)

    mask = np.zeros((height, width), dtype=np.uint8)
    cv2.fillPoly(mask, [pts], (255))

    res = cv2.bitwise_and(img,img,mask = mask)

    rect = cv2.boundingRect(pts) # returns (x,y,w,h) of the rect
    cropped = res[rect[1]: rect[1] + rect[3], rect[0]: rect[0] + rect[2]]

    cv2.imshow('res', res)

def mouse_callback(event, x, y, flags, params):

    global selecting, pts, img

    if event == cv2.EVENT_LBUTTONDOWN:
        selecting = True
    elif event == cv2.EVENT_MOUSEMOVE:
        if selecting == True:
            pts.append((x, y))
            crop(pts)
            print((x,y))
    elif event == cv2.EVENT_LBUTTONUP:
        selecting = False

res = None

selecting = False
pts = []
img = cv2.imread("girl.png", -1)
height = img.shape[0]
width = img.shape[1]

cv2.namedWindow('image')
cv2.setMouseCallback('image', mouse_callback)

cv2.imshow('image', img)
cv2.waitKey(0)

cv2.imwrite("res.png", res)

我的挑戰是將上述代碼封裝到一個接口中,如下所示:

在此處輸入圖像描述

到目前為止,我已經按照教程來實現類似的目標:

# import the necessary packages
from tkinter import *
from PIL import Image
from PIL import ImageTk
from tkinter import filedialog as tkf
import cv2

def select_image():
    # grab a reference to the image panels
    global panelA, panelB
    # open a file chooser dialog and allow the user to select an input
    # image
    path = tkf.askopenfilename()

    # ensure a file path was selected
    if len(path) > 0:
        # load the image from disk, convert it to grayscale, and detect
        # edges in it
        image = cv2.imread(path)
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        edged = cv2.Canny(gray, 50, 100)
        # OpenCV represents images in BGR order; however PIL represents
        # images in RGB order, so we need to swap the channels
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        # convert the images to PIL format...
        image = Image.fromarray(image)
        edged = Image.fromarray(edged)
        # ...and then to ImageTk format
        image = ImageTk.PhotoImage(image)
        edged = ImageTk.PhotoImage(edged)

        # if the panels are None, initialize them
        if panelA is None or panelB is None:
            # the first panel will store our original image
            panelA = Label(image=image)
            panelA.image = image
            panelA.pack(side="left", padx=10, pady=10)
            # while the second panel will store the edge map
            panelB = Label(image=edged)
            panelB.image = edged
            panelB.pack(side="right", padx=10, pady=10)
        # otherwise, update the image panels
        else:
            # update the pannels
            panelA.configure(image=image)
            panelB.configure(image=edged)
            panelA.image = image
            panelB.image = edged

# initialize the window toolkit along with the two image panels
root = Tk()
panelA = None
panelB = None
# create a button, then when pressed, will trigger a file chooser
# dialog and allow the user to select an input image; then add the
# button the GUI
btn = Button(root, text="Select an image", command=select_image)
btn.pack(side="bottom", fill="both", expand="yes", padx="10", pady="10")
# kick off the GUI
root.mainloop()

我沒有設法完成的是在 tkinter 中實現鼠標事件,因為 function 采用 window 名稱 - 但我只希望它應用於圖像。 我怎樣才能做到這一點?

不要將命令綁定到圖像,而是將其綁定到包含圖像的 tk.Label:

import tkinter as tk
from PIL import Image
from PIL import ImageTk

root = tk.Tk()
ima = Image.open('test.png')
imag = ImageTk.PhotoImage(ima)
lab = tk.Label(root, image=imag)
lab.pack()
lab.bind('<Button-1>', *function)
root.mainloop()

解釋

Tkinter 提供了強大的機制讓您自己處理事件。 對於每個小部件,您可以Python 函數和方法綁定到事件。

(...)

事件以字符串形式給出,使用特殊的事件語法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM