20. OpenCV шаг за шагом. Обработка изображения - альфа-смешивание

1. OpenCV шаг за шагом. Введение.
2. Установка.
3. Hello World.
4. Загрузка картинки.
5. Вывод видео
6. Ползунок
7. Захват видео с камеры
8. Запись видео
9. События от мышки
10. Обработка изображения — сглаживание
11. Обработка изображения — изменение размеров
12. ROI — интересующая область изображения
13. Типы данных OpenCV
14. Матрица
15. Сохранение данных в XML
16. Генерация случайных чисел
17. Обработка изображения — морфологические преобразования
18. Обработка изображения — морфологические преобразования 2
19. Обработка изображения — заливка части изображения
20. Обработка изображения — альфа-смешивание

Альфа-канал (alpha channel) — это значение, точно такое же, как цветовые компоненты (красный, зеленый и синий). Оно определяет степень прозрачности для каждого пикселя изображения.
Однако, OpenCV пока не умеет работать с 4-канальными изображениями RGBA (как ни трудно догадаться A — это и есть обозначение альфа-канала). При загрузке RGBA изображения оно просто преобразуется в RGB.
Однако, OpenCV реализует операцию альфа-смешивания (alpha blending) — т.е. наложение изображений друг на друга с целью создания эффекта частичной прозрачности.
Этого эффекта можно добиться используя функцию cvAddWeighted().

CVAPI(void)  cvAddWeighted( const CvArr* src1, double alpha,
                            const CvArr* src2, double beta,
                            double gamma, CvArr* dst );
— взвешенная поэлементная сумма двух массивов
формула:
dst = src1 * alpha + src2 * beta + gamma

src1 — первый исходный массив
alpha — вес элементов первого массива
src2 — второй исходный массив
beta — вес элементов второго массива
gamma — добавочная величина к каждой сумме
dst — массив для сохранения результата

массивы должны иметь одинаковый тип и размер (или размер ROI)

А вот и пример работы данной функции:
Загружаем два изображения, причём первое должно быть больше второго, т.к. на изображении image с помощью cvSetImageROI() выделяется область интереса размером со второе изображение.
Затем пиксели ROI первой картинки и пиксели второй картинки поэлементно складываются с весовыми коэффициентами alpha = 0.5 и beta = 0.5, соответственно и получается нужный эффект альфа-смешивания.

//
// alpha blending 
// взвешенная поэлементная сумма двух массивов - cvAddWeighted()
//
//  http://dasl.mem.drexel.edu/~noahKuntz/openCVTut2.html
// 

#include <cv.h>
#include <highgui.h>
#include <stdio.h>

IplImage* image = 0;
IplImage* templ = 0;
IplImage* dst = 0;

int main(int argc, char* argv[])
{
	// имя картинки задаётся первым параметром
	char* filename = argc >= 2 ? argv[1] : "Image0.jpg";
	// получаем картинку
	image = cvLoadImage(filename,1);

	printf("[i] image: %s\n", filename);
	assert( image != 0 );

	// шаблон
	char* filename2 = argc >= 3 ? argv[2] : "templ.bmp";
	printf("[i] template: %s\n", filename2);

	templ = cvLoadImage(filename2,1);
	assert( templ != 0 );

	cvNamedWindow("origianl", CV_WINDOW_AUTOSIZE);
	cvNamedWindow("template", CV_WINDOW_AUTOSIZE);
	cvNamedWindow("res", CV_WINDOW_AUTOSIZE);  

	dst = cvCloneImage(templ);

	// размер шаблона
	int width = templ->width;
	int height = templ->height;

	// оригинал и шаблон
	cvShowImage( "origianl", image);
	cvShowImage( "template", templ);

	int x = 0;
	int y = 0;
	// задаём весовые коэффициенты
	double alpha = 0.5;
	double beta = 0.5;
	// устанавливаем область интереса
	cvSetImageROI(image, cvRect(x,y,width,height));
	// взвешенная сумма
	cvAddWeighted(image, alpha, templ, beta, 0.0, dst);
	// освобождаем область интереса
	cvResetImageROI(image);

	// показываем результат
	cvShowImage( "res", dst);

	// ждём нажатия клавиши
	cvWaitKey(0);

	// освобождаем ресурсы
	cvReleaseImage( &image );
	cvReleaseImage( &templ );
	cvReleaseImage( &dst );
	cvDestroyAllWindows(); 
	return 0;
}


результат работы:


Ссылки:
ru.wikipedia.org/wiki/Альфа-канал
stackoverflow.com/questions/1451021/alpha-channel-in-opencv
blog.developer.stylight.de/2010/05/how-to-load-alpha-channel-pngs-with.html

Читать далее: 21. Обработка изображения — пороговое преобразование
  • 0
  • 9 ноября 2010, 12:09
  • noonv

Комментарии (1)

RSS свернуть / развернуть
+
0
Подскажите, пожалуйста, как реализовать soft light смешивание с учетом прозрачности. Интересно как это выглядит при попиксельной обработке.
Нашел формулу
#define ChannelBlend_SoftLight(A,B)  ((uint8)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))))

Но как реализовать, учитывая прозрачность, не понимаю.
avatar

Zaph

  • 20 января 2014, 15:34

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.