Protocole
Protocole

Reputation: 1743

cv::Scalar not displaying expected color

On an image frame, I use

void ellipse(Mat& img, Point center, Size axes, double angle, double startAngle, double endAngle, const Scalar& color, int thickness=1, int lineType=8, int shift=0)

to draw an ellipse and I want to set the ellipse color to green enter image description here [ RGB value : (165, 206, 94) ]. So I set the parameter const Scalar& color to

cv::Scalar(94.0, 206.0, 165.0, 0.0); // as BGR order, suppose the value is 0.0 - 255.0
cv::Scalar(94.0/255.0, 206.0/255.0, 165.0/255.0, 0.0); // suppose the value is 0.0 - 1.0

I also tried RGB alternative.

CV_RGB(165.0, 206.0, 94.0); // as RGB order, suppose the value is 0.0 - 255.0
CV_RGB(165.0/255.0, 206.0/255.0, 94.0/255.0); // suppose the value is 0.0 - 1.0

But the color being displayed is white enter image description here [ RGB value (255, 255, 255) ] , not the desired green one.

What I missed at this point? Any suggestion please. Thank you.

EDIT:

Let me put whole related code here. According to OpenCV iOS - Video Processing, this is the CvVideoCamera config in - (void)viewDidLoad;:

self.videoCamera = [[CvVideoCamera alloc] initWithParentView:imgView];
[self.videoCamera setDelegate:self];
self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront;
self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPreset352x288;
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
self.videoCamera.defaultFPS = 30;
self.videoCamera.grayscaleMode = NO;
[self.videoCamera adjustLayoutToInterfaceOrientation:UIInterfaceOrientationPortrait];

Then after [self.videoCamera start]; called, the (Mat&)image would be captured and can be processed in the CvVideoCameraDelegate method - (void)processImage:(Mat&)image; and here are the code to draw an ellipse:

- (void)processImage:(Mat&)image {

NSLog(@"image.type(): %d", image.type()); // got 24

// image.convertTo(image, CV_8UC3); // try to convert image type, but with or without this line result the same

NSLog(@"image.type(): %d", image.type()); // also 24

cv::Scalar colorScalar = cv::Scalar( 94, 206, 165 );
cv::Point center( image.size().width*0.5, image.size().height*0.5 );
cv::Size size( 100, 100 );
cv::ellipse( image, center, size, 0, 0, 360, colorScalar, 4, 8, 0 );

}

Eventually, the ellipse is still in white, not the desired green one.

Upvotes: 8

Views: 28706

Answers (4)

PowHu
PowHu

Reputation: 2189

Set alpha to 255 can fix this problem. Scalar(94,206,165,255)

Upvotes: 19

Barshan Das
Barshan Das

Reputation: 3767

As mrgloom points correctly in the comment, it might be because of type of your image [ the Mat object where you want to draw, i.e Mat &img in ellipse() function]. cv::Scalar(94, 206, 165) is the desired green color for 8UC3 type images. Setting these values in 32FC3 image will result in white color.

Upvotes: 3

Shakir
Shakir

Reputation: 41

I was having similar problem and I have managed to fix it by first converting image to BGR. So in your case processImage function would look like as:

-(void)processImage:(Mat&)image
{
    cvtColor(image, image, CV_RGBA2BGR);
    cv::Scalar colorScalar = cv::Scalar( 94, 206, 165 );
    cv::Point center( image.size().width*0.5, image.size().height*0.5 );
    cv::Size size( 100, 100 );
    cv::ellipse( image, center, size, 0, 0, 360, colorScalar, 4, 8, 0 );
}

The only line which I have included in your code is:

cvtColor(image, image, CV_RGBA2BGR);

If you also log channel, depth and type information in the above function as follows:

NSLog(@"Before conversion");
NSLog(@"channels %d", image.channels());
NSLog(@"depth %d", image.depth());
NSLog(@"type %d", image.type());
NSLog(@"element size %lu", image.elemSize());
cvtColor(image, image, CV_RGBA2BGR);
NSLog(@"After conversion");
NSLog(@"channels %d", image.channels());
NSLog(@"depth %d", image.depth());
NSLog(@"type %d", image.type());
NSLog(@"element size %lu", image.elemSize());

you will see before conversion:

channels 4
depth 0
type 24
element size 4

which I think is CV_8UC4 and after conversion it becomes:

channels 3
depth 0
type 16
element size 3

which is CV_8UC3.

I guess one of the reason why it does not work without cvtColor is that the opencv drawing functions don't support alpha transparency when the target image is 4-channel as mentioned in opencv documentation. So by converting CV_RGBA2BGR we take out alpha channel. However having said that I do not managed to get it work if I do:

cvtColor(image, image, CV_RGBA2RGB);

In this Red and Blue colors are inverted in the image. So although it seems to work but I am not sure if it is the actual reason.

Upvotes: 0

theroom101
theroom101

Reputation: 609

you can use

src.convertTo(src, CV_8UC3);

Where CV_8UC3 means that you use 8 bits unsigned char and 3 color image representation. More information you can find here OpenCV docs after that your ellipse should be green, if it doesn't help post the whole code.

Upvotes: 1

Related Questions