【OpenCV】BGRからHSVへの画像変換

このQ&Aのポイント
  • OpenCVを使って任意の画像をBGR表色系からHSV表色系に変換するプログラムです。
  • 元画像と変換後の画像の色味が異なってしまう問題が発生しています。
  • 原因が分からずに困っています。どなたか分かる方がいらっしゃいましたらご指摘お願いします。
回答を見る
  • ベストアンサー

【OpenCV】BGRからHSVへの画像変換

OpenCVを使って任意の画像データをBGR表色系からHSV表色系に変換するプログラムです。 コンパイルして実行してみたところ、添付画像のように元画像とは色味が異なった画像が出力されてしまいます。 他の画像ファイルを使ってみましたが結果は同じでした。 HSVへの変換がうまくいってないのでしょうが、調べても原因は分かりませんでした。 どなたか分かる方がいらっしゃいましたらご指摘お願いします。 以下にコードを載せます。 #include <cv.h> #include <highgui.h> int main (int argc, char **argv){ IplImage *src_img=0; // 入力画像 IplImage *hsv_img=0; // hsvに変換された画像 // (1)画像を読み込む src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); // (2)読み込んだ画像をhsvに変換する hsv_img = cvCreateImage (cvGetSize (src_img), IPL_DEPTH_8U, 3); cvCvtColor (src_img, hsv_img, CV_BGR2HSV); // (3)画像を表示,キーが押されたときに終了 cvNamedWindow ("Source_Image", CV_WINDOW_AUTOSIZE); cvNamedWindow ("HSV_Image", CV_WINDOW_AUTOSIZE); cvShowImage ("Source_Image", src_img); cvShowImage ("HSV_Image", hsv_img); cvWaitKey (0); // (4)メモリ解放 cvDestroyWindow ("Source_Image"); cvDestroyWindow ("HSV_Image"); cvReleaseImage (&src_img); cvReleaseImage (&hsv_img); return 0; } OS:Windows7 OpenCVのバージョン:2.1 添付画像で用いた画像の形式:png

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

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

cvCvtColorで変換したものは、別に色空間情報を持っているわけではありません。 CV_BGR2HSV で変換した前も後も「3チャンネルの画像」でしかありません。 cvShowImageは BGRの3チャンネル画像をカラー表示することはできますが、HSVの画像から色を復元するようなことはしません。 そもそも、画像がBGRなのがHSVなのか判断できないのですから。

Klein0x79
質問者

お礼

BGRからHSVに変換されても“見た目の色”は同じであるというわけではないのですね。 詳しい説明をありがとうございました。

その他の回答 (1)

  • helpaitm
  • ベストアンサー率80% (4/5)
回答No.1

画像を見ての通り正しく変換されていると思われますが、何か問題があるのでしょうか? HSV画像をcvShowImageすればこうなります。

Klein0x79
質問者

お礼

素早い返答ありがとうございます。 なるほど、表色系が変わるだけで出力画像は変わらないものだと思っていました。

関連するQ&A

  • OpenCVでRGBをHSVに変換する

    いつもありがとうございます。 今OpenCVを使って画像の変換をしているのですが、エラーが出てしまい困っています。 cvCvtColor(src, gray_img, CV_RGB2GRAY); でグレースケールに変換するのはエラーは出ず実行結果が出てくるのですが、 cvCvtColor(src, hsv_img, CV_RGB2HSV); cvCvtColor(src, hsv_img, CV_HSV2RGB); このようにHSVに変換しようとすると、「ハンドルされていない例外が発生しました」とエラーが出てきて、実行できません。 HSV変換とグレースケール変換の違いがあるのではないかと思って調べているのですが、わかりません。 わたしの都合によりソースを載せることはできないのですが、何が間違っているか教えてもらえるとうれしいです。

  • OpenCV2.3 のエラー

    Open CV2.3をVisual Studio2013 expresssに設定しました。 が、プログラムを実行すると 「エラー 3 error LNK1107: ファイルが無効であるか、または壊れています: 0x10B000 を読み取れません。 C:\Program Files\opencv\build\x64\vc10\staticlib\IlmImf.pdb...」 と表示されてしまい、困っています。 エラー原因は[リンカー]-[入力]-[追加の依存ファイル]の設定でしょうか。 当初、libとstaticlibフォルダの中にある、拡張子pbdを含む、重複なしのすべてのファイルを[追加の依存ファイル]に設定していましたが、これがエラーの原因かと思い、 libとstaticlibフォルダ内の、拡張子libのみに修正しました。 が、同じエラーが依然として出ています。 プログラムは以下の内容で、単純に画像を表示させるだけのものです。 ============================================= #include <cxcore.h> #include <cv.h> #include <highgui.h> int _tmain(int argc) { IplImage *src_img = 0, *dst_img; // (1)画像を読み込む src_img = cvLoadImage("C\\Users\\...\\thNDM091S8.jpg", CV_LOAD_IMAGE_COLOR); // (6)画像の表示 cvNamedWindow("Fitting", CV_WINDOW_AUTOSIZE); cvShowImage("Fitting", src_img); cvWaitKey(0); cvDestroyWindow("Fitting"); cvReleaseImage(&src_img); return 0; } ============================================== どこを直せばいいでしょうか。 いろいろと調べましたがわかりませんので、教えていただけると助かります。 よろしくお願いいたします。

  • OpenCVで画像を読み込みたい

    OpenCVを勉強しようと思い先日始めました。 http://chihara.naist.jp/opencv/?FrontPage 上記のサイトに掲載されている通りにVC++ 2008 EEで ・環境変数PATH ・インクルードファイル ・ライブラリファイル ・リンカ の設定をしました。 これでいざプログラムをコンパイルして実行すると何故か画像が読み込んでくれません。 これらの設定以外の他にするべきことがあるのでしょうか? いきなり出鼻を挫かれたので困っています。よろしくお願いします。 OS:XP SP2 開発環境:VC++ 2008 EE 実行したプログラム ---------------------------------------------------------------- #include "cv.h" #include "highgui.h" int main( int argc, char** argv ) { IplImage* img; char* filename = "abc.bmp"; if( argc == 2 && (img = cvLoadImage( filename, 1)) != 0 ) { cvNamedWindow( "Image view", 1 ); cvShowImage( "Image view", img ); cvWaitKey(0); // イベント処理を含む場合には,これが重要. cvDestroyWindow( "Image view" ); cvReleaseImage( &img ); return 0; } return -1; } ----------------------------------------------------------------

  • OpenCVでの画像からの顔検出

    OpenCVでの顔検出プログラム 以下のようなプログラムを実行したいのですが、ちゃんとビルトできるものの 肝心な画像からの顔認識が行われません。 例えばimg_0000.bmpという画像の顔認識を実行したい場合、 画像の読み込みの部分のプログラムを変えるべきなのか、bmpのイメージを置くフォルダの場所が間違っているのか 原因がわかりません。よろしければ手を貸していただきたいです。 ------------------------------------------------------------------- #include <cv.h> #include <highgui.h> int main (int argc, char **argv) { int i; IplImage *src_img = 0, *src_gray = 0; const char *cascade_name = "haarcascade_frontalface_default.xml"; CvHaarClassifierCascade *cascade = 0; CvMemStorage *storage = 0; CvSeq *faces; static CvScalar colors[] = { {{0, 0, 255}}, {{0, 128, 255}}, {{0, 255, 255}}, {{0, 255, 0}}, {{255, 128, 0}}, {{255, 255, 0}}, {{255, 0, 0}}, {{255, 0, 255}} }; // (1)画像を読み込む if (argc < 2 || (src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR)) == 0) return -1; src_gray = cvCreateImage (cvGetSize (src_img), IPL_DEPTH_8U, 1); // (2)ブーストされた分類器のカスケードを読み込む cascade = (CvHaarClassifierCascade *) cvLoad (cascade_name, 0, 0, 0); // (3)メモリを確保し,読み込んだ画像のグレースケール化,ヒストグラムの均一化を行う storage = cvCreateMemStorage (0); cvClearMemStorage (storage); cvCvtColor (src_img, src_gray, CV_BGR2GRAY); cvEqualizeHist (src_gray, src_gray); // (4)物体(顔)検出 faces = cvHaarDetectObjects (src_gray, cascade, storage, 1.11, 4, 0, cvSize (40, 40)); // (5)検出された全ての顔位置に,円を描画する for (i = 0; i < (faces ? faces->total : 0); i++) { CvRect *r = (CvRect *) cvGetSeqElem (faces, i); CvPoint center; int radius; center.x = cvRound (r->x + r->width * 0.5); center.y = cvRound (r->y + r->height * 0.5); radius = cvRound ((r->width + r->height) * 0.25); cvCircle (src_img, center, radius, colors[i % 8], 3, 8, 0); } // (6)画像を表示,キーが押されたときに終了 cvNamedWindow ("Face Detection", CV_WINDOW_AUTOSIZE); cvShowImage ("Face Detection", src_img); cvWaitKey (0); cvDestroyWindow ("Face Detection"); cvReleaseImage (&src_img); cvReleaseImage (&src_gray); cvReleaseMemStorage (&storage); return 0; } -------------------------------------------------------- 以上のプログラムです。よろしくお願いします。

  • OpenCV2.4.6で色抽出を行いたい。

    Webカメラから取得した映像を用いて色抽出を行いたいです。 システム開発はVisual Studio 2012で言語はC++です。 OpenCV2.4.6を利用しているのですが、サンプルプログラムが古いバージョンで、OpenCV2.4.6では動かないので以下のプログラムを改良したいです。 参考にしたサイトはこちらです。 http://d.hatena.ne.jp/wah-wah-hawah/20090325/1237996168 以下プログラム #include <cv.h> #include <highgui.h> void GetMaskHSV(IplImage* src, IplImage* mask,int erosions, int dilations) { int x = 0, y = 0; uchar H, S, V; uchar minH, minS, minV, maxH, maxS, maxV; CvPixelPosition8u pos_src, pos_dst; uchar* p_src; uchar* p_dst; IplImage* tmp; tmp = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3); //HSVに変換 cvCvtColor(src, tmp, CV_RGB2HSV); CV_INIT_PIXEL_POS(pos_src, (unsigned char*) tmp->imageData, tmp->widthStep,cvGetSize(tmp), x, y, tmp->origin); CV_INIT_PIXEL_POS(pos_dst, (unsigned char*) mask->imageData, mask->widthStep, cvGetSize(mask), x, y, mask->origin); minH = 100; maxH = 115; minS = 80; maxS = 255; minV = 120; maxV = 255; for(y = 0; y < tmp->height; y++) { for(x = 0; x < tmp->width; x++) { p_src = CV_MOVE_TO(pos_src, x, y, 3); p_dst = CV_MOVE_TO(pos_dst, x, y, 3); H = p_src[0]; //0から180 S = p_src[1]; V = p_src[2]; if( minH <= H && H <= maxH && minS <= S && S <= maxS && minV <= V && V <= maxV ) { p_dst[0] = 255; p_dst[1] = 255; p_dst[2] = 255; } else { p_dst[0] = 0; p_dst[1] = 0; p_dst[2] = 0; } } } if(erosions > 0) cvErode(mask, mask, 0, erosions); if(dilations > 0) cvDilate(mask, mask, 0, dilations); cvReleaseImage(&tmp); } int main(int argc, char **argv) { int c; CvCapture* capture = 0; IplImage* frame = 0; IplImage* mask = 0; IplImage* dst = 0; if(argc == 1 || (argc == 2 && strlen (argv[1]) == 1 && isdigit(argv[1][0]))) capture = cvCreateCameraCapture(argc == 2 ? argv[1][0] - '0' : 0); frame = cvQueryFrame(capture); mask = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3); dst = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3); cvNamedWindow("src", CV_WINDOW_AUTOSIZE); cvNamedWindow("dst", CV_WINDOW_AUTOSIZE); while(1) { frame = cvQueryFrame(capture); GetMaskHSV(frame, mask, 1, 1); cvAnd(frame, mask, dst); cvShowImage("src", frame); cvShowImage("dst", dst); c = cvWaitKey(10); if(c == 'q') break; } cvDestroyWindow("src"); cvDestroyWindow("dst"); cvReleaseImage(&frame); cvReleaseImage(&dst); cvReleaseImage(&mask); cvReleaseCapture(&capture); return(0); }

  • OpenCVのエラーが取れません。

    VC++にてOpenCVを使って画像処理を行っています。 cvHoughCircles関数を使ってハフ変換による円検出をしているのですが、 「Null pointer(NULL array pointer is passed)  in function cvGetMat,C\User\VP\opencv\cxcore\src\cxarry.cpp(2780)  Press"Abort"to terminate application. Press"Retry"to debug(if the app is running under debugger). Press"Ignore"to continue(this is not safe).」 というエラーが出てしまいます。 これはいったいどういったエラーなのでしょうか? プログラムは以下の通りです。 //-------------------------------------------------- #include <stdio.h> #include <cv.h> #include <highgui.h> int main (int argc, char **argv) { int i; float *p; IplImage *src_img = 0, *src_img_gray = 0; CvMemStorage *storage; CvSeq *circles = 0; char *filename = "lena.jpg"; IplImage *image; //画像の読み込み・平滑化・二値化 image = cvLoadImage(filename, 0); // 0: グレイスケールで読み込む // (2)ハフ変換のための前処理(画像の平滑化を行なわないと誤検出が発生しやすい) cvSmooth (src_img_gray, src_img_gray, CV_GAUSSIAN, 11, 11, 0, 0); storage = cvCreateMemStorage (0); // (3)ハフ変換による円の検出と検出した円の描画 circles = cvHoughCircles (src_img_gray, storage, CV_HOUGH_GRADIENT, 1, 100, 20, 50, 10, MAX (src_img_gray->width, src_img_gray->height)); for (i = 0; i < circles->total; i++) { p = (float *) cvGetSeqElem (circles, i); cvCircle (src_img, cvPoint (cvRound (p[0]), cvRound (p[1])), 3, CV_RGB (0, 255, 0), -1, 8, 0); cvCircle (src_img, cvPoint (cvRound (p[0]), cvRound (p[1])), cvRound (p[2]), CV_RGB (255, 0, 0), 3, 8, 0); } // (4)検出結果表示用のウィンドウを確保し表示する cvNamedWindow ("circles", 1); cvShowImage ("circles", src_img); cvWaitKey (0); cvDestroyWindow ("circles"); cvReleaseImage (&src_img); cvReleaseImage (&src_img_gray); cvReleaseMemStorage (&storage); return 0; } //----------------------------------------------------- 解決方法など分かりましたら、よろしくお願いいたします。

  • OpenCV

    いつもお世話になっております。 添付の2値画像からハフ関数で直線抽出したいのですが、うまく行かず困っています。 エラーは表示されず、ただグレー 一色の出力です。 閾値、投票数、最小長さ、など値をいろいろ変えてみたのですがうまくいきません。 どなたか原因がおわかりであればぜひ教えてください。 よろしくお願い致します。 '================================================== ’void Sample(char *FilePath){ int i; float *line, rho, theta; double a, b, x0, y0; IplImage *src_img_std = 0, *src_img_prob = 0, *src_img_gray = 0; CvMemStorage *storage; CvSeq *lines = 0; CvPoint *point, pt1, pt2; src_img_gray = cvLoadImage(FilePath, CV_LOAD_IMAGE_GRAYSCALE); storage = cvCreateMemStorage(0); // (3)標準的ハフ変換による線の検出と検出した線の描画 lines = cvHoughLines2(src_img_gray, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI / 180, 1, 1, 0); for (i = 0; i <lines->total; i++) { line = (float *)cvGetSeqElem(lines, i); rho = line[0]; theta = line[1]; a = cos(theta); b = sin(theta); x0 = a * rho; y0 = b * rho; pt1.x = cvRound(x0 + 1000 * (-b)); pt1.y = cvRound(y0 + 1000 * (a)); pt2.x = cvRound(x0 - 1000 * (-b)); pt2.y = cvRound(y0 - 1000 * (a)); cvLine(src_img_std, pt1, pt2, CV_RGB(255, 0, 0), 3, 8, 0); } cvNamedWindow("Hough_line_standard", CV_WINDOW_AUTOSIZE); cvShowImage("Hough_line_standard", src_img_std); cvWaitKey(0); cvDestroyWindow("Hough_line_standard");

  • OpenCVの連続画像読み込みについて

    こんにちは。 連続画像の読み込みが出来なくて困ってます。 今まではVisualStudioを使い、読み込んでいたので IplImage* src_img = cvLoadImage("sample.bmp", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); if (src_img == NULL){ return 0; } のように書き直して動かしていたのですが http://opencv.jp/sample/initialization.html#combine の画像の連結のところで if (argc < 2) { return 1; } else { img_num = argc - 1; img = (IplImage **) cvAlloc (sizeof (IplImage *) * img_num); for (i = 0; i < img_num; i++) { img[i] = cvLoadImage (argv[i + 1], CV_LOAD_IMAGE_COLOR); if (img[i] == 0) return -1; } } ここをどのようにすれば連続画像を読み込めるようになるのか教えていただけないでしょうか。 よろしくお願いいたします。

  • OpenCVでサンプルコードを使うとエラーが出ます

    環境はVidualStudio2008、OpenCVは2.1のバージョンを利用しています。 OpenCVのテンプレートマッチングのサンプルを利用したところエラーが発生しました。 ソースは以下のものを使っています。 ところどころに入っているprintfは私が自分で入れたものですがこれが原因であるとは考えにくいのです。 エラーは添付したような画像で現れます。 またデバッグしたところ [下のフレームは間違っているか、または見つかりません。KernelBase.dll に対して読み込まれたシンボルはありません。] KernelBase.dll!76b7b9bc() このような文章も表示されました。 どうすれば解決できるでしょうか。 #include <cv.h> #include <highgui.h> int main (int argc, char **argv) { double min_val, max_val; CvPoint min_loc, max_loc; CvSize dst_size; IplImage *src_img, *tmp_img, *dst_img; argv[1]="○○"; argv[2]="○○"; argc=3; printf("1complete\n"); cvNamedWindow ("Image", 1); src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR); tmp_img = cvLoadImage (argv[2], CV_LOAD_IMAGE_COLOR); if(argc != 3 || (src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR))==0||(tmp_img = cvLoadImage (argv[2], CV_LOAD_IMAGE_COLOR))==0) return -1; printf("2complete\n"); // (1)探索画像全体に対して,テンプレートのマッチング値(指定した手法に依存)を計算 dst_size = cvSize (src_img->width - tmp_img->width + 1, src_img->height - tmp_img->height + 1); printf("2-1complete\n"); dst_img = cvCreateImage (dst_size, IPL_DEPTH_32F, 1);    //ここで動作停止 printf("2-2complete\n"); cvMatchTemplate (src_img, tmp_img, dst_img, CV_TM_CCOEFF_NORMED); printf("2-3complete\n"); cvMinMaxLoc (dst_img, &min_val, &max_val, &min_loc, &max_loc, NULL); printf("3complete\n"); // (2)テンプレートに対応する位置に矩形を描画 cvRectangle (src_img, max_loc, cvPoint (max_loc.x + tmp_img->width, max_loc.y + tmp_img->height), CV_RGB (255, 0, 0), 3); printf("4complete\n"); cvShowImage ("Image", src_img); printf("ALL COMPLETE!\n"); cvWaitKey (0); cvDestroyWindow ("Image"); cvReleaseImage (&src_img); cvReleaseImage (&tmp_img); cvReleaseImage (&dst_img); return 0; }

  • C++でOpenCV コンパイルでエラー

    超初心者です。 Visual C++2010 ExpressでOpenCVを使おうとしています。 このページを参考にしています。 http://gihyo.jp/dev/feature/01/opencv/0002?page=2 プログラムは以下の通り。 #include <C:\Program Files (x86)\opencv\build\include\opencv\cv.h> #include <C:\Program Files (x86)\opencv\build\include\opencv\highgui.h> int main(int argc, char* argv[]) { IplImage* img; // 画像ファイルポインタの宣言 char imgfile[] = "lena.jpg"; // 読み込み画像ファイル名 // 画像の読み込み img = cvLoadImage(imgfile, CV_LOAD_IMAGE_COLOR); // 画像の表示 cvNamedWindow ("lena", CV_WINDOW_AUTOSIZE); cvShowImage ("lena", img); cvWaitKey (0); cvDestroyWindow("lena"); // 画像の解放 cvReleaseImage(&img); return 0; } コンパイルすると、以下のエラーメッセージが出ます。 1>------ ビルド開始: プロジェクト: try, 構成: Debug Win32 ------ 1> try.cpp 1>c:\program files (x86)\opencv\build\include\opencv\cv.h(63): fatal error C1083: include ファイルを開けません。'opencv2/core/core_c.h': No such file or directory ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== どのようにすれば通るのでしょうか? 教えてください。よろしくお願いします。