转换图像颜色空间并在OpenCV中输出单独的通道

时间:2012-12-10 16:40:18

标签: opencv

我正在尝试减少将RGB图像转换为YCbCr图像的例程的运行时间。我的代码如下所示:

cv::Mat input(BGR->m_height, BGR->m_width, CV_8UC3, BGR->m_imageData);
cv::Mat output(BGR->m_height, BGR->m_width, CV_8UC3);

cv::cvtColor(input, output, CV_BGR2YCrCb);

cv::Mat outputArr[3];
outputArr[0] = cv::Mat(BGR->m_height, BGR->m_width, CV_8UC1, Y->m_imageData);
outputArr[1] = cv::Mat(BGR->m_height, BGR->m_width, CV_8UC1, Cr->m_imageData);
outputArr[2] = cv::Mat(BGR->m_height, BGR->m_width, CV_8UC1, Cb->m_imageData);  

split(output,outputArr);

但是,这段代码很慢,因为有一个冗余的分割操作,它将交错的RGB图像复制到单独的通道图像中。有没有办法让cvtColor函数创建一个已经拆分成通道图像的输出?我试图使用_OutputArray类的构造函数来接受一个向量或矩阵数组作为输入,但它不起作用。

3 个答案:

答案 0 :(得分:0)

您确定复制图像数据是限制步骤吗? 你是如何生产Y的? Cr / Cb cv ::垫子?
你能不能重写这个函数把结果写成三个独立的图像?

答案 1 :(得分:0)

cv :: cvtColor没有调用选项,它将结果作为三个单独的cv :: Mats(每个通道一个)。

  

dst - 输出与src相同大小和深度的图像。

来源:http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#cvtcolor

您必须从结果中复制像素(正如您已经在做的那样)或自己编写这样的转换函数。

答案 2 :(得分:0)

使用拆分。这会将图像分成3个不同的通道或阵列。

现在将它们转换回UIImage是我遇到麻烦的地方。我得到三个灰度图像,每个阵列一个。我确信它们是cvMat格式的正确通道,但当我将它们转换为UIImage时,它们是灰度但每个图像中的灰度值不同。如果您可以使用imreadimshow,那么它应该在拆分后为您显示图像。我的问题是尝试使用ios.h方法,我相信它重新组装数组,而不是传输单个数组。这是我的代码,使用分段控件来选择要显示的图层或数组。就像我说的那样,我获得了3张灰度图像,但值完全不同。我需要保留一层并放弃其余部分。仍然致力于这一部分。

UIImageToMat(_img, cvImage);
cv::cvtColor(cvImage, RYB, CV_RGB2BGRA);
split(RYB, layers);
if (_segmentedRGBControl.selectedSegmentIndex == 0) {
   // cv::cvtColor(layers[0], RYB, CV_8UC1);
    RYB = layers[0];
    _imageProcessView.image = MatToUIImage(RYB);
}
if (_segmentedRGBControl.selectedSegmentIndex == 1) {
    RYB = (layers[1]);
    _imageProcessView.image = MatToUIImage(RYB);
}
if (_segmentedRGBControl.selectedSegmentIndex == 2) {
    RYB = (layers[2]);
    _imageProcessView.image = MatToUIImage(RYB);
}
}