如何在 tkinter 中实现 opencv selectROI?
How to implement opencv selectROI in tkinter?
我有一张图像,我想在 tkinter 中使用它,并使用来自 OpenCv 的 select 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()
目前你的代码还有很多地方我觉得做的不对,所以我提供一个代码,你可以仔细研究一下。
总之需要在不同的线程运行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()
我有一张图像,我想在 tkinter 中使用它,并使用来自 OpenCv 的 select 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()
目前你的代码还有很多地方我觉得做的不对,所以我提供一个代码,你可以仔细研究一下。
总之需要在不同的线程运行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()