控制流程 Python OpenCv:为什么 cv2.setMouseCallback 不在循环内?
Flow of Control Python OpenCv : Why cv2.setMouseCallback isn't inside loop?
我对以下程序中的控制流感到困惑。该代码的目的是在来自网络摄像头的实时视频流中绘制一个矩形。
工作原理:第一次点击会初始化矩形起始角的坐标,并用粗体圆圈标记。第二次单击将完成矩形。
现在我的问题是:为什么 cv2.setMouseCallback('Test',draw_rectangle) 语句不在循环内?
代码运行良好,但我无法理解控制流。请帮帮我。
import cv2
import os
os.environ["OPENCV_VIDEOIO_PRIORITY_MSMF"] = "0"
#CALLBACK FUNCTION RECTANGLE
def draw_rectangle(event,x,y,flags,param): #Param is the just the additional paramter which u can receive
global pt1, pt2, topLeft_Clicked, botRight_Clicked
if event ==cv2.EVENT_LBUTTONDOWN:
#Reset if rectangle is drawing i.e both var are true
if topLeft_Clicked and botRight_Clicked:
pt1=(0,0)
pt2=(0,0)
topLeft_Clicked=False
botRight_Clicked=False
if topLeft_Clicked == False:
pt1=(x,y)
topLeft_Clicked=True
elif botRight_Clicked == False:
pt2=(x,y)
botRight_Clicked=True
#GLOBAL VARIABLES
pt1=(0,0)
pt2=(0,0)
topLeft_Clicked= False
botRight_Clicked= False
#COnnect to the Callback
cap=cv2.VideoCapture(0)
cv2.namedWindow('Test')
cv2.setMouseCallback('Test',draw_rectangle)
while True:
ret,frame=cap.read()
#Drawing Based on Global Variables
if topLeft_Clicked: # If topleft is true
cv2.circle(frame,center=pt1,radius=5,color=(0,0,255),thickness=-1)
if topLeft_Clicked and botRight_Clicked:
cv2.rectangle(frame,pt1,pt2,(0,0,255),3)
cv2.imshow('Test',frame)
if(cv2.waitKey(1) & 0xFF==ord('q')):
break
cap.release()
cv2.destroyAllWindows()
回调是每次将鼠标移到显示上时调用的函数 window。它独立于 main 中的流程,即它在一个新线程中等待鼠标输入的变化。
之所以在main中使用loop是因为要更新显示的图像。调用imshow
后需要调用waitKey
影响渲染
事件调用回调函数。与常规函数不同,您不需要每次都调用函数 运行。
行 cv2.setMouseCallback('Test',draw_rectangle)
将函数 draw_rectangle
设置为对从 OpenCV window "Test"
上的鼠标接收到的任何事件的响应。设置回调后,在 while
循环内,您将在 "Test"
window.
上捕获所有鼠标事件
cv2.setMouseCallback('Test',draw_rectangle) 这个函数实际上是一个事件处理程序,它设置了在每次鼠标左键单击时调用 draw_rectangle 函数。 while 循环中的其余代码用于所有动态操作,最后 cv2.imshow 用于在图像中渲染它。
为了更好地处理 opencv closeWindows,仅关闭当前使用的 window 仅:
def showImage(imageName, image):
img = image.copy()
cv2.imshow(imageName, img)
while(1):
pressedKey = cv2.waitKey(0) & 0xFF
if(pressedKey == ord('q')):
cv2.destroyWindow(imageName)
break
else:
cv2.putText(img, "\press q to exit", (10,10), cv2.FONT_HERSHEY_SIMPLEX, 0.45, color=(255,0,0))
cv2.imshow(imageName, img)
我对以下程序中的控制流感到困惑。该代码的目的是在来自网络摄像头的实时视频流中绘制一个矩形。
工作原理:第一次点击会初始化矩形起始角的坐标,并用粗体圆圈标记。第二次单击将完成矩形。
现在我的问题是:为什么 cv2.setMouseCallback('Test',draw_rectangle) 语句不在循环内?
代码运行良好,但我无法理解控制流。请帮帮我。
import cv2
import os
os.environ["OPENCV_VIDEOIO_PRIORITY_MSMF"] = "0"
#CALLBACK FUNCTION RECTANGLE
def draw_rectangle(event,x,y,flags,param): #Param is the just the additional paramter which u can receive
global pt1, pt2, topLeft_Clicked, botRight_Clicked
if event ==cv2.EVENT_LBUTTONDOWN:
#Reset if rectangle is drawing i.e both var are true
if topLeft_Clicked and botRight_Clicked:
pt1=(0,0)
pt2=(0,0)
topLeft_Clicked=False
botRight_Clicked=False
if topLeft_Clicked == False:
pt1=(x,y)
topLeft_Clicked=True
elif botRight_Clicked == False:
pt2=(x,y)
botRight_Clicked=True
#GLOBAL VARIABLES
pt1=(0,0)
pt2=(0,0)
topLeft_Clicked= False
botRight_Clicked= False
#COnnect to the Callback
cap=cv2.VideoCapture(0)
cv2.namedWindow('Test')
cv2.setMouseCallback('Test',draw_rectangle)
while True:
ret,frame=cap.read()
#Drawing Based on Global Variables
if topLeft_Clicked: # If topleft is true
cv2.circle(frame,center=pt1,radius=5,color=(0,0,255),thickness=-1)
if topLeft_Clicked and botRight_Clicked:
cv2.rectangle(frame,pt1,pt2,(0,0,255),3)
cv2.imshow('Test',frame)
if(cv2.waitKey(1) & 0xFF==ord('q')):
break
cap.release()
cv2.destroyAllWindows()
回调是每次将鼠标移到显示上时调用的函数 window。它独立于 main 中的流程,即它在一个新线程中等待鼠标输入的变化。
之所以在main中使用loop是因为要更新显示的图像。调用imshow
后需要调用waitKey
影响渲染
事件调用回调函数。与常规函数不同,您不需要每次都调用函数 运行。
行 cv2.setMouseCallback('Test',draw_rectangle)
将函数 draw_rectangle
设置为对从 OpenCV window "Test"
上的鼠标接收到的任何事件的响应。设置回调后,在 while
循环内,您将在 "Test"
window.
cv2.setMouseCallback('Test',draw_rectangle) 这个函数实际上是一个事件处理程序,它设置了在每次鼠标左键单击时调用 draw_rectangle 函数。 while 循环中的其余代码用于所有动态操作,最后 cv2.imshow 用于在图像中渲染它。
为了更好地处理 opencv closeWindows,仅关闭当前使用的 window 仅:
def showImage(imageName, image):
img = image.copy()
cv2.imshow(imageName, img)
while(1):
pressedKey = cv2.waitKey(0) & 0xFF
if(pressedKey == ord('q')):
cv2.destroyWindow(imageName)
break
else:
cv2.putText(img, "\press q to exit", (10,10), cv2.FONT_HERSHEY_SIMPLEX, 0.45, color=(255,0,0))
cv2.imshow(imageName, img)