8

在图像框架上,我使用

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)

绘制一个椭圆,我想将椭圆颜色设置为绿色 在此处输入图像描述[RGB 值:(165,206,94)]。所以我将参数设置const Scalar& color

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

我也尝试了 RGB 替代方案。

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

但是显示的颜色是白色在此处输入图像描述[RGB 值 (255, 255, 255) ],而不是所需的绿色。

我在这一点上错过了什么?请有任何建议。谢谢你。

编辑:

让我把整个相关的代码放在这里。根据OpenCV iOS - Video Processing,这是以下CvVideoCamera配置- (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];

然后在[self.videoCamera start];调用之后,(Mat&)image将被捕获并可以在 CvVideoCameraDelegate 方法中进行处理,- (void)processImage:(Mat&)image;这里是绘制椭圆的代码:

- (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 );

}

最终,椭圆仍然是白色的,而不是所需的绿色。

4

4 回答 4

19

将 alpha 设置为 255 可以解决此问题。标量 (94,206,165,255)

于 2014-03-19T05:41:43.760 回答
3

正如mrgloom 在评论中正确指出的那样,这可能是因为您的图像类型[您要绘制的Mat 对象,即ellipse() 函数中的Mat &img]。cv::Scalar(94, 206, 165) 是 8UC3 类型图像所需的绿色。在 32FC3 图像中设置这些值将产生白色。

于 2013-04-10T06:42:39.770 回答
1

您可以使用

src.convertTo(src, CV_8UC3);

其中 CV_8UC3 表示您使用 8 位无符号字符和 3 色图像表示。更多信息你可以在这里找到OpenCV 文档 ,如果它不能帮助发布整个代码,你的椭圆应该是绿色的。

于 2013-04-10T10:30:35.780 回答
0

我遇到了类似的问题,我已经设法通过首先将图像转换为 BGR 来解决它。所以在你的情况下 processImage 函数看起来像:

-(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 );
}

我在您的代码中包含的唯一行是:

cvtColor(image, image, CV_RGBA2BGR);

如果你还在上述函数中记录了频道、深度和类型信息,如下所示:

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());

您将在转换前看到:

channels 4
depth 0
type 24
element size 4

我认为是 CV_8UC4 转换后它变成:

channels 3
depth 0
type 16
element size 3

这是CV_8UC3。

我猜如果没有 cvtColor 就无法工作的原因之一是,当目标图像是 4 通道时,opencv 绘图函数不支持 alpha 透明度,如opencv 文档中所述。所以通过转换 CV_RGBA2BGR 我们取出 alpha 通道。但是,话虽如此,如果我这样做,我将无法使其工作:

cvtColor(image, image, CV_RGBA2RGB);

在这种情况下,红色和蓝色在图像中是反转的。因此,尽管它似乎有效,但我不确定这是否是实际原因。

于 2013-07-18T13:40:37.270 回答