简体   繁体   English

如何创建半透明形状?

[英]How to create a semi transparent shape?

I would like to know how to draw semi-transparent shapes in OpenCV, similar to those in the image below (from http://tellthattomycamera.wordpress.com/ )我想知道如何在 OpenCV 中绘制半透​​明形状,类似于下图(来自http://tellthattomycamera.wordpress.com/

在此处输入图片说明

I don't need those fancy circles, but I would like to be able to draw a rectangle, eg, on a 3 channel color image and specify the transparency of the rectangle, something like我不需要那些花哨的圆圈,但我希望能够绘制一个矩形,例如,在 3 通道彩色图像上并指定矩形的透明度,例如

rectangle (img, Point (100,100), Point (300,300), Scalar (0,125,125,0.4), CV_FILLED);

where 0,125,125 is the color of the rectangle and 0.4 specifies the transparency.其中0,125,125是矩形的颜色, 0.4指定透明度。 However OpenCV doesn't have this functionality built into its drawing functions.但是,OpenCV 的绘图功能中没有内置此功能。 How can I draw shapes in OpenCV so that the original image being drawn on is partially visible through the shape?如何在 OpenCV 中绘制形状,以便通过形状部分可见正在绘制的原始图像?

The image below illustrates transparency using OpenCV.下图说明了使用 OpenCV 的透明度。 You need to do an alpha blend between the image and the rectangle.您需要在图像和矩形之间进行 alpha 混合。 Below is the code for one way to do this.下面是执行此操作的一种方法的代码。

在此处输入图片说明

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

int main( int argc, char** argv )
{
    cv::Mat image = cv::imread("IMG_2083s.png"); 
    cv::Mat roi = image(cv::Rect(100, 100, 300, 300));
    cv::Mat color(roi.size(), CV_8UC3, cv::Scalar(0, 125, 125)); 
    double alpha = 0.3;
    cv::addWeighted(color, alpha, roi, 1.0 - alpha , 0.0, roi); 

    cv::imshow("image",image);
    cv::waitKey(0);
}

In OpenCV 3 this code worked for me:在 OpenCV 3 中,这段代码对我有用:

cv::Mat source = cv::imread("IMG_2083s.png");
cv::Mat overlay;
double alpha = 0.3;

// copy the source image to an overlay
source.copyTo(overlay);

// draw a filled, yellow rectangle on the overlay copy
cv::rectangle(overlay, cv::Rect(100, 100, 300, 300), cv::Scalar(0, 125, 125), -1);

// blend the overlay with the source image
cv::addWeighted(overlay, alpha, source, 1 - alpha, 0, source);

Source/Inspired by: http://bistr-o-mathik.org/2012/06/13/simple-transparency-in-opencv/来源/灵感来源: http : //bistr-o-mathik.org/2012/06/13/simple-transparency-in-opencv/

Adding to Alexander Taubenkorb's answer, you can draw random (semi-transparent) shapes by replacing the cv::rectangle line with the shape you want to draw.添加到 Alexander Taubenkorb 的答案中,您可以通过将cv::rectangle线替换为要绘制的形状来绘制随机(半透明)形状。

For example, if you want to draw a series of semi-transparent circles, you can do it as follows:例如,如果你想画一系列半透明的圆,你可以这样做:

cv::Mat source = cv::imread("IMG_2083s.png");  // loading the source image
cv::Mat overlay;  // declaring overlay matrix, we'll copy source image to this matrix
double alpha = 0.3;  // defining opacity value, 0 means fully transparent, 1 means fully opaque

source.copyTo(overlay);  // copying the source image to overlay matrix, we'll be drawing shapes on overlay matrix and we'll blend it with original image

// change this section to draw the shapes you want to draw
vector<Point>::const_iterator points_it;  // declaring points iterator
for( points_it = circles.begin(); points_it != circles.end(); ++points_it )  // circles is a vector of points, containing center of each circle
    circle(overlay, *points_it, 1, (0, 255, 255), -1);  // drawing circles on overlay image


cv::addWeighted(overlay, alpha, source, 1 - alpha, 0, source);  // blending the overlay (with alpha opacity) with the source image (with 1-alpha opacity)

For C++, I personally like the readability of overloaded operators for scalar multiplication and matrix addition:对于 C++,我个人喜欢用于标量乘法和矩阵加法的重载运算符的可读性:

... same initial lines as other answers above ...

// blend the overlay with the source image
source = source * (1.0 - alpha) + overlay * alpha;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM