Умное обрезание изображения
Я ищу метод, который я могу использовать для обрезки нескольких участков автоматически... без необходимости вручную устанавливать размер рамки обрезки.
Мне нужно обрезать список графиков спектрограмм, как эти,
В котором мне нужен только сам сюжет, и больше ничего. Просто сюжет.
В настоящее время я обрезаю это так.
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