OpenCVでのYCrCb値の求め方

このQ&Aのポイント
  • OpenCVを利用してカメラ画像の輝度値のCr,Cb成分を求める方法について調査しています.
  • 2つの式が存在し、異なる値が得られますが、どちらが正しいかやより正確な値を求める方法についても知りたいです.
  • 画像処理初心者であるため、ご教授いただけるとありがたいです.
回答を見る
  • ベストアンサー

OpenCVにおいてのYCrCb値の求め方

こんにちは OpenCVを用いてカメラに映る画像の輝度値のCr,Cb成分(画素数全体の平均を取り)を表示する プログラムを作ろうと考えているんですが、サイトを検索していると輝度値の求め方が・・・ Y→輝度値, Cr,Cb→輝度値からそれぞれR成分,B成分を引き取ったもの R,G,B→RGBそれぞれの値,delta→8ビット画像(128) があるとしまして Y = 0.299*R + 0.587*G + 0.114*B Cr = 0.5*R - 0.419*G - 0.081*B + delta Cb = -0.169*R - 0.332*G + 0.5*B + delta と Y = 0.299*R + 0.587*G + 0.114*B (Yは同じ式) Cr = 0.713 * (R - Y) + delta Cb = 0.564 * (B - Y) + delta 2通りあります.どちらの式も違う値(小数部の範囲で)が出ます. どちらが正しいCr成分,Cb成分を求める式なのでしょうか? あるいどちらがより正確な値が求められるのでしょうか? 画像処理を始めたばかりでなので,ご教授よろしくお願い致します.

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

kmeeさんが言っているように、式の表記方法が違うだけで、YCrCb変換の式としては同じと思った方が良いと思います。 ちなみに、後半の式を展開しても Y = 0.299*R + 0.587*G + 0.114*B Cr = 0.499813*R - 0.41853*G - 0.08128*B + delta Cb = -0.16864*R - 0.33107*G + 0.499704*B + delta となり、RGBの値が0~255の場合、2通りの式の計算の差の絶対値が一番大きくても-0.23766 しかもcvCvtColorを使っているのであれば、RGBの値は入力も出力の8Bitで使っている?でしょうから、計算結果には、なんら影響はないと思います。 また、カメラで画像を撮影した時のRGBの値は、普通に2~3ぐらいはふらつくので、RGBの値が1以下の話をしても、あまり意味が無いと思います。 あえて、どちらが正確か?というと、YCrCbの定義を表している後半の式が良いと思います。

dezeckco
質問者

お礼

回答ありがとうございます。 RGBの値は結構変化するのですね・・・ 予想以上でした^^; 展開したらほぼ同じ式になるんですね・・・ 途中計算式が難しくてどらがいいのか迷っていました。 参考にさせて頂きます。

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

cvtColorでRGB→YCrCbに変換したら、3チャンネルあるうちのそれぞれのチャンネルにY,Cr,Cbが入っています。 Cr,Cbの値が欲しいなら ・cvtColorでRGB(BGR?)→YCrCbに変換 ・splitでチャンネル毎に分離 http://opencv.jp/opencv-2.2/c/core_operations_on_arrays.html#split http://opencv.jp/opencv-2.2/cpp/core_operations_on_arrays.html#cv-split で、Y,Cr,Cbそれぞれだけが入った1チャンネルの画像になります。 あるいは、RGB画像からR,G,Bをそれぞれ取り出す要領で、Y,Cr,Cbが取りだせます。

dezeckco
質問者

お礼

3チャンネルで分離ですか・・・ 了解しました。時間的に実装できるかわかりませんが、やってみます。 回答ありがとうございます。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

小数部の違いというのは誤差の範囲ではないかと。 それより、OpenCVを使っているのなら http://opencv.jp/opencv-2.2/c/imgproc_miscellaneous_image_transformations.html#cvtcolor http://opencv.jp/opencv-2.2/cpp/imgproc_miscellaneous_image_transformations.html#cv-cvtcolor を使えばいいのではないでしょうか。

dezeckco
質問者

補足

どの式も正しいのでしょうか? cvtColorのことでしょうか? これは使っています. 実はYCrCb変換のCrとCbの値の入手したいのです. こちらのサイトでは後者の式を用いてますね・・・どちらが正しいのでしょうか?

関連するQ&A

  • YCbCrってどういう意味?

    RGBは光の三原色で色を表そうという考え方ですよね?これは分かるのですが、どうして、YCbCrで色が表せるのかが分かりません。どこかで、Yは輝度で、Cb,Crはどれだけ赤いか,どれだけ青いかを表すと読みました。まず、ここが分かりません。輝度(明るさ)と赤み,青みだけで、なぜすべての色を表すことが出来るのでしょうか? また、RGB→YCbCr変換式の各係数はどのようにして決められているのでしょうか? 分かりやすく教えてください。 よろしくお願いします。

  • OpenCVでcvSetImageROIについて

    OpenCVで画像aから画像bをcvSetImageROIで切り抜きました. 画像aと切り抜いた画像bの画素値を比較すると,同じところを見ているはずなのに, 上と下で画素値が少しづつ違っています. cvSetImageROIで画像の輝度値が変わってしまうことはありますか?(輝度値を見たのはmatlabです)

  • Excel VBA での計算について…

    こんばんは、最近VBAを使い始めた初心者のものです。 画像処理をやってます。Bitmap形式の画像からRGB値を読み込んでそれぞれのワークシートに値を入れる所までは出来てます。 そのあと、RGB→XYZ→L*a*b*に変換した値を新しいワークシートの対応するセルにいれたいのですが、なにぶん初心者なのでどう書くのかわからず困ってます。 どなたか教えていただけないでしょうか? ちなみにRGB→XYZの変換式は X=0.607R+0.174G+0.201B Y=0.299R+0.587G+0.114B Z=0.066G+1.117B で、XYZ→L*a*b*の変換式は (X/0.983)>0.008856,(Y/1.000)>0.008856,(Z/1.183)>0.008856の時 L*=116(Y/1.000)^1/3 a*=500{(X/0.983)^1/3-(Y/1.000)^1/3} b*=200{(Y/1.000)^1/3-(Z/1.183)^1/3} (X/0.983),(Y/1.000),(Z/1.183)の値に0.008856以下のものがある場合は、 上式で対応する立法根の項をそれぞれ以下の式に置き換えて計算します。 (X/0.983)^1/3→7.787(X/0.983)+16/116 (Y/1.000)^1/3→7.787(Y/1.000)+16/116 (Z/1.183)^1/3→7.787(Z/1.183)+16/116

  • OpenCv ヒストグラム比較について

    OpenCv ヒストグラム比較について 画像の色を比較するためにヒストグラムを比較する関数cvCompareHistを使って比較しています。 ですが↓の画像の図形でRGB成分を分けてからそれぞれを比較したのですが、必ずどの成分も一致とでます。 ヒストグラムは色の分布を持っていてその分布を比較しているんですよね? cvCompareHistがいまいちなにを比較しているのかがはっきりとわからない状態です。

  • OpenCV2-画素を配列に格納したい

    こんにちは。 私のパソコンにはOpenCV2.3をインストールしています。 たとえば、 IplImage* img; で読み込んだ画像を pixel[x][y] といった2次元配列に格納したいです。 といいますのも、 for(int i = 0; i < img->width; i++){ for(int j = 0; j < img->heifht; i++){ pixel[i][j] = ~~~~~~; } } といった処理をしたいからです。 ちなみに、この2次元配列にはRGBと輝度値が入っていればOKです。 ...説明が不十分ですが、どうか教えていただけるとすごく助かります>< お願いします!

  • 奇数の判断について・・・・・・・・

    y座標が16で割ると余り1になるようなすべてのピクセルを白(RGB成分の輝度値が255)にした画像を生成したい場合・・・・・・・・・ /* nWidth:画像の幅、nHeight:画像の高さ*/ /* x座標とy座標の値を足すと奇数になるすべてのピクセルを白(RGB成分の輝度値が255)にする画像を生成する */  for(j = 0; j < nHeight; j++)   for(k = 0; k < nWidth; k++)   if(k%16==1)     {     DllBmpSetPixelValueR(pBmpOrig, j, k, 255);     DllBmpSetPixelValueG(pBmpOrig, j, k, 255);     DllBmpSetPixelValueB(pBmpOrig, j, k, 255);    } と条件式としましては、if(k%16==1)な感じでも大丈夫でしょうか? すみませんがアドバイスお願いします。。。。。。

  • テレビの色復調について

    テレビの復調にてついてお尋ねしたいことがあります。 RGBのカラー信号を伝送する場合、 通常、輝度信号と色差信号に分けて伝送するとのことですが、 輝度信号をYとして、一般に Y = 0.30R + 0.59G + 0.11B と、表されることが分かりました。 しかし、これを復調する方法が分かりません。 マトリクス回路での復調方法、RGBの求め方を教えてください。 よろしくお願いします。

  • 色彩について

    CIE基準で、x=0.28、y=0.52になるとき、赤青緑の3色で作られる白色LEDの 緑色として最適である、 なんて教科書に書いてあったんですが、これはなぜなんでしょうか? というのは、RGB系からCIEへの換算では、 x=0.6R-0.28G-0.32B y=0.2R-0.52G+0.31B という式が使われますが、たしかに、この式から、 RGB系でG=1、R=B=0(グリーンのみ)のときを考えると、 x=0.28 y=0.52 となります。だから、緑色として最適なのか?とは思いますが、しかし x=0.28、y=0.52 になるときは、「G=1、R=B=0」 以外のときでもあるのではないでしょうか?たとえば、y=0.52は、 「G=0、R=1、B=1」 (青と赤が混ざっている) でも、y=0.51 となると思うのです。

  • OpenCVのIplImage型に関する質問

    OpenCVのIplImageという構造体は http://hp.vector.co.jp/authors/VA025246/opencv/004.html のようになっているようなのですが, 画像をキャプチャした際に、「画素のdepthが 8(bit)でチャンネル数3(RGB)のとき」、 char *imageData から、一直線の配列として画像がRGBRGBRGB・・・という風に並んでいて、それぞれの大きさがcharだというのはわかりました。 そこで、imageDataのポインタを進めていって(+1したり+2したりすることで)画像データを読み込んでいます しかし、「depthが32(bit)でチャンネル数1(グレイ画像)のとき」、同じように辿っても、正しいデータが得られませんでした(0.00000という画素値やありえないぐらい大きい値)。 型がcharなので、そこがおかしいのかと思いますが、 char型から始まる画像データなのに、double型(32bit)をどうやっていれてあるのか見当もつきませんし、どうやって32bitずつポインタを進めていくのかもわかりません。 そもそも、ここに本当にデータが入ってるのか・・・(汗 OpenCV経験者の方は少数だと思いますが、画像処理経験者の方など、何か思いつくところがある方、ぜひとも意見をお願いしますm(_ _"m)ペコリ

  • OpenCv 透明度について

    OpenCv 透明度について 透明度を表すRGBAのA(アルファチャネル)をいじって画像の透明にしたいのですが、いじってみてもなにも変化がありません。 なにが悪いのかわかりません ↓こんな感じでやってます。 // 画像を読み込む src_img = cvLoadImage(src_imgfile,CV_LOAD_IMAGE_COLOR); //RGBA変換 dst_img = cvCreateImage(cvGetSize(bg_img),IPL_DEPTH_8U,4); cvCvtColor(bg_img,dst_img,CV_RGB2RGBA); //透明度をいじる for ( int y = 0 ; y < dst_img->height ; y++ ) { for ( int x = 0 ; x < dst_img->width ; x++ ) { dst_img->imageData[dst_img->widthStep * y + x * 4 + 3] = -255; } }

専門家に質問してみよう