Преобразовать изображение в CSV

Что нужно сделать, чтобы разбить изображение на сетку квадратных ячеек, раскрасить каждую ячейку содержащимся в ней усредненным цветом и экспортировать полученные средние значения в виде CSV-файла?

Поскольку ppm — это простые форматы изображений, преобразование в формат ppm может быть хорошим началом, но что дальше?

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

Поскольку игровая карта будет обновляться по мере разработки игры, я надеюсь автоматизировать этот процесс, поэтому я считаю, что решение на основе кода было бы оптимальным; он написан на С#.

«как эффективно действовать дальше» - почему вы беспокоитесь об эффективности, если на данный момент у вас нет эффективности? Просто идите вперед, внедрите его, а затем измерьте, является ли эффективность проблемой или нет.

Thomas Weller 26.01.2019 16:57

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

Caleb 26.01.2019 17:02

Простой поиск в Google выдал хорошее место для начала.

Idle_Mind 26.01.2019 17:21

Было бы полезно, если бы вы объяснили, какие значения вы на самом деле хотите записать в файл CSV. Если rgb(r,g,b) и вам действительно нужен CSV-файл, то разделители-запятые будут сбивать с толку из-за тех, что в значениях rgb. Также вы хотите rgb или hex? Вы хотите, чтобы это было как rgb (r, g, b) или просто значения r, g, b.

fmw42 26.01.2019 21:02
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
1 386
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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

Просто в терминале (или в командной строке Windows), начиная с этого изображения 500x256:

magick start.png -resize 3x2\! -depth 8 -compress none ppm:
P3
3 2
255
189 0 66 189 0 66 189 0 66 
66 0 189 66 0 189 66 0 189

Это изменило размер изображения и усреднило цвета в изображение 3x2 (выберите другой размер, если хотите) и распечатало вывод в виде текстового файла PPM.

Размер 3x2, и первая строка составляет 3 пикселя с rgb (189,0,66), который в основном красный, а вторая строка — 3 пикселя с rgb (66,0,189), который в основном синий.

Я оставлю вас в формате CSV :-)


Здесь вы можете уменьшить его размер и снова увеличить, чтобы увидеть эффект усреднения по блокам 8x3:

magick start.png -resize 8x3\! -depth 8 -scale 400x result.png


В зависимости от того, что вам нравится анализировать, вы можете получить одну и ту же информацию в немного другом формате:

magick start.png -resize 8x3\! -depth 8 txt:

# ImageMagick pixel enumeration: 8,3,65535,srgb
0,0: (54998,0,10537)  #D60029  srgb(214,0,41)
1,0: (54998,0,10537)  #D60029  srgb(214,0,41)
2,0: (54998,0,10537)  #D60029  srgb(214,0,41)
3,0: (54998,0,10537)  #D60029  srgb(214,0,41)
4,0: (54998,0,10537)  #D60029  srgb(214,0,41)
5,0: (54998,0,10537)  #D60029  srgb(214,0,41)
...
...
3,1: (32896,0,32896)  #800080  purple
4,1: (32896,0,32896)  #800080  purple
5,1: (32896,0,32896)  #800080  purple
6,1: (32896,0,32896)  #800080  purple
7,1: (32896,0,32896)  #800080  purple
0,2: (10537,0,54998)  #2900D6  srgb(41,0,214)
5,2: (10537,0,54998)  #2900D6  srgb(41,0,214)
6,2: (10537,0,54998)  #2900D6  srgb(41,0,214)
7,2: (10537,0,54998)  #2900D6  srgb(41,0,214)

Вот небольшой цикл сценария bash с использованием Imagemagick для получения средних цветов блоков изображения и записи в файл csv.

Вход (256x256):

Чтобы получить правильное среднее значение для блоков изображения, следует использовать -scale, а не -resize. Итак, здесь я получаю набор 4x4 средних блоков 64x64 цветов из изображения (256/4=64). Затем я перебираю каждый блок в строках, затем в столбцах и получаю цвета. Я сохраняю цвета для каждой строки в строке rowlist с запятыми между ними. Собрав каждый ряд цветов, я записываю его в текстовый файл. Повтор для следующего ряда.

convert image.png -scale 4x4! image2.png
for ((j=0; j<4; j++)); do
for ((i=0; i<4; i++)); do
rowcolor=`convert image2.png -crop 1x1+$i+$j +repage -format "rgb(%[fx:round(255*u.r)]_%[fx:round(255*u.g)]_%[fx:round(255*u.b)])" info:`
if [ $i -eq 0 ]; then
rowlist = "$rowcolor"
else
rowlist = "$rowlist,$rowcolor"
fi
done
echo "$rowlist" >> image_colors.txt
done


Данные в полученном текстовом файле выглядят следующим образом:

rgb(8_0_247),rgb(50_0_205),rgb(50_0_205),rgb(8_0_247)
rgb(50_0_205),rgb(157_0_98),rgb(157_0_98),rgb(50_0_205)
rgb(50_0_205),rgb(157_0_98),rgb(157_0_98),rgb(50_0_205)
rgb(8_0_247),rgb(50_0_205),rgb(50_0_205),rgb(8_0_247)


Вы можете удалить rgb(), если хотите, и просто сохранить значения цвета. Я использовал _ для разделения значений, чтобы запятые использовались только между цветами rgb(...). Однако вы можете предпочесть использовать табуляции или пробелы для разделителей файлов, чтобы значения цвета были r, g, b, а не r_g_b.

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

convert image.png -scale 4x4! image2.png
for ((j=0; j<4; j++)); do
for ((i=0; i<4; i++)); do
rowcolor=`convert image2.png -depth 8 -crop 1x1+$i+$j +repage -format "#%[hex:u.p]" info:`
if [ $i -eq 0 ]; then
rowlist = "$rowcolor"
else
rowlist = "$rowlist,$rowcolor"
fi
done
echo "$rowlist" >> image_colors.txt
done


который создает следующие значения в текстовом файле.

#0800F7,#3200CD,#3200CD,#0800F7
#3200CD,#9D0062,#9D0062,#3200CD
#3200CD,#9D0062,#9D0062,#3200CD
#0800F7,#3200CD,#3200CD,#0800F7


Использование %[hex:] является новым для Imagemagick в версиях Imagemagick 6 и 7 от 01.06.2017.

Почему масштабирование, а не изменение размера, пожалуйста?

Mark Setchell 26.01.2019 21:34

Масштаб усредняет блоки пикселей. Изменение размера интерполирует пиксели и поэтому не является правильным средним значением, если вы не укажете -filter box. Другие фильтры выполняют взвешивание в локальной окрестности и поэтому не учитывают каждый пиксель одинаково при усреднении для изменения размера. См. imagemagick.org/script/command-line-options.php#scale в сравнении с imagemagick.org/script/command-line-options.php#resize и imagemagick.org/Использование/фильтр/#interpolated.

fmw42 26.01.2019 23:27

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