我尝试构建一个代码,在其中我可以使用OpenCV在图像上方绘制线条。在我的代码中,我可以自由绘制线条,但是我想在按下Shift键的同时绘制水平线条。实际上,我不了解flags
和鼠标event
的确切逻辑。请让我知道,如何修复我的代码。
import cv2
import numpy as np
cropping = False
x_start, y_start, x_end, y_end = 0, 0, 0, 0
image = cv2.imread("C:/Users/USER-PC/Documents/python/image/sunflower.jpg")
oriImage = image.copy()
def draw_line(event, x,y, flags, param):
global x_start, y_start, x_end, y_end, cropping
if event == cv2.EVENT_LBUTTONDOWN:
x_start, y_start, x_end, y_end = x,y,x,y
cropping = True
elif event == cv2.EVENT_MOUSEMOVE and flags != cv2.EVENT_FLAG_SHIFTKEY:
x_end, y_end = x,y
elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_SHIFTKEY:
x_end, y_end = x,y_start
elif event == cv2.EVENT_LBUTTONUP:
x_end, y_end = x,y
cropping = False
cv2.line(image, (x_start, y_start),(x_end, y_end), (255,0,0),2)
cv2.namedWindow("image")
cv2.setMouseCallback("image", draw_line)
while (1):
i = image.copy()
if not cropping:
cv2.imshow("image", image)
elif cropping:
cv2.line(i, (x_start, y_start),(x_end, y_end), (255,0,0),2)
# cv2.rectangle(i, (x_start, y_start), (x_end, y_end), (255,0,0), 2)
cv2.imshow("image", i)
if cv2.waitKey(1) & 0xFF ==27:
break
cv2.destroyAllWindows
flags
由几个位组成,请参见。 mouse event flags上的文档。对于这种情况,您要检测到,已激活EVENT_FLAG_LBUTTON
(值1
)和EVENT_FLAG_SHIFTKEY
(值16
),因此在这种情况下为flags = 17
。现在,检查flags == 17
可能是一个选项,但是专门检查EVENT_FLAG_SHIFTKEY
位是否已激活可能会有所帮助:
shift_pressed = (flags & cv2.EVENT_FLAG_SHIFTKEY) > 0
如果激活了True
,则返回EVENT_FLAG_SHIFTKEY
,否则返回False
。
然后可以通过以下方式修改您的draw_line
方法:
def draw_line(event, x,y, flags, param):
global x_start, y_start, x_end, y_end, cropping
shift_pressed = (flags & cv2.EVENT_FLAG_SHIFTKEY) > 0
if event == cv2.EVENT_LBUTTONDOWN:
x_start, y_start, x_end, y_end = x, y, x, y
cropping = True
elif event == cv2.EVENT_MOUSEMOVE and shift_pressed:
x_end, y_end = x, y_start
elif event == cv2.EVENT_MOUSEMOVE:
x_end, y_end = x, y
elif event == cv2.EVENT_LBUTTONUP:
x_end, y_end = x, y
cropping = False
cv2.line(image, (x_start, y_start), (x_end, y_end), (255, 0, 0), 2)
根据我对您问题的理解,这确实是您想要实现的目标。
希望有帮助!