Reputation: 16255
I have an image I am trying to segment by colouring each pixel either red green or blue. I have calculated a confidence score for each pixel and want to adjust the alpha transparency of the pixel to reflect confidence, i.e. low confidence means almost transparent. Is there a way to do this in OpenCV? If not can anyone suggest a minimally invasive library (C++)?
I have tries using a 4 channel 8-bit Mat
as suggested by Aurellius, here is the code:
cv::Mat m = cv::Mat(20,20, CV_8UC4);
for(int i = 0; i < m.rows; i++){
for(int j = 0; j < m.cols; j++){
Vec4b& v = m.at<Vec4b>(i,j);
v[0] = 255;
v[1] = 0;
v[2] = 0;
v[3] = 0.5;
}
}
imwrite("alpha.png", m);
namedWindow("m");
imshow("m", m);
waitKey(0);
The image shown is just all blue (no transparency) and the image just fully transparent.
Upvotes: 7
Views: 19522
Reputation: 4164
I've also had the same problem but when was drawing transparent shapes and solved it by blending images. I've fount this in OpenCV's documentation
if you want to paint semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main image.
For this purpose I suggest you to take a look at this documentation article. Hope this will help.
Upvotes: 3
Reputation: 11329
There are many ways to accomplish this. One possible way is to access and modify each individual pixel. Assuming image
is a four-channel, 8-bit cv::Mat
:
auto& pixel = image.at<cv::Vec4b>(i,j);
pixel[3] = confidence;
where i
and j
are the indices of the pixel in the image.
There are other methods that are probably more elegant, but they will depend on your current code.
UPDATE:
The behavior you describe is to be expected. Apparently cv::imshow()
does not support transparency. This explains why your displayed image is all blue.
As for the saved image, it is important to remember that the image is of type CV_8UC4
. That means that each channel element is stored as a uchar
. Assigning a value of 0.5
will truncate to zero, hence the fully transparent saved image.
If your confidence is a float value in the range [0,1]
, scale it by 255 to put it in the range supported by 8-bit images. Thus,
v[3] = 0.5;
becomes
v[3] = 0.5 * 255;
Upvotes: 6