在OpenCV中将三个灰度[R,G,B]图像合并为一幅彩色图像

6
我有三张灰度图像,使用分割函数创建。现在我想要重新生成彩色图像。我尝试了以下代码,但没有成功。我得到的结果图像仍然是灰度的。
        cv::Mat R = cv::imread("/home/r/secret_R.png",0);
        cv::Mat G = cv::imread("/home/r/secret_G.png",0);
        cv::Mat B = cv::imread("/home/r/secret_B.png",0);
        std::vector<cv::Mat> array_to_merge;
        array_to_merge.push_back(R);
        array_to_merge.push_back(G);
        array_to_merge.push_back(B);
        cv::Mat color;
        cv::merge(array_to_merge, color);

于是我尝试了cvtColor函数:
        cv::Mat color_converted;
        cv::cvtColor(color, color_converted, CV_GRAY2BGR);
        cv::imwrite("/home/r/color_secret.png",color_converted);

但显然,它仅适用于只有一个通道的源图像。我将其中一张灰度图像传入:

cv::cvtColor(R, color_converted, CV_GRAY2BGR);

但是我仍然不能得到一张彩色图像。生成的图像仍然是灰度的。

我做错了什么?我该如何得到我的彩色图像呢?


你的PNG文件是否确实被编码为灰度图像,而不是仅具有灰色像素的RGB图像?在合并之前,我建议使用OpenCV将R、G和B转换为灰度图像。 - Drew Noakes
是的,它们绝对是灰度单通道图像。 - Chani
2个回答

15

我看不出你的代码有什么问题。我怀疑可能是源数据或者导入程序处理源数据的方式有问题。在加载图像后,你可以打印图像元数据以查看OpenCV正在读取哪些属性?它们都必须具有相同的尺寸和单通道。

std::cout << "Red:   " << R.size().width << " x " << R.size().height << " x " << R.channels() << std::endl;
std::cout << "Green: " << G.size().width << " x " << G.size().height << " x " << G.channels() << std::endl;
std::cout << "Blue:  " << B.size().width << " x " << B.size().height << " x " << B.channels() << std::endl;

我刚刚运行了你的程序,只添加了头文件和主函数。我做了一个小改动,将BGR顺序(默认顺序)合并在一起。我使用以下命令在Mac OS X 10.8上编译它:

g++ -o merge merge.cpp -lopencv_core -lopencv_highgui

与OpenCV版本2.4.3不兼容。

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>

int main(int argc, char* argv[])
{
    cv::Mat R = cv::imread("chan_dest_red.png", 0);
    cv::Mat G = cv::imread("chan_dest_green.png", 0);
    cv::Mat B = cv::imread("chan_dest_blue.png", 0);

    std::vector<cv::Mat> array_to_merge;

    array_to_merge.push_back(B);
    array_to_merge.push_back(G);
    array_to_merge.push_back(R);

    cv::Mat color;

    cv::merge(array_to_merge, color);

    imwrite("merged.png", color);

    return 0;
}

我已经将另一个项目中的一些单通道图像拆分成文件,然后将它们合并成一张彩色图像,效果很好。源文件信息如下:

Red:   500 x 333 x 1
Green: 500 x 333 x 1
Blue:  500 x 333 x 1

恭喜 - 这是我在 SO 上找到的最佳答案之一。 - peterh

1
一种方法是使用 cvtColor 从一个通道创建彩色图像,然后使用 at 函数在循环中逐像素替换其他两个颜色。可能有一种更容易使用矩阵运算符的方法,但我对 openCV 不够熟悉,无法确定。

4
抱歉,那将是一种非常低效且缓慢的方法。cv::merge()函数旨在以优化的方式完成此操作。 - gavinb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接