【问题标题】:How to implement opencv selectROI in tkinter?如何在 tkinter 中实现 opencv selectROI?
【发布时间】:2021-11-16 19:12:15
【问题描述】:

我有一个图像,我想在 tkinter 中使用它,并使用 OpenCv 中的选择 ROI 函数和鼠标事件。我不知道如何解决这个问题,但我尽我所能,这是我的代码。 我的问题是我有错误说我在 (lbl tkimgis) 的变量没有定义。有没有其他方法可以实现这一目标或我可以做出改变的任何建议? 谢谢您的帮助。祝你有美好的一天!

from tkinter import *
import numpy as np
import cv2
import sys
import PIL.Image as imge
import PIL.ImageTk as imtk

ev = None

def click(event, u16):
    global subregion, tkimgis, ev
    if ev == None:
        ev = event
        return None
    bbox = cv2.selectROI("Image", u16, fromCenter=False)
    cv2.destroyWindow("Image")

    print("region:", bbox)
    ####Here u16 is my image array from another jupyter notebook cell

    tkimgis = imtk.PhotoImage(image=imge.fromarray(u16))
    lbl.config(image=tkimgis)
    (x,y,w,h) = bbox
    subregion = na[y:y+h, x:x+w]
    ev = event
root = Tk()
lbl = Label(root, image=tkimgis)
lbl.place(x=0, y=0)
root.bind('<Button-1>', lambda event: click(event))
root.mainloop()

【问题讨论】:

  • 我认为您发布的代码中存在缩进问题。
  • 您好,抱歉,我已经编辑了它

标签: python image opencv tkinter event-handling


【解决方案1】:

目前你的代码还有很多我觉得做得不对的地方,所以我提供一个代码供你仔细研究。

简而言之,你需要在不同的线程中运行cv2.selectROI,然后从主线程更新标签图像。

import tkinter as tk
import cv2
from PIL import Image, ImageTk
from threading import Thread


def display_roi(event):
    global tkimg

    if image:
        tkimg = ImageTk.PhotoImage(image)
        cropped_lbl.config(image=tkimg)

def select_roi():
    global image

    img = cv2.imread("sample.png")
    roi  = cv2.selectROI(img)

    imCrop = img[int(roi[1]):int(roi[1]+roi[3]), int(roi[0]):int(roi[0]+roi[2])]
    
    if len(imCrop)>0:
        image = Image.fromarray(cv2.cvtColor(imCrop, cv2.COLOR_BGR2RGB))

    cv2.destroyAllWindows()
    root.event_generate("<<ROISELECTED>>")

def start_thread():

    thread = Thread(target=select_roi, daemon=True)
    thread.start()


root = tk.Tk()

cropped_lbl = tk.Label(root)
cropped_lbl.pack(expand=True, fill="both")

tk.Button(root, text="select ROI", command=start_thread).pack()

root.bind("<<ROISELECTED>>", display_roi)
root.mainloop()

【讨论】:

  • 我希望这个 ROI 功能只提取 ROI 的坐标,如顶部(x,y)和底部(x,y),以便我可以使用它来绘制值。但我不明白你的代码我对 tkinter 和 python 都是新手,所以我的技能不是那么高。
  • @Blueman0002 这不是selectROI 返回的吗?所以你已经有了它,这里roi=cv2.selectROI(),roi 是你的 bbox。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 2011-11-30
  • 1970-01-01
  • 2021-11-01
  • 2014-07-02
  • 2015-10-09
相关资源
最近更新 更多