Tkinter窗口中cv2图像上的鼠标事件

2024-09-26 18:03:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个程序,它允许你自由裁剪一幅图像,同时向你展示结果图像。下面的代码实现了这一点

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)

我的挑战是将上述代码封装到一个接口中,如下所示:

enter image description here

到目前为止,我已经按照教程实现了类似的功能:

# 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中实现鼠标事件,因为该函数接受一个窗口名——但我只希望它应用于图像。我怎样才能做到这一点


Tags: andthetorectimageimportnoneimg
1条回答
网友
1楼 · 发布于 2024-09-26 18:03:21

与其将命令绑定到图像,不如将其绑定到包含图像的tk.标签:

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 provides a powerful mechanism to let you deal with events yourself. For each widget, you can bind Python functions and methods to events.

(...)

Events are given as strings, using a special event syntax:

相关问题 更多 >

    热门问题