Arhn - архитектура программирования

Python OpenCV – нарисуйте правильный прямоугольник изменения размера

Я пробовал этот код, где у меня есть изображение, затем я могу нарисовать прямоугольник, когда я щелкаю и перетаскиваю мышь. В событии Mouse Down я отмечаю координаты x и y как начальный угол прямоугольника. При перемещении мыши я рисую прямоугольник из старых координат x и y, которые я сохранил, в новый, где находится мышь. Наконец, на Mouse Up я рисую прямоугольник как окончательный.

Вот код, который я использую:

import cv2
import numpy as np

drawing = False # True if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix, iy = -1, -1

# mouse callback function
def draw_circle(event, x, y, flags, param):
    global ix, iy, drawing, mode, overlay, output, alpha
    overlay = img.copy()
    output = img.copy()
    alpha = 0.5

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(overlay, (ix, iy), (x, y), (0, 255, 0), -1)
                cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, img)
                cv2.imshow('image', img)
            else:
                cv2.circle(overlay, (x,y),5,(0,0,255),-1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(overlay, (ix, iy), (x, y), (0, 255, 0), -1)
            cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, img)

        else:
            cv2.circle(overlay, (x, y), 5, (0, 0, 255), -1)


##img = np.zeros((512, 512, 3), np.uint8)
# Get our image
img = cv2.imread("bed_cv.jpg", 1)

#make cv2 windows, set mouse callback
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)

while(1):
    cv2.imshow('image', img)

    # This is where we get the keyboard input
    # Then check if it's "m" (if so, toggle the drawing mode)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break

cv2.destroyAllWindows()

Конечно, проблема здесь в том, что если я начну с центра, затем перетащу в правый нижний угол, а затем вернусь в левый нижний угол, первый прямоугольник не сотрется. Конечно, это происходит потому, что я на самом деле рисую прямоугольник на изображении, а не очищаю его, поэтому каждый прямоугольник, созданный в событии Mouse Move, рисуется.

Эффект, которого я хочу добиться, подобен тому, когда вы рисуете прямоугольник на рабочем столе, и вы можете менять направление, не создавая прямоугольник.

Мой вопрос: можно ли визуально нарисовать прямоугольник, но еще не записать его на изображение?

11.03.2017

  • См. здесь. Я обычно храню копию исходного изображения, изображение со всеми уже нарисованными прямоугольниками (копия слоя) и копию копии слоя, где я рисую частичный прямоугольник, который я создаю сейчас (рабочая копия), и рисую прямоугольник на только рабочая копия. На mouseUp я сохраняю рабочую копию как копию нового слоя. 11.03.2017
  • @Miki спасибо за подсказку! Мне удалось это сделать. Скоро выложу код. 11.03.2017
  • Альтернативным вариантом может быть использование некоторой обратимой операции. Если это схема, вы можете нарисовать ее с помощью операции XOR (хотя с OpenCV вам, вероятно, потребуется использовать для этого итератор строк). Для заполненного прямоугольника вы можете инвертировать область интереса. Конечно, это не будет выглядеть так же, но это подход, позволяющий избежать необходимости сохранять копию изображения. 11.03.2017

Ответы:


1

Идея заключалась в том, чтобы сделать копию изображения (в данном случае img2), а затем использовать ее в качестве вывода для наложений в событии Mouse Move. Затем используйте исходное изображение (в данном случае img) в событии нажатия кнопки:

import cv2
import numpy as np

drawing = False # True if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix, iy = -1, -1

# mouse callback function
def draw_circle(event, x, y, flags, param):
    global ix, iy, drawing, mode, overlay, output, alpha
    overlay = img.copy()
    output = img.copy()
    alpha = 0.5

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(overlay, (ix, iy), (x, y), (0, 255, 0), -1)
                cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, img2)
                cv2.imshow('image', img2)
            else:
                cv2.circle(overlay, (x,y),5,(0,0,255),-1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(overlay, (ix, iy), (x, y), (0, 255, 0), -1)
            cv2.addWeighted(overlay, alpha, output, 1 - alpha, 0, img)

        else:
            cv2.circle(overlay, (x, y), 5, (0, 0, 255), -1)


##img = np.zeros((512, 512, 3), np.uint8)
# Get our image
img = cv2.imread("bed_cv.jpg", 1)
img2 = img.copy()

#make cv2 windows, set mouse callback
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)

while(1):
    cv2.imshow('image', img2)

    # This is where we get the keyboard input
    # Then check if it's "m" (if so, toggle the drawing mode)
    k = cv2.waitKey(1) & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break

cv2.destroyAllWindows()
11.03.2017
Новые материалы

Коллекции публикаций по глубокому обучению
Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

Представляем: Pepita
Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

Советы по коду Laravel #2
1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

3 способа решить квадратное уравнение (3-й мой любимый) -
1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

Создание VR-миров с A-Frame
Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

Демистификация рекурсии
КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..