Умное обрезание изображения

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

Мне нужно обрезать список графиков спектрограмм, как эти,

введите описание изображения здесь

В котором мне нужен только сам сюжет, и больше ничего. Просто сюжет.

В настоящее время я обрезаю это так.

print "Hstacked Image"
images1 = Image.open(spectogram_path_train+"/"+name+"_plot_static_conv.png")
images2 = Image.open(spectogram_path_train+"/"+name+"_plot_delta_conv.png")
images3 =      Image.open(spectogram_path_train+"/"+name+"_plot_delta_delta_conv.png")

box = (100,55,592,496)
cropped1  = images1.crop(box)
cropped2  = images2.crop(box)
cropped3  = images3.crop(box)

width1, height1 = cropped1.size
width2, height2 = cropped2.size
width3, height3 = cropped3.size

sum_width  = width1 + width2 + width3
max_height = max(height1,height2,height3)

new_im = Image.new('RGB',(sum_width,max_height))
x_offset = 0

for im in [cropped1,cropped2,cropped3]:
    new_im.paste(im,(x_offset,0))
    x_offset+=im.size[0]

new_im.save(spectogram_path_train+"/"+name+"_plot_hstacked.png")

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

Я ищу умный урожай, который способен убрать все, кроме цветного сюжета.

2 ответа

Решение

Итак... Я решил последовать предложению @martineau и создал решение, которое воспользовалось этим.

images1 = Image.open(static)
images2 = Image.open(delta)
images3 = Image.open(delta_delta)

data_numpy = np.array(images1)
number = 0
right = 0

for i in data_numpy[55,:]:
#    print i
    number+=1
    if i[0] == 234 and i[1] == 234 and i[2] == 242 and i[3] == 255 and number > 100:
#        print "Found it!"
        right = number
        break
    if i[0] == 255 and i[1] == 255 and i[2] == 255 and i[3] == 255 and number > 100:
        right = number
        break
#print right

box = (100,55,right,496)

cropped1  = images1.crop(box)
cropped2  = images2.crop(box)
cropped3  = images3.crop(box)

Я надеюсь, что код говорит сам за себя, если нет..

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

Я не знаю Python, но вы можете сделать это без языка высокого уровня в Терминале с ImageMagick, который установлен в большинстве дистрибутивов Linux и доступен для macOS и Windows.

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

Затем я отмечаю, что все, что вас интересует, это насыщенный цвет, а весь посторонний текст - черный / серый и ненасыщенный, поэтому я бы обратился к насыщенности, чтобы быть дискриминантом. Эта команда, введенная в Терминал, загружает ваше изображение и устанавливает все пиксели в черный цвет, т. Е. Ноль, где они ненасыщенные и сохраняют свои текущие значения везде. Затем он обрезает границы и сохраняет результат.

convert spectrum.png -alpha off -fx "saturation<0.2?0:u" -trim z.png

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

convert spectrum.png -alpha off -fx "saturation<0.2?0:u" -trim +repage -crop x1! txt: | awk -F, '/black/{print $1;exit}'

496

Итак, мне нужно обрезать столбец 496, что я делаю с:

convert spectrum.png -alpha off -fx "saturation<0.2?0:u" -trim +repage -crop 496x+0+0 z.png

Если бы я хотел автоматизировать весь процесс, я мог бы сделать:

x=$(convert spectrum.png -alpha off -fx "saturation<0.2?0:u" -trim +repage -crop x1! txt: | awk -F, '/black/{print $1;exit}')
convert spectrum.png -alpha off -fx "saturation<0.2?0:u" -trim +repage -crop ${x}x+0+0 y.png
Другие вопросы по тегам