我怎样才能让这个程序自己触发 cv.waitKey() 以退出这个循环?
How can I get this program to trigger cv.waitKey() on its own in order to exit this loop?
问题:我希望代码在绘制矩形后退出循环,但它不起作用!我有一个循环 cv.waitKey() 等待按下。我怎样才能从一些外部发起者退出循环?顺便说一句,我正在构建别人的代码。
我尝试使用 pynput 但由于某种原因它无法正常工作...这是代码,一旦在图像上绘制了矩形,我想退出 while 循环。
import numpy as np
import cv2 as cv
from pynput.keyboard import Key, Controller
from time import sleep
class Interface:
def __init__(self, image):
self.ix = 0
self.iy = 0
self.ix2 = 0
self.iy2 = 0
self.drawing = False
self.before_rect = image.copy()
self.image = image.copy()
self.result_img = image.copy()
# Adding Function Attached To Mouse Callback
def draw(self,event,x,y,flags,params):
# Left Mouse Button Down Pressed
if(event==1):
self.drawing = True
self.ix = x
self.iy = y
# Moving mouse
if(event==0):
self.ix2 = x
self.iy2 = y
if self.drawing == True:
self.image = (self.before_rect).copy()
cv.rectangle(self.image, pt1=(self.ix, self.iy), pt2=(x, y), color=(255, 255, 255), thickness=3)
# Left Mouse Button Up
if(event==4):
if self.drawing == True:
self.ix2 = x
self.iy2 = y
# For Drawing Rectangle
cv.rectangle(self.result_img, pt1=(self.ix, self.iy), pt2=(x, y), color=(255, 255, 255), thickness=3)
self.image = (self.result_img).copy()
'''Here is the issue!!! How do I solve it?'''
# Doesn't do anything to exit the loop like I wanted :(
print('pressed') # (output to terminal) -> pressed
keyboard = Controller()
keyboard.press(Key.esc)
sleep(.01)
keyboard.release(Key.esc)
self.drawing = False
def get_boxes(self):
cv.namedWindow("Window")
# Adding Mouse CallBack Event
cv.setMouseCallback("Window", self.draw)
# Starting The Loop So Image Can Be Shown
while (True):
cv.imshow("Window", self.image)
if cv.waitKey(5) & 0xFF == 27:
break
cv.destroyAllWindows()
return
# Making The Blank Image
orig = np.zeros((512,512,3))
# Start drawing boxes!
obj = Interface(orig)
obj.get_boxes()
-它正在执行 pynput 按键(我知道,因为它会打印 'pressed'),但它不会对代码产生任何影响。伤心。
谢谢你的帮助! ~(^ \_`_/ ^)~
使用布尔标志
我认为使用 flags 更好,更符合 Pythonic,而不是通过键命令隐式地打破循环,即告诉你何时 运行 的布尔变量或打破循环。这对您来说特别容易,因为您正在使用实例化对象,即在其方法之间共享相同范围的实例(通过 self
参数)。
例如,在您的 __init__()
函数中,您可以初始化一个变量 self.loop_running = True
,它是在实例化时定义的。
随后,在您的 draw()
方法中,每当您想要触发循环中断时,将此标志设置为 False
,例如:
def drawing(*args):
# some code
if self.drawing:
self.ix2 = x
self.iy2 = y
# For Drawing Rectangle
cv.rectangle(self.result_img, pt1=(self.ix, self.iy), pt2=(x, y), color=(255, 255, 255), thickness=3)
self.image = (self.result_img).copy()
# set flag to false ->
self.loop_running = False
然后在调用主循环的最终函数中,将 while True
更改为 while self.loop_running
!:
def get_boxes(self):
cv.namedWindow("Window")
# Adding Mouse CallBack Event
cv.setMouseCallback("Window", self.draw)
# Starting The Loop So Image Can Be Shown
while self.loop_running:
cv.imshow("Window", self.image)
cv.destroyAllWindows()
return
问题:我希望代码在绘制矩形后退出循环,但它不起作用!我有一个循环 cv.waitKey() 等待按下。我怎样才能从一些外部发起者退出循环?顺便说一句,我正在构建别人的代码。
我尝试使用 pynput 但由于某种原因它无法正常工作...这是代码,一旦在图像上绘制了矩形,我想退出 while 循环。
import numpy as np
import cv2 as cv
from pynput.keyboard import Key, Controller
from time import sleep
class Interface:
def __init__(self, image):
self.ix = 0
self.iy = 0
self.ix2 = 0
self.iy2 = 0
self.drawing = False
self.before_rect = image.copy()
self.image = image.copy()
self.result_img = image.copy()
# Adding Function Attached To Mouse Callback
def draw(self,event,x,y,flags,params):
# Left Mouse Button Down Pressed
if(event==1):
self.drawing = True
self.ix = x
self.iy = y
# Moving mouse
if(event==0):
self.ix2 = x
self.iy2 = y
if self.drawing == True:
self.image = (self.before_rect).copy()
cv.rectangle(self.image, pt1=(self.ix, self.iy), pt2=(x, y), color=(255, 255, 255), thickness=3)
# Left Mouse Button Up
if(event==4):
if self.drawing == True:
self.ix2 = x
self.iy2 = y
# For Drawing Rectangle
cv.rectangle(self.result_img, pt1=(self.ix, self.iy), pt2=(x, y), color=(255, 255, 255), thickness=3)
self.image = (self.result_img).copy()
'''Here is the issue!!! How do I solve it?'''
# Doesn't do anything to exit the loop like I wanted :(
print('pressed') # (output to terminal) -> pressed
keyboard = Controller()
keyboard.press(Key.esc)
sleep(.01)
keyboard.release(Key.esc)
self.drawing = False
def get_boxes(self):
cv.namedWindow("Window")
# Adding Mouse CallBack Event
cv.setMouseCallback("Window", self.draw)
# Starting The Loop So Image Can Be Shown
while (True):
cv.imshow("Window", self.image)
if cv.waitKey(5) & 0xFF == 27:
break
cv.destroyAllWindows()
return
# Making The Blank Image
orig = np.zeros((512,512,3))
# Start drawing boxes!
obj = Interface(orig)
obj.get_boxes()
-它正在执行 pynput 按键(我知道,因为它会打印 'pressed'),但它不会对代码产生任何影响。伤心。
谢谢你的帮助! ~(^ \_`_/ ^)~
使用布尔标志
我认为使用 flags 更好,更符合 Pythonic,而不是通过键命令隐式地打破循环,即告诉你何时 运行 的布尔变量或打破循环。这对您来说特别容易,因为您正在使用实例化对象,即在其方法之间共享相同范围的实例(通过 self
参数)。
例如,在您的 __init__()
函数中,您可以初始化一个变量 self.loop_running = True
,它是在实例化时定义的。
随后,在您的 draw()
方法中,每当您想要触发循环中断时,将此标志设置为 False
,例如:
def drawing(*args):
# some code
if self.drawing:
self.ix2 = x
self.iy2 = y
# For Drawing Rectangle
cv.rectangle(self.result_img, pt1=(self.ix, self.iy), pt2=(x, y), color=(255, 255, 255), thickness=3)
self.image = (self.result_img).copy()
# set flag to false ->
self.loop_running = False
然后在调用主循环的最终函数中,将 while True
更改为 while self.loop_running
!:
def get_boxes(self):
cv.namedWindow("Window")
# Adding Mouse CallBack Event
cv.setMouseCallback("Window", self.draw)
# Starting The Loop So Image Can Be Shown
while self.loop_running:
cv.imshow("Window", self.image)
cv.destroyAllWindows()
return