Вам НЕ нужен subimage-search для достижения вашей цели. Проблема может быть сведена к разбору текста.
1. Основы
Учтите следующее: вы можете указать ImageMagick преобразовать любое изображение в текстовое представление, которое содержит точную информацию о цвете для каждого отдельного пикселя. Пример:
convert wizard: textwizard.txt
(wizard:
— это встроенный образ, доступный для всех установок ImageMagick в целях тестирования.)
Да, это так просто! Этот «формат» изображения запрашивается простым добавлением суффикса .txt
. Результаты:
# ImageMagick pixel enumeration: 480,640,255,srgb
0,0: (255,255,255) #FFFFFF white
1,0: (255,255,255) #FFFFFF white
2,0: (255,255,255) #FFFFFF white
[....]
47,638: (246,247,249) #F6F7F9 srgb(246,247,249)
48,638: (246,247,249) #F6F7F9 srgb(246,247,249)
47,639: (236,235,236) #ECEBEC srgb(236,235,236)
48,639: (230,228,218) #E6E4DA srgb(230,228,218)
[....]
476,639: (255,255,255) #FFFFFF white
477,639: (255,255,255) #FFFFFF white
478,639: (255,255,255) #FFFFFF white
479,639: (255,255,255) #FFFFFF white
Если вы посмотрите на первую строку вывода, вы заметите, что ImageMagick использует ее для детализации некоторой специальной информации об изображении:
# ImageMagick pixel enumeration: 480,640,255,srgb
Это означает:
- изображение имеет ширину 480 пикселей,
- изображение имеет высоту 640 пикселей,
- изображение использует диапазон 0-255 для информации о цвете на канал (что эквивалентно 8-битной глубине цвета),
- изображение построено в цветовом пространстве sRGB
Остальные строки состоят из 4 столбцов:
- первый столбец в формате
(N,M)
указывает точное положение соответствующих пикселей как (row_number,column_number)
. (Индекс для номеров строк и столбцов начинается с нуля: строка № 1 обозначается как 0
, № 2 — как 1
.)
- остальные три столбца, избыточно, содержат одну и ту же информацию, каждый в другой нотации: точное значение цвета для пикселя, указанное в столбце 1. (Последний столбец будет использовать удобочитаемое имя, если ImageMagick знает его для этого значения цвета...)
В качестве примечания: вы можете использовать такое текстовое представление исходного изображения (с некоторыми дополнительными модификациями или без них), чтобы воссоздать реальное изображение:
convert textwizard.txt wizard.jpg
2. Выберите конкретную строку
Вы должны знать, что вы можете выбрать определенную область изображения с помощью следующего синтаксиса:
image.png[WIDTHxHEIGHT+X_OFFSET+Y_OFFSET]
Таким образом, чтобы выбрать только определенную строку, вы можете установить HEIGHT
как 1
. Чтобы получить любую строку полностью, установите X-OFFSET
как 0
. Чтобы получить конкретную строку, установите Y-OFFSET
соответственно.
Чтобы получить значения (для встроенного изображения wizard:
, использованного выше) для строки с индексом 47, мы можем сделать:
convert wizard:[640x1+0+47] row47.txt
cat row47.txt
# ImageMagick pixel enumeration: 480,1,255,srgb
0,0: (255,255,255) #FFFFFF white
1,0: (255,255,255) #FFFFFF white
2,0: (255,255,255) #FFFFFF white
[....]
428,0: (82,77,74) #524D4A srgb(82,77,74)
429,0: (169,167,168) #A9A7A8 srgb(169,167,168)
430,0: (232,231,228) #E8E7E4 srgb(232,231,228)
432,0: (246,247,249) #F6F7F9 srgb(246,247,249)
[....]
476,0: (255,255,255) #FFFFFF white
477,0: (255,255,255) #FFFFFF white
478,0: (255,255,255) #FFFFFF white
479,0: (255,255,255) #FFFFFF white
Если вы не хотите, чтобы текст выводился в файл, а печатался на стандартном канале вывода, вы можете сделать это:
convert wizard:[480x1+0+47] txt:-
3. Сшиваем все вместе
Основываясь на приведенных выше фрагментах информации, подход, который можно использовать для этой задачи, ясен:
- Перебрать все строки пикселей изображения.
- Выведите значение цвета каждого пикселя в виде текста.
- Найдите первый небелый пиксель и сохраните информацию о его местоположении.
4. Возможный скрипт (OS X, Linux, Unix)
Вот основная часть скрипта Bash, который можно использовать:
# Define some image specific variables (width, height, ...)
image=${1}
number_of_columns=$(identify -format '%W' ${image})
width=${number_of_columns} # just an alias
number_of_rows=$(identify -format '%H' ${image})
height=${number_of_rows} # just an alias
max_of_indices=$(( ${height} -1 ))
# Loop through all rows and grep for first non-white pixel
for i in $(seq 0 ${max_of_indices}); do
echo -n "Row ${i} : " ;
convert ${image}[${width}x1+0+${i}] txt:- \
| grep -v enumeration \
| grep -v '#FFFFFF' -m 1 \
|| echo "All WHITE pixels in row!"
done
-v white
отменит выбор всех строк, содержащих строку white
. Параметр -m 1
вернет максимум 1 совпадение (т. е. первое совпадение).
Это будет медленно, но сработает.
person
Kurt Pfeifle
schedule
05.03.2015