Полупрозрачные объекты на IplImage - PullRequest
0 голосов
/ 20 мая 2019

Я рисую объекты на IplImage следующим образом:

cvLine(image, point_1, point_2, color, thickness, CV_AA); // Line
cvCircle(mage, point, radius, color, thickness, CV_AA); // Circle
// and some others...

Как я могу нарисовать их полупрозрачными?cv::Scalar не поддерживает альфа-канал, если я правильно понимаю.Я нашел что-то похожее, но не совсем подходящее: ссылка .Здесь речь идет о полупрозрачности IplImage, а не об объектах на ней.

1 Ответ

1 голос
/ 20 мая 2019

Итак, я протестировал его сейчас с IplImage и cv::Mat, и оба cvCircle и cv::circle не поддерживают рисование полупрозрачных объектов. Я использовал OpenCV 3.4.0, так как эта версия все еще поддерживает старый C API.

Давайте посмотрим на следующий код:

// IplImage - doesn't work
IplImage* ipl = cvCreateImage(cvSize(201, 201), IPL_DEPTH_8U, 4);
cvSet(ipl, CvScalar(255, 0, 0, 255));
cvCircle(ipl, CvPoint(100, 100), 50, CvScalar(0, 0, 255, 128), CV_FILLED);

// cv::Mat - doesn't work
cv::Mat img = cv::Mat(201, 201, CV_8UC4, cv::Scalar(255, 0, 0, 255));
cv::circle(img, cv::Point(100, 100), 50, cv::Scalar(0, 0, 255, 128), cv::FILLED);

Мы создаем синее 4-канальное изображение с нулевой прозрачностью и рисуем красный круг с 0,5 прозрачностью. В обоих случаях мы получаем следующий вывод:

False output

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

Итак, для IplImage, а также для cv::Mat нам нужно использовать смешивание, например. используя addWeighted. Давайте посмотрим на этот код:

// IplImage - works
IplImage* iplBG = cvCreateImage(cvSize(201, 201), IPL_DEPTH_8U, 3);
cvSet(iplBG, CvScalar(255, 0, 0));
IplImage* iplFG = cvCreateImage(cvSize(201, 201), IPL_DEPTH_8U, 3);
cvSet(iplFG, CvScalar(0, 0, 0));
cvCircle(iplFG, CvPoint(100, 100), 50, CvScalar(0, 0, 255), CV_FILLED);
IplImage* iplOut = cvCreateImage(cvSize(201, 201), IPL_DEPTH_8U, 3);
cvAddWeighted(iplBG, 1, iplFG, 0.5, 0, iplOut);

// cv::Mat - works
cv::Mat imgBG = cv::Mat(201, 201, CV_8UC3, cv::Scalar(255, 0, 0));
cv::Mat imgFG = cv::Mat(201, 201, CV_8UC3, cv::Scalar(0, 0, 0));
cv::circle(imgFG, cv::Point(100, 100), 50, cv::Scalar(0, 0, 255), cv::FILLED);
cv::Mat imgOut;
cv::addWeighted(imgBG, 1, imgFG, 0.5, 0, imgOut);

Фактически, мы создаем синее 3-канальное фоновое изображение, например:

Background

И мы создаем черное переднее 3-канальное изображение того же размера с красным кружком:

Foreground

Используя addWeighted с alpha = 1 и beta = 0.5, мы получаем ожидаемый результат для обеих версий:

Correct output

...