Как рисовать свободные и горизонтальные линии, используя события мыши и флаги? - PullRequest
0 голосов
/ 08 марта 2020

Я пытаюсь построить код, в котором я могу рисовать линии над изображением, используя OpenCV. В моем коде я могу свободно рисовать линии, но я хочу рисовать горизонтальные линии, пока я нажимаю клавишу Shift. На самом деле, я не понял точную логику c из 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

1 Ответ

1 голос
/ 09 марта 2020

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)

Насколько я понимаю ваш вопрос, это то, что вы хотите достичь.

Надеюсь, что поможет!

...