IplImage 上的半透明对象
Translucent objects on IplImage
我在 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
不支持 alpha 通道,如果我没理解错的话。我发现了类似但不太合适的内容:link。这里我们说的是半透明IplImage
,而不是上面的物体。
所以,我现在用 IplImage
和 cv::Mat
测试了它,cvCircle
和 cv::circle
都不支持绘制 semi-transparent 对象。我使用的是 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 的红色圆圈。在这两种情况下,我们都会得到以下输出:
我们看到,红色圆圈部分实际上"replaces"原始蓝色图像中的像素值。
因此,对于 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 通道背景图像是这样的:
然后,我们创建一个与红色圆圈大小相同的黑色前景 3 通道图像:
将 addWeighted
与 alpha = 1
和 beta = 0.5
结合使用,我们得到两个版本的预期输出:
我在 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
不支持 alpha 通道,如果我没理解错的话。我发现了类似但不太合适的内容:link。这里我们说的是半透明IplImage
,而不是上面的物体。
所以,我现在用 IplImage
和 cv::Mat
测试了它,cvCircle
和 cv::circle
都不支持绘制 semi-transparent 对象。我使用的是 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 的红色圆圈。在这两种情况下,我们都会得到以下输出:
我们看到,红色圆圈部分实际上"replaces"原始蓝色图像中的像素值。
因此,对于 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 通道背景图像是这样的:
然后,我们创建一个与红色圆圈大小相同的黑色前景 3 通道图像:
将 addWeighted
与 alpha = 1
和 beta = 0.5
结合使用,我们得到两个版本的预期输出: