Удалить фон изображения
От: vsb Казахстан  
Дата: 10.01.21 02:25
Оценка:
Хочется в таком изображении заменить чёрный цвет на прозрачный. Т.е. во-первых правльно обработать края изображения, создав плавный переход на однопиксельной границе антиалиасинга, но самое сложное — правильно обработать частицы горящего огня, чтобы он остался полупрозрачным. Мне это нужно сделать программно, т.к. таких изображений много. Интуитивно кажется, что сначала надо выделить область с чистым чёрным цветом и потом расширять её по одному пикселу, пока они не слишком темнеют (т.е. чтобы расширение на границе с основным рисунком остановилось сразу, а там, где горит огонь, но формализовать это рассуждение не получается.

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

Думал уже находить области с огнём и отдельно их обрабатывать, но как-то слишком сложно всё выходит. Хочется всё же попробовать некий универсальный способ подобрать.

Если это сильно облегчит задачу, можно изначально рисовать исходное изображение на фоне любого другого цвета. Хотя мне показалось, что это только исказит цвета.
Re: Удалить фон изображения
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 10.01.21 03:45
Оценка: 13 (2)
Здравствуйте, vsb, Вы писали:

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


Сама задача называется маттирование (matting), когда каждому пикселю изображения ищется соответствующее полупрозрачное значение. Применяется во всяких Фотошопах для вырезания людей (как у тебя), или для видео трансляций при замене фона, или уже для классического хромакея в кино. Стандартные подходы из коробки у тебя вряд ли заведутся — изображение искусственное.
С другой стороны, раз оно искусственное, то можно попробовать применить простые методы, тот же ICA, который используют в том числе для восстановления линейно смешанных изображений. Но для тебя ICA будет даже много, можно его упростить. Раз ты рисуешь на любом фоне, то надо нарисовать дважды — на двух разных фонах.
Тогда каждый пиксель картинки будет равен:
Img1[x, y] = OBJ[x, y] * T[x, y] + Color1 * (1 — T[x, y])
Img2[x, y] = OBJ[x, y] * T[x, y] + Color2 * (1 — T[x, y])

Тут Img1 и Img2 — это готовые изображения (они известны), а OBJ — это изображение объекта (его надо найти), Color1 и Color2 — два разных цвета фона (известны), T — это полупрозрачная маска со значениями в [0, 1] (неизвестна), x, y — координаты каждого пикселя.
Получаем для каждого пикселя систему из двух линейных уравнений с двумя неизвестными OBJ[x, y] и T[x, y]. Решив её получим цвет пикселя объекта, который рисуешь, и значение полупрозрачности для него. Кажется и всё. Хотя для каждого пикселя будет 3 системы — для R, G и B.
Отредактировано 10.01.2021 3:51 Nuzhny . Предыдущая версия .
Re[2]: Удалить фон изображения
От: vsb Казахстан  
Дата: 10.01.21 03:57
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Раз ты рисуешь на любом фоне, то надо нарисовать дважды — на двух разных фонах.


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

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