我想画一个透明的多边形(在这种情况下为三角形)。但我无法通过搜索网络找到任何示例。
// Create image
Mat image = Mat::zeros( 400, 400, CV_8UC3 );
// Draw a circle
/** Create some points */
Point Treangle_points[1][20];
Treangle_points[0][0] = Point( 150, 100 );
Treangle_points[0][1] = Point( 275, 350 );
Treangle_points[0][2] = Point( 50, 20 );
const Point* ppt[1] = { Treangle_points[0] };
int npt[] = { 3 };
fillPoly( image, ppt, npt, 1, Scalar( 255, 255, 255 ), 8 );
imshow("Image",image);
答案 0 :(得分:3)
要使用透明度,您需要在BGRA色彩空间中使用alpha
频道。 alpha = 0
表示完全透明,而alpha = 255
表示不透明的颜色。
你需要创建一个CV_8UC4
图像(又名Mat4b
),或者将一个3通道图像转换为带有cvtColor(src, dst, COLOR_BGR2BGRA)
的4通道,并绘制一个透明的填充形状,alpha通道等于到0。
如果您加载4频道图片,请记得使用imread("path_to_image", IMREAD_UNCHANGED);
透明三角形(透明度在这里呈现为白色,您可以看到图像实际上是透明的,用您首选的图像查看器打开它):
代码:
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
// Create a BGRA green image
Mat4b image(300, 300, Vec4b(0,255,0,255));
vector<Point> vertices{Point(100, 100), Point(200, 200), Point(200, 100)};
vector<vector<Point>> pts{vertices};
fillPoly(image, pts, Scalar(0,0,0,0));
// ^ this is the alpha channel
imwrite("alpha.png", image);
return 0;
}
注意
imshow
无法正确显示透明度,因为它只会忽略alpha
频道。
C ++ 98版
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
// Create a BGRA green image
Mat4b image(300, 300, Vec4b(0, 255, 0, 255));
Point vertices[3];
vertices[0] = Point(100, 100);
vertices[1] = Point(200, 200);
vertices[2] = Point(200, 100);
const Point* ppt[1] = { &vertices[0] };
int npt[] = { 3 };
fillPoly(image, ppt, npt, 1, Scalar(0, 0, 0, 0), 8);
imwrite("alpha.png", image);
imshow("a", image);
waitKey();
return 0;
}
答案 1 :(得分:1)
这个问题确实是一个古老的问题。我找到了一些答案,但这不是我想要的。我想设置一个多边形roi透明,在没有alpha通道帮助的情况下将其重叠。我们仍然可以在没有4通道图像的情况下通过透明区域观察背景:
代码如下:
// img: input 3 channels image
// roi : polygon represents by points
// color: transparent base color
// alpha: transparent ratio
// out: out image with transparent area
void SetTransparentColor(cv::Mat &img, vector<vector<cv::Point> > &roi, cv::Scalar color, double alpha, cv::Mat &out)
{
cv::Mat layer = cv::Mat::zeros(img.size(), CV_8UC3);
cv::fillPoly(layer, roi, color);
cv::addWeighted(img, alpha, layer, 1-alpha, 0, out);
}
我还尝试了其他方法,并且核心思想是相同的,即通过合并两个具有alpha值的区域像素(代表透明比率)。但是它们很耗时。所以我不会在这里放这些代码。
答案 2 :(得分:0)
作为Miki答案的补充,下面的示例代码可能很有用。
有关详细信息,请参阅http://answers.opencv.org/question/73114
另见sample code of OpenCV documentation
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main( int, char** argv )
{
Mat image(400, 400, CV_8UC4, Scalar(0, 0, 200,0));
Mat bgra[4];
split(image,bgra);
rectangle(bgra[3],Rect(100,100,200,200),Scalar(255),-1);
merge(bgra,4,image);
imwrite("transparent1.png",image);
rectangle(bgra[3],Rect(150,150,100,100),Scalar(127),-1);
merge(bgra,4,image);
imwrite("transparent2.png",image);
bgra[3] = bgra[3] * 0.5; // here you can change transparency %50
// bgra[3] = bgra[3] + 50 // you can add some value
// bgra[3] = bgra[3] - 50 // you can subtract some value
merge(bgra,4,image);
imwrite("transparent3.png",image);
waitKey(0);
return(0);
}