opencv: how to change the transparency level of an image - opencv

Is it possible to change the transparency level of an IplImage (the alhpa channel)? I can do this using cvSet and setting all the values to a cvScalar, but that would change not only the alpha channel, but the actual RGB channels, as well.
thanks for the help.

You can add a scalar to an RGBA image with cvAddS:
void cvAddS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL)
For increasing just the alpha channel of an image you could use for example a cvScalar(0,0,0,30).
This will increase the alpha value by 30.
The same way cvSubS can be applied to substract a scalar.

Related

Most efficient way to create a Mat object using existing buffer in RGB format?

I have a bitmap in RGB format, i.e. 24bit per pixel. How can I create a Mat object so that I can minimize data copying while making sure that the order of the channel is treated correctly, given that default order in OpenCV is BGR
In general you can use RGB order as usual, just remember to convert to correct color space when needed.
You can create a Mat header with no copies using:
int rows = ...
int cols = ...
uchar* rgb_buffer = ...
cv::Mat3b rgb_image(rows, cols, bgr_buffer);
None (or just a few) of the OpenCV functions assume that matrix data should be in BGR or RGB order. You can also operate on your data with your custom processing accounting for RGB order.
The fact that OpenCV images are in BGR order is mostly a matter of input / output (basically imshow, imread, imwrite, and the like).
You can always convert your image with cvtColor(..., RGB2<whatever>) in case you need to switch color space. This won't be a performance issue, since the data would be copied anyway.
RGB buffer:
int rows, int cols, uchar* input_RGB;
Mat buffer declaration:
Mat image(rows, cols, CV_8UC3, input_RGB);
https://docs.opencv.org/master/d6/d6d/tutorial_mat_the_basic_image_container.html

OpenCV Pixel with "no value"

Is it possible in OpenCV to have pixels with no colour? Like a transparent layer or in gimp if you delete all colours or elements on a layer.
Yes you can using BGRA system by making the alpha value equal to 0.
Example:
cv::Mat img(ROW, COLS, CV_8UC4, cv::Scalar(B_VALUE,G_VALUE,R_VALUE,0 /* This is the alpha*/));
Now all the this cv::Mat pixels are 100% transparent. You can change the alpha value to 255 so it is fully opaque or any value in the range [0,255] for a degree of transparent.

Detecting red balls in a basket scalar value wont work

I am trying to detect red balls in a basket through thresholding . My problem is I think I have the wrong Scalar values because the result is just black.I am not sure which vector channel is the luminance,hue,saturation and brightness
enter code here
Mat onespoon= image[2];
Mat onespoonnewcolor;
Mat newspoon;
cvtColor(onespoon, onespoonnewcolor, CV_BGR2HSV);
inRange(onespoonnewcolor, Scalar(30,0,60,30), Scalar(70,7,100,70), newspoon);
namedWindow( "Display window", CV_WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Display window", newspoon ); // Show our image inside it.
You are converting to HSV color space. That means the first, second, and third image channels correspond to hue, saturation, and value. There is no fourth channel, so your Scalar arguments should have only three elements.
In OpenCV, hue ranges from 0 to 180, and saturation and value range from 0 to 255.
Without a posted example image, I can only guess a range for the correct hue angles. This suggests that hue values in the ranges [0, 15] and [165,180] might work well. Since red wraps around the zero-point of the spectrum, this would require two applications of cv::inRange(). For hue and saturation, I would discard low values, using the range [20,255].
Your code might then look like this, after which newspoon contains the results of both inRange passes:
cv::Mat temp1, temp2;
cv::inRange(onespoonnewcolor, cv::Scalar(0,20,20), cv::Scalar(15,255,255), temp1);
cv::inRange(onespoonnewcolor, cv::Scalar(165,20,20), cv::Scalar(180,255,255), temp2);
cv::Mat newspoon;
cv::bitwise_or(temp1, temp2, newspoon);
As pointed out in the comments, it is possible to do this with only a single call to inRange(), which is more efficient and eliminates some temporary variables:
cv::Mat newspoon;
cv::inRange(onespoonnewcolor, cv::Scalar(16,20,20), cv::Scalar(164,255,255), newspoon);
newspoon = 255 - newspoon;

How do I create a histogram which can be used for calcBackProject in opencv?

I have specified the histogram as
MatND skinCrCbHist =Mat::zeros(Size(256,256),CV_8UC1);
ellipse(skinCrCbHist, Point(113, 155.6), Size(283.4, 159.2), 43.0, 0.0, 360.0, Scalar(255), -1); // Using a really big ellipse to find any sort of back projection in CrCb domain.
cvtColor(src, ycrcb, CV_BGR2YCrCb); //src is input, image of a person
float crrange[]={0,255};
float cbrange[]={0,255};
const float* ranges[]={crrange,cbrange};
int channelsy[]={1,2};
calcBackProject( &ycrcb, 1, channelsy, skinCrCbHist, backproj, ranges, 255, true );
imshow("bp",backproj);
The problem i face is that backproj shows a completely black image.
When I used a normal histogram created with calcHist on a natural image, i do get some sort of backprojection. But how do i use a histogram, i create artificially, by specifying an ellipse, to get a backprojection.
If I understood your problem correctly, you could use mask with the original calcHist function.
You didn't specified which version of OpenCV you are using, so I will assume the latest 2.4.6.0. The method prototype is following (omitting defaults, and types):
calcHist(images, nimages, channels, mask, hist, dims, histSize, ranges)
The third parameter is mask. The mask means, that the function will ignore all pixels which matches zero pixels in mask. In program the mask is another image correctly setup.
Here is pseudo-code for you problem:
1) get input image
2) create matrix of same size as input of type CV_8UC1 filled with zeros
3) draw white (value 255) ellipse on the new image
4) call caclHist with the new image as mask
http://docs.opencv.org/modules/imgproc/doc/histograms.html

how to set hue value of some pixel with opencv

I need to change the hue of some pixels of my image, but i don't know how to set them!
I converted the image in HSV with CV_BGR2HSV and now i'm cycling with a for by rows and cols...
how can I access each pixel's hue?
for setting RGB i'm using this code...
CvScalar s;
s=cvGet2D(imgRGB,i,j); // get the (i,j) pixel value
printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]);
s.val[0]=240;
s.val[1]=100;
s.val[2]=100;
cvSet2D(imgRGB,i,j,s); // set the (i,j) pixel value
You already converted your image to HSV, so the 3 layers of the image now correspond to Hue, Saturation and Value:
s.val[0] is the hue.
s.val[1] is the saturation.
s.val[2] is the value.
So go ahead and use exactly the same method as for your RGB images to get and set the pixel values.
Yes, openCV uses 180° i.e., (0°-179°) cylinder of HSV; while normally its (0°-240°) in MS paint and ideally (0°-360°). So, openCV gives you result of hue from (0°-179°).

Resources