Matplotlib RectangleSelector продолжает сохранять старые значения - PullRequest
0 голосов
/ 13 октября 2019

Я пытаюсь создать ограничивающую рамку для изображений. Я хочу, чтобы инструмент сначала позволил мне нарисовать ограничивающий прямоугольник с помощью прямоугольного селектора, а затем после настройки ограничивающего прямоугольника. Если я нажму 'w', я хочу, чтобы координаты моей ограничительной рамки были сохранены в списке Python. Это мой код:

def line_select_callback(clk, rls):
    global tl_list
    global br_list
    global object_list
    global class_list
    plt.connect('key_press_event', set_class)    
    tx = int(clk.xdata)
    ty = int(clk.ydata)
    bx = int(rls.xdata)
    by = int(rls.ydata)

    plt.connect('key_press_event', lambda event: set_final(event, tx, ty, bx, by))


def toggle_selector(event):
    toggle_selector.RS.set_active(True)

def set_class(event):
    global clas

    if event.key == '1':
        clas = '0'
        print('class set to 0')
    elif event.key == '2':
        print('class set to 1')
        clas = '1'

def set_final(event, tx, ty, bx, by):
    global object_list
    global class_list

    if event.key == 'w':
        tl_list.append((tx, ty))
        br_list.append((bx, by))
        class_list.append(clas)

if __name__ == '__main__':
    print('Default class set to 0')
    for n, image_file in enumerate(os.scandir(image_folder)):
        img = image_file
        fig, ax = plt.subplots(1)
        image = cv2.imread(image_file.path)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        ax.imshow(image)

        toggle_selector.RS = RectangleSelector(ax, line_select_callback,
                                                drawtype='box', useblit=False,
                                                button=[1], minspanx=5, minspany=5,
                                                spancoords='pixels', interactive=True )

        bbox = plt.connect('key_press_event', toggle_selector)
        key = plt.connect('key_press_event', onkeypress)
        plt.show()

Проблема в том. Когда я сохраняю новые ограничивающие рамки, старые ящики также сохраняются. Допустим, я рисую 3 прямоугольника на изображении. Сохраненные координаты выглядят следующим образом:

{296,181,417,373,0} {235,178,447,370,0} {296,181,417,373,0} {235,178,447,370,0} {77,125,207,319,0} {296,181,417,373,0}

Первый ящик сохраняется 3 раза, второй ящик 2 раза и последний ящик 1 раз. Как это решить?

1 Ответ

0 голосов
/ 13 октября 2019

Нашел простой обходной путь. Когда вы закончите настройку ограничивающего прямоугольника, нажмите «n», чтобы сохранить текущий ограничивающий прямоугольник, и продолжайте рисовать новый ограничивающий прямоугольник на том же изображении. Когда вы закончите создавать ограничивающие рамки для изображения, нажмите «q», чтобы загрузить следующее изображение. Следующий код может быть изменен, чтобы сделать инструмент маркировки для таких проектов, как YOLO.

import os
import matplotlib.pyplot as plt
import cv2
from matplotlib.widgets import RectangleSelector
import matplotlib.patches as patches

Xs = []
Ys = []
breaker = False
tx=0
ty=0
bx=0
by=0

p_tx=0
p_ty=0
p_bx=0
p_by=0

# constants
image_folder = 'images'

def line_select_callback(clk, rls):
    global tx,ty,bx,by
    tx = int(clk.xdata)
    ty = int(clk.ydata)
    bx = int(rls.xdata)
    by = int(rls.ydata)


def onkeypress(event):
    global tx,ty,bx,by, Xs, Ys, p_tx, p_ty, p_bx, p_by
    if event.key == 'n':            
        if (p_tx != tx) or (p_ty != ty) or (p_bx != bx) or (p_by != by):
            Xs.append((tx, bx))
            Ys.append((ty, by))
            mystr=""
            mystr += " " + str(tx)+","+str(ty)+","+str(bx)+","+str(by)+" "
            print(mystr)
            p_tx=tx
            p_ty=ty
            p_bx=bx
            p_by=by
            plt.close()


def toggle_selector(event):
    toggle_selector.RS.set_active(True)

def break_loop(event):
    global breaker
    if event.key == 'q':
        breaker = True

if __name__ == '__main__':
    for n, image_file in enumerate(os.scandir(image_folder)):        
        while(True):
            img = image_file
            fig, ax = plt.subplots(1)
            image = cv2.imread(image_file.path)
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            ax.imshow(image)

            for i in range(len(Xs)):
                tl_x, br_x= Xs[i]
                tl_y , br_y = Ys[i]
                rect = patches.Rectangle((tl_x,tl_y), abs(br_x - tl_x), abs(tl_y - br_y),linewidth=1,edgecolor='r',facecolor='none')
                ax.add_patch(rect)

            toggle_selector.RS = RectangleSelector(ax, line_select_callback,
                                                    drawtype='box', useblit=False,
                                                    button=[1], minspanx=5, minspany=5,
                                                    spancoords='pixels', interactive=True)

            bbox = plt.connect('key_press_event', toggle_selector)
            plt.connect('key_press_event', onkeypress)
            loopBreaker = plt.connect('key_press_event', break_loop)
            if breaker:
                break
            plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...