2

これは、stackoverflow に関する私の最初の投稿です。すべてを正しく行うことを願っています。そうでない場合は申し訳ありません。

単一の RGB 値を CIE L*a*b* 色空間に変換する関数のコードを書いています。この関数は、3 つの float 配列 ([0-255] の値を持つ RGB チャネル) を取り、L*a*b* 値を持つ 3 つの float 配列を出力に与えることになっています。そのために、cvtColorOpenCV で利用可能な関数を使用しています。

openCV Web サイトで提案されているように、コンストラクターによって Mat 構造 ( で必要cvtColor) を作成しています。

私の問題は、コードが正しく実行され、変換が実行されると思いますが、Mat 構造に含まれる値を取得できないことです。

これが私のコードです:

float * rgb2lab(float rgb[3]) {
    // bring input in range [0,1]
    rgb[0] = rgb[0] / 255;
    rgb[1] = rgb[1] / 255;
    rgb[2] = rgb[2] / 255;

    // copy rgb in Mat data structure and check values
    cv::Mat rgb_m(1, 1, CV_32FC3, cv::Scalar(rgb[0], rgb[1], rgb[2]));
    std::cout << "rgb_m = " << std::endl << " " << rgb_m << std::endl;
    cv::Vec3f elem = rgb_m.at<cv::Vec3f>(1, 1);
    float R = elem[0];
    float G = elem[1];
    float B = elem[2];
    printf("RGB =\n [%f, %f, %f]\n", R, G, B);

    // create lab data structure and check values
    cv::Mat lab_m(1, 1, CV_32FC3, cv::Scalar(0, 0, 0));
    std::cout << "lab_m = " << std::endl << " " << lab_m << std::endl;

    // convert
    cv::cvtColor(rgb_m, lab_m, CV_RGB2Lab);

    // check lab value after conversion
    std::cout << "lab_m2 = " << std::endl << " " << lab_m << std::endl;
    cv::Vec3f elem2 = lab_m.at<cv::Vec3f>(1, 1);
    float l = elem2[0];
    float a = elem2[1];
    float b = elem2[2];
    printf("lab =\n [%f, %f, %f]\n", l, a, b);

    // generate the output and return
    static float lab[] = { l, a, b };
    return lab;
}

ご覧のとおり、at関数によって Mat 構造からすべてのチャネルを抽出し、ベクトルから個別にアクセスしています。これは多くの場所で解決策として提案されています (そのうちの 1 つ)。

しかし、このコードを実行すると (入力ベクトルは {123,10,200} でした) cout、Mat 構造の出力が正しく取得されます (そこからアルゴリズムが正しく変換されます) が、抽出された値が間違っていることがわかります。

rgb_m = 
 [0.48235294, 0.039215688, 0.78431374]
RGB =
 [0.000000, 0.000000, -5758185472.000000]
lab_m = 
 [0, 0, 0]
lab_m2 = 
 [35.198029, 70.120964, -71.303688]
lab =
 [0.000000, 0.000000, 4822177514157213323960797626368.000000]

誰が私が間違っているのか考えていますか?

ご協力ありがとうございました!

4

1 に答える 1