Вывод геометрии декодирования при обнаружении текста EAST

Я пытаюсь использовать модель EAST в OpenCV для обнаружения текста на изображениях. Я успешно получаю результат после запуска изображения через сеть, но мне трудно понять, как работает функция декодирования, которую я использую. Я знаю, что я получаю 5 чисел на выходе из модели, и я думаю, что это расстояния от точки до верхней, нижней, левой и правой сторон прямоугольника, соответственно, и угол поворота в конце. Я не уверен, что делает функция декодирования, чтобы получить ограничивающую рамку для текстовой области.

Я знаю, почему смещение умножается на 4 (при прогоне модели оно уменьшается на 4). Я знаю, почему h и w такие, какие они есть. Я не уверен ни в чем после этого.

баллы — это баллы достоверности для каждого региона; геометрия — это значения геометрии для каждой области (пять чисел, которые я упомянул) scoreThresh — это просто порог для немаксимального подавления

def decode(scores, geometry, scoreThresh):
    detections = []
    confidences = []

    ############ CHECK DIMENSIONS AND SHAPES OF geometry AND scores ############
    assert len(scores.shape) == 4, "Incorrect dimensions of scores"
    assert len(geometry.shape) == 4, "Incorrect dimensions of geometry"
    assert scores.shape[0] == 1, "Invalid dimensions of scores"
    assert geometry.shape[0] == 1, "Invalid dimensions of geometry"
    assert scores.shape[1] == 1, "Invalid dimensions of scores"
    assert geometry.shape[1] == 5, "Invalid dimensions of geometry"
    assert scores.shape[2] == geometry.shape[2], "Invalid dimensions of scores and geometry"
    assert scores.shape[3] == geometry.shape[3], "Invalid dimensions of scores and geometry"
    height = scores.shape[2]
    width = scores.shape[3]
    for y in range(0, height):

        # Extract data from scores
        scoresData = scores[0][0][y]
        x0_data = geometry[0][0][y]
        x1_data = geometry[0][1][y]
        x2_data = geometry[0][2][y]
        x3_data = geometry[0][3][y]
        anglesData = geometry[0][4][y]
        for x in range(0, width):
            score = scoresData[x]

            # If score is lower than threshold score, move to next x
            if (score < scoreThresh):
                continue

            # Calculate offset
            offsetX = x * 4.0
            offsetY = y * 4.0
            angle = anglesData[x]

            # Calculate cos and sin of angle
            cosA = math.cos(angle)
            sinA = math.sin(angle)
            h = x0_data[x] + x2_data[x]
            w = x1_data[x] + x3_data[x]

            # Calculate offset
            offset = ([offsetX + cosA * x1_data[x] + sinA * x2_data[x], offsetY - sinA * x1_data[x] + cosA * x2_data[x]])

            # Find points for rectangle
            p1 = (-sinA * h + offset[0], -cosA * h + offset[1])
            p3 = (-cosA * w + offset[0],  sinA * w + offset[1])
            center = (0.5*(p1[0]+p3[0]), 0.5*(p1[1]+p3[1]))
            detections.append((center, (w,h), -1*angle * 180.0 / math.pi))
            confidences.append(float(score))

    # Return detections and confidences
    return [detections, confidences]

Итак, каков ваш точный вопрос?

HansHirse 09.04.2019 06:31

В основном, почему функция декодирования делает то, что делает?

user1845455 09.04.2019 10:52
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
2
2 044
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

бумага содержит диаграмму выходного формата. Вместо того, чтобы задавать поле обычным способом, оно указывается как набор расстояний (вверх, вправо, вниз и влево) от смещения (x, y), в дополнение к углу A, количество поворотов поля против часовой стрелки . image from Arxiv paper

Обратите внимание, что scores и geometry индексируются y, x, в отличие от любой логики ниже расчета offset. Поэтому, чтобы получить максимальные баллы за компоненты геометрии y, x:

high_scores_yx = np.where(scores[0][0] >= np.max(scores[0][0]))
y, x = high_scores_yx[0][0], high_scores_yx[1][0]
h_upper, w_right, h_lower, w_left, A = geometry[0,:,y,x]

Код использует offset для хранения смещения нижнего правого угла прямоугольника. Поскольку он находится в правом нижнем углу, ему нужны только w_right и h_lower, которые в коде обозначаются x1_data и x2_data соответственно.

box_diagram

Расположение правого нижнего угла относительно исходного смещения offsetX, offsetY зависит от угла поворота. Ниже пунктирные линии показывают ориентацию осей. Компоненты, которые нужно перейти от оригинала к нижнему смещению, помечены фиолетовым (по горизонтали) и фиолетовым (по вертикали). Обратите внимание, что компонент sin(A) * w_right равен вычтено, потому что y становится больше по мере опускания в этой системе координат.

rotation_diagram

Так что это объясняет

offset = ([offsetX + cosA * x1_data[x] + sinA * x2_data[x], offsetY - sinA * x1_data[x] + cosA * x2_data[x]])

Далее: p1 и p3 — левый нижний и правый верхний углы прямоугольника соответственно с учетом поворота. center — это просто среднее значение этих двух баллов.

Наконец, -1*angle * 180.0 / math.pi преобразует исходный угол в радианах против часовой стрелки в угол в градусах по часовой стрелке (поэтому окончательный выходной угол должен быть отрицательным для объектов, повернутых против часовой стрелки). Это сделано для совместимости с методом CV2 boxPoints, используемым в:

https://github.com/opencv/opencv/blob/7fb70e170154d064ef12d8fec61c0ae70812ce3d/samples/dnn/text_detection.py

Большое вам спасибо, я смог разобраться с некоторыми вещами самостоятельно, но был сбит с толку индексами y, x и знаками некоторых из этих косинусов и синусов. Это здорово!

user1845455 11.04.2019 00:00

Другие вопросы по теме