события мыши на opencv - PullRequest
0 голосов
/ 18 мая 2018

Я пытаюсь написать функцию, которая откроет изображение и нарисует круг, в котором нажата левая кнопка мыши.затем размер круга можно отрегулировать с помощью колесика мыши / клавиатуры.Кроме того, каждый щелчок будет печатать метку в последовательности, например, 1-й круг ставит метку «1», 2-й нарисованный круг ставит метку «2» и так далее.Мне удалось получить круг и метку на изображении, но я не уверен , как увеличить радиус или , изменить метку различными щелчками .

import cv2
import numpy as np

# Create a black image and a window
windowName = 'Drawing'
img = cv2.imread('000025.png',cv2.IMREAD_COLOR)
cv2.namedWindow(windowName)








# mouse callback function
def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(img, (x,y), 30, (255, 0,), 1)
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img,'label' , (x + 30, y + 30), font, 1, (200, 255, 155), 1, cv2.LINE_AA)




# bind the callback function to window
cv2.setMouseCallback(windowName, draw_circle)


def main():
    while (True):
        cv2.imshow(windowName, img)
        if cv2.waitKey(20) == 27:
            break

    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Я думаю, что это может работать для вас:

import cv2
import numpy as np
import math


# mouse callback function
def draw_circle(event, x, y, flags, param):
    global x1, y1, radius, num
    if event == cv2.EVENT_LBUTTONDOWN:
        x1, y1 = x, y

    if event == cv2.EVENT_LBUTTONUP:
        num += 1
        radius = int(math.hypot(x - x1, y - y1))
        cv2.circle(img, (x1,y1), radius, (255, 0,), 1)

        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, f'label: {num}', (x + 30, y + 30), font, 1, (200, 255, 155), 1, cv2.LINE_AA)


if __name__ == "__main__":
    num = 0
    # Create a black image and a window
    windowName = 'Drawing'
    img = cv2.imread('img.jpg', cv2.IMREAD_COLOR)
    cv2.namedWindow(windowName)
    # bind the callback function to window
    cv2.setMouseCallback(windowName, draw_circle)
    while (True):
        cv2.imshow(windowName, img)
        if cv2.waitKey(20) == 27:
            break

    cv2.destroyAllWindows()

Результат: enter image description here

Это простой код, и вы можете сделать много вещейс событиями мыши.

0 голосов
/ 18 мая 2018

Используя следующий код, вы также можете визуализировать окружность, одновременно перемещая мышь.Я дополнил код, предоставленный Салманом, добавив еще одно условие, включающее событие MOUSEMOVE.

import cv2
import numpy as np
import math

drawing = False

def draw_circle(event, x, y, flags, param):
    global x1, y1, drawing, radius, num, img, img2
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        x1, y1 = x, y
        radius = int(math.hypot(x - x1, y - y1))
        cv2.circle(img, (x1,y1), radius, (255, 0, 0), 1)

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            a, b = x, y
            if a != x & b != y:
                img = img2.copy()
                radius = int(math.hypot(a - x1, b - y1))
                cv2.circle(img, (x1,y1), radius, (255, 0, 0), 1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        num += 1
        radius = int(math.hypot(x - x1, y - y1))
        cv2.circle(img, (x1,y1), radius, (255, 0, 255), 1)
        font = cv2.FONT_HERSHEY_SIMPLEX
        cv2.putText(img, '_'.join(['label', str(num)]), (x + 20, y + 20), font, 1, (200, 255, 155), 1, cv2.LINE_AA)
        img2 = img.copy()


if __name__ == "__main__":
    num = 0
    windowName = 'Drawing'

    img = np.zeros((500, 500, 3), np.uint8)
    img2 = img.copy()
    cv2.namedWindow(windowName)
    cv2.setMouseCallback(windowName, draw_circle)
    while (True):
        cv2.imshow(windowName, img)
        if cv2.waitKey(20) == 27:
            break

    cv2.destroyAllWindows()

Пример вывода:

enter image description here

0 голосов
/ 18 мая 2018

Сначала вы должны сохранить все координаты (или другие атрибуты) ваших объектов в глобальном динамическом объекте.

Вы должны дать руководство приложению, если вы рисуете круг, метку или другой рисунок.Это может быть сделано путем создания пунктов меню в окне OpenCV или нажатием клавиш (я сделал оба).Вы должны отслеживать контекст (следующий щелчок x, координаты y центра круга, точка в круге (для расчета радиуса, если вы не решите использовать для него mousewheel / kbd) левый угол прямоугольника и т. Д.

Вы должны сохранить созданные чертежи в указанном глобальном объекте.

Если вы хотите отредактировать / удалить существующий чертеж, вы должны создать функцию итератора, которая определяет ближайший чертеж (по его середине- или другой пункт) для правильного выбора.

Все вышеперечисленное выполнимо только в OpenCV.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...