gpt4 book ai didi

opencv - 使用OpenCV绘制具有透明度的椭圆

转载 作者:行者123 更新时间:2023-12-02 16:38:50 25 4
gpt4 key购买 nike

我目前正在使用opencv在白色背景以及X和Y轴上绘制椭圆,如下所示:

Mat image = Mat::zeros(size,size, CV_8UC3);
image.setTo(Scalar(255,255,255)); /* White background */

/* Draw Axis */
line(image,
Point(originX, 0), /*Point 1*/
Point(originX, size), /*Point 2*/
Scalar(colorAxis.B,colorAxis.G,colorAxis.R), /*Color*/
1, /*Thickness*/
8); /*lineType*/

line(image,
Point(0, originY), /*Point 1*/
Point(size, originY), /*Point 2*/
Scalar(colorAxis.B,colorAxis.G,colorAxis.R), /*Color*/
1, /*Thickness*/
8);

for(i=0; i<numEllipses; i++)
{
ellipse(image,
Point(originX + dataEllipse[k].center[0]*ppu, originY - dataEllipse[k].center[1]*ppu),
Size(dataEllipse[k].axis[0]*ppu, dataEllipse[k].axis[1]*ppu),
-dataEllipse[k].angle,
0,
360,
Scalar(colorEllipse.B, colorEllipse.G, colorEllipse.R),
-1,
CV_FILLED);
}

imshow("Result", image);
waitKey(1);

这是因为有N个椭圆,并且它们重叠。另外,还有一个权重值对应于一种颜色(从蓝色到红色)。我也想使用此权重值将其用作alpha参数。

对于我所看到的,可以使用addWeigth函数,但是它在两个图像之间,我想用椭圆来做。有什么办法做到这一点,或者每个椭圆我必须有一个图像,并使用addWeigth和image0和image1,然后(image0和image1)和image2,依此类推?

谢谢您的帮助。

最佳答案

这是一个简单的示例程序,该程序使用临时椭圆图像绘制透明椭圆。

请注意,weight = 1表示椭圆不是透明的而是实心的,因此该椭圆的“下方”不再可见。绘图顺序确实有所不同!

int main()
{
//cv::Mat input = cv::imread("../inputData/Lenna.png");
cv::Mat background = cv::Mat(512,512, CV_8UC3, cv::Scalar(255,255,255));

std::vector<cv::Point2f> centers;
std::vector<cv::Scalar> colors;
std::vector<cv::Size> axes;
std::vector<float> angles;
std::vector<float> weights;

// make sure that there are same number of entries in each vector.
centers.push_back(cv::Point2f(255, 255));
centers.push_back(cv::Point2f(275, 255));
centers.push_back(cv::Point2f(255, 275));
centers.push_back(cv::Point2f(275, 275));
centers.push_back(cv::Point2f(255, 225));
centers.push_back(cv::Point2f(225, 225));

colors.push_back(cv::Scalar(255,0,0));
colors.push_back(cv::Scalar(0,255,0));
colors.push_back(cv::Scalar(0,0,255));
colors.push_back(cv::Scalar(0,0,0));
colors.push_back(cv::Scalar(0,0,0));
colors.push_back(cv::Scalar(0,255,0));

axes.push_back(cv::Size(128,128));
axes.push_back(cv::Size(128,128));
axes.push_back(cv::Size(128,128));
axes.push_back(cv::Size(128,128));
axes.push_back(cv::Size(128,128));
axes.push_back(cv::Size(128,128));

angles.push_back(0);
angles.push_back(0);
angles.push_back(0);
angles.push_back(0);
angles.push_back(0);
angles.push_back(0);

// weight 0 means completely transparent = invible. weight 1 means completely solid = will overwrite everything else
weights.push_back(0.5f); // half transparent
weights.push_back(0.5f);
weights.push_back(0.5f);
weights.push_back(1.0f); // solid
weights.push_back(0.3f); // quite transparent
weights.push_back(0.3f); // quite transparent

// ORDER DOES MATTER!
// printing a transparent ellipse over a solid ellipse will make the transparent ellipse partly visible, but printing the solid ellipse over anything will make only the solid ellipse visible
// you could however sort ellipses before printing so that more solid ones are more in the background for example

int thickness = 5;

for(unsigned int i=0; i<centers.size(); ++i)
{
cv::Mat temporaryEllipse = cv::Mat::zeros(background.rows, background.cols, background.type()); // same size and type as background;
cv::Mat temporaryMask = cv::Mat::zeros(background.rows, background.cols, CV_8UC1); // empty single channel 8bit mask

// draw ellipse to temporary
cv::ellipse(temporaryEllipse, centers[i], axes[i], angles[i], 0, 360, colors[i], thickness);

// draw same ellipse to mask
cv::ellipse(temporaryMask, centers[i], axes[i], angles[i], 0, 360, 255, thickness);

for(int y=0; y<temporaryEllipse.rows; ++y)
for(int x=0; x<temporaryEllipse.cols; ++x)
{
// only blend pixel that belong to the ellipse!
if(temporaryMask.at<unsigned char>(y,x))
{
cv::Vec3b ellipsePixel = temporaryEllipse.at<cv::Vec3b>(y,x);
cv::Vec3b backgroundPixel = background.at<cv::Vec3b>(y,x);

float weight = weights[i];
cv::Vec3b blendedPixel = weight*ellipsePixel + (1-weight)*backgroundPixel;

// update result
background.at<cv::Vec3b>(y,x) = blendedPixel;
}
}
}


cv::imshow("input", background);
cv::imwrite("../outputData/TransparentEllipses.png", background);
cv::waitKey(0);
return 0;
}

enter image description here

并以15的厚度绘制

enter image description here

关于opencv - 使用OpenCV绘制具有透明度的椭圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32314680/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com