これは、stackoverflow に関する私の最初の投稿です。すべてを正しく行うことを願っています。そうでない場合は申し訳ありません。
単一の RGB 値を CIE L*a*b* 色空間に変換する関数のコードを書いています。この関数は、3 つの float 配列 ([0-255] の値を持つ RGB チャネル) を取り、L*a*b* 値を持つ 3 つの float 配列を出力に与えることになっています。そのために、cvtColor
OpenCV で利用可能な関数を使用しています。
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]
誰が私が間違っているのか考えていますか?
ご協力ありがとうございました!