Ход мыслей был таков:
— всего имеем 256 градаций каждого канала
— все, что, примерно, ниже 30-го значения, можно отнести к «черному» зеленому
— вариант, где зеленая составляющая является доминирующей, почти наверняка является зеленым цветом (тут еще есть градации серого, близкого к серому и пр.)
Имея наобум взятое изображение из интернета
(взято по адресу vid8o.files.wordpress.com/2011/01/chromakey.jpg?w=620)
и аналогично взятый фон
(не знаю кому принадлежит)
идем реализовывать алгоритм для 24-битного изображения и 8-битной маски (альфа-канала):
byte const black_threshold = 30; byte* chroma_p = chroma_data; byte* alpha_p = alpha_data; for (int counter = 0; counter < size; ++counter) { byte b = *chroma_p++; byte g = *chroma_p++; byte r = *chroma_p++; // определим, зеленый ли пиксел перед нами if (g > r && g > b) { // если этот зеленый достаточно черный, то оставим его нетронутым в маске if (g < black_threshold) *alpha_p++ = 255; else { // вычислим разницу между компонентами для определения яркости маски byte m = g - max(r, b); *alpha_p++ = 255 - m; } } }
Запускаем, получаем:
маска
и по маске наложенное изображение на наш фон
В итоге наша реализация показывает довольно неплохой, но очень грубый результат. В частности, мы видим на полученном изображении зеленый туман. Вглянем на гистограмму маски:
Видим, что основная часть маски в области прозрачности лежит в интервале 17-100. Поэтому растянем интервал значений 100-255 на интервал 0-255, «убив» тем самым пелену и получим вот такую гистограмму
и вот такую маску, более похожую на необходимую нам
.
В результате мы избавились от ненужной нам пелены
,
но видим оставшийся ореол вокруг маски и зеленую «засветку» тона, которая у нас естественно смотрелась на первоначальном зеленом фоне и совсем инородно смотрится на нашем новом фоне. В целом результат обошелся дешево, но остается ряд вопросов. Как бороться с ореолом? Можно попробовать сузить маску сверткой, или попробовать как-то иначе растянуть гистограмму маски. А вот как бороться с засветом я пока не знаю, поэтому для дальнейщей работы пищи достаточно. Критика, советы и рекомендации приветствуются. Так же буду признателен ссылкам на подобные работы, в том числе их реализацию при помощи GPU, OpenCV и пр.
ссылка на оригинал статьи http://habrahabr.ru/post/158479/
Добавить комментарий