Python разделить изображение в перекрывающихся и вращающихся плитках - PullRequest
0 голосов
/ 02 июня 2019

Я делаю классификацию изображений.У меня очень несбалансированные данные.Я пробую пару подходов, чтобы преодолеть несбалансированную проблему данных.один из них - выборочный класс меньшинства.Изображения, которые у меня есть, уже имеют высокое разрешение (1392x1038), поэтому я делю их на плитки размером 348x256 размера 16.Как и в случае передискретизации, вы просто копируете классы меньшинства.Я думал о том, чтобы разбить изображение на перекрывающиеся плитки с шагом 1 или 2, так что у меня было бы несколько разных изображений, и это также помогло бы мне в передискретизации.Следующий код разбивает изображения на указанное количество перекрывающихся плиток определенного размера

for i in range(0, count):
        start_row_idx = random.randint(0, img_height-target_height-1)
        start_col_idx = random.randint(0, img_width-target_width-1)

        if mode == 'rgb':
            patch = img_array[start_row_idx:(start_row_idx+target_height), start_col_idx:(start_col_idx+target_width), :]
        else:
            patch = img_array[start_row_idx:(start_row_idx+target_height), start_col_idx:(start_col_idx+target_width)]
        patches.append(patch)
        idxs.append((start_row_idx, start_col_idx))

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

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

enter image description here

1 Ответ

1 голос
/ 02 июня 2019

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

После этого это просто вопрос применения аффинного преобразования, которое представляет собой просто поворот к плиткам, а затем добавление ксписок.Проблема с поворотом изображений в OpenCV заключается в том, что когда вы поворачиваете изображение, оно обрезается, поэтому вы не получаете всю плитку, содержащуюся в изображении, после поворота.

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

import cv2
import numpy as np

def rotate_about_center(src, angle):
    h, w = src.shape[:2]
    rangle = np.deg2rad(angle)  # angle in radians
    # now calculate new image width and height
    nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))
    nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))
    # ask OpenCV for the rotation matrix
    rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, 1)
    # calculate the move from the old centre to the new centre combined
    # with the rotation
    rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0]))
    # the move only affects the translation, so update the translation
    # part of the transform
    rot_mat[0,2] += rot_move[0]
    rot_mat[1,2] += rot_move[1]
    return cv2.warpAffine(src, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)

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

import random
max_angle = 20 # +/- 20 degrees maximum rotation
patches = []
idxs = []
for i in range(0, count):
    start_row_idx = random.randint(0, img_height-target_height-1)
    start_col_idx = random.randint(0, img_width-target_width-1)

    # Generate an angle between +/- max_angle
    angle = (2*max_angle)*random.random() - max_angle

    if mode == 'rgb':
        patch = img_array[start_row_idx:(start_row_idx+target_height), start_col_idx:(start_col_idx+target_width), :]
    else:
        patch = img_array[start_row_idx:(start_row_idx+target_height), start_col_idx:(start_col_idx+target_width)]

    # Randomly rotate the image
    patch_r = rotate_about_center(patch, angle)

    # Save it now
    patches.append(patch_r)
    idxs.append((start_row_idx, start_col_idx))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...