RGBからHSVへ変換し求めるには?


ビックマン  2005-12-13 04:06:25  No: 59933

以下のプログラムはfruitsという画像上の(10,10)の場所のRGBを求めるプログラムです。これをRGBからHSVに変換し、(10,10)の場所のHSVの値を求めるようなプログラムにするにはどうすればいいでしょうか?

よろしくお願いします。

#include <stdio.h>
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"

// グローバル変数群
char wndname[] = "Image";
IplImage *img=0;

// 座標(x,y)のRGB値(r,g,b)を参照する関数
int getpixel(IplImage *image, int x, int y, int *r, int *g, int *b){
    *r =(uchar) image->imageData[y *image->widthStep+ x * image->nChannels + 2];
    *g =(uchar) image->imageData[y *image->widthStep+ x * image->nChannels + 1];
    *b =(uchar) image->imageData[y *image->widthStep+x * image->nChannels];
    return 0;  
}

int main( int argc, char** argv ){
    int x=10,y=10; // RGB値を参照する座標
    int r,g,b; // RGB値を格納する変数

    // 画像ファイル読み込み
    char* filename = argc == 2 ? argv[1] : (char*)"fruits.jpg";
    if( (img = cvLoadImage( filename, 1)) == 0 )
        return -1;

    // 画像表示窓の準備
    cvNamedWindow(wndname, 1);

    // 座標(x,y)のRGB値(r,g,b)を参照
    getpixel(img,x,y,&r,&g,&b);
    printf("座標(%d, %d)のRGB値は(%d, %d, %d)です.\n",x,y,r,g,b);

    // 画像表示
    cvShowImage("Image", img);

    // 何かキーを押すと終了
    cvWaitKey(0);

    // 解放
    cvReleaseImage(&img);
    cvDestroyWindow(wndname);

    return 0;
}


L/D  2005-12-13 09:50:52  No: 59934

"RGBからHSV"をgoogleで検索しろ!!


ビックマン  2005-12-14 03:30:35  No: 59935

RGBをHSVへ変換することは出来ました。しかしgetpixelでHSVの値を取得しようとしてもいまいち上手くいっていないようでした。
getpixelではHSVの値を取得することは出来ないのでしょうか?また、出来ないのであればどのような関数を使うことによって取得できるのでしょうか?
以下は私が作成したプログラム(USBカメラで撮影した画像を保存し、その画像をHSVに変換しx,y=(160,120)のHSVの値を取得する)です。

#include "cv.h"
#include "highgui.h"
#include "stdio.h"
#include "cxcore.h"

//グローバル変数群
IplImage *src = 0 , *src2 = 0 ;  //元画像データ
IplImage *hsvImage1 = 0  ;
IplImage *hImage1 = 0 , *sImage1 = 0 , *vImage1 = 0  ;
// グローバル変数群
//IplImage *img=0;

// 座標(x,y)のHSV値(h,s,v)を参照する関数
int getpixel(IplImage *image, int x, int y, int *h, int *s, int *v){
    *h =(uchar) image->imageData[y *image->widthStep+ x * image->nChannels + 2];
    *s =(uchar) image->imageData[y *image->widthStep+ x * image->nChannels + 1];
    *v =(uchar) image->imageData[y *image->widthStep+ x * image->nChannels];
    return 0;  
}

//------
//主関数
//------
int main( int argc, char** argv ){
  int h1  , s1  , v1  ;   //画像のHSVを記憶する変数
  int x=0 ,y=0 ;                      //画像上の座標を記憶する変数
  int key;  //キー入力
  CvCapture* capture = NULL;  //カメラのデバイス

  //カメラが見つからない場合
  if(NULL==(capture = cvCaptureFromCAM(-1))){
    printf("カメラが見つかりませんでした.");
    return -1;
  }

  //画像表示窓の準備
  cvNamedWindow("Capture", CV_WINDOW_AUTOSIZE);// 0を代入すると正方形
  //窓の出現位置
  cvMoveWindow("Capture", 50, 50);

  //処理ループの開始
  for(;;){
    //キャプチャ側から画像を取り出す
    if(NULL==(src=cvQueryFrame(capture))){
      printf("画像の取得ができませんでした.");
      break;
    }

    //画像表示
    cvShowImage("Capture", src);

    //キー入力
    key = cvWaitKey(10);

    //ESCで終了
    if(key==0x1b){
      break;
    exit(0);
  }

  //1キー入力で静止画画像を取得
  if(key==0x31){  
    cvNamedWindow("A still image 1", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("A still image 1", 50, 290);
    cvSaveImage( "A still image 1.bmp", src);

    // 画像ファイル読み込み
    char* filename = argc == 2 ? argv[1] : (char*)"A still image 1.bmp";
    if( (src2 = cvLoadImage( filename, 1)) == 0 )
      return -1;

    cvShowImage("A still image 1", src2);

    hsvImage1 = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 3);
    hImage1 = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
    sImage1 = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
    vImage1 = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
    cvCvtColor(src2, hsvImage1, CV_BGR2HSV); // RGB->HSV
    cvCvtPixToPlane(hsvImage1, hImage1, sImage1, vImage1, 0);// HSV -> H, S, V

    cvNamedWindow("h1", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("h1", 50, 530);
    cvShowImage("h1", hImage1);
    cvNamedWindow("s1", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("s1", 210, 530);
    cvShowImage("s1", sImage1);
    cvNamedWindow("v1", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("v1", 370, 530);
    cvShowImage("v1", vImage1);

    x=160;
    y=120;
    getpixel(hsvImage1,x,y,&h1,&s1,&v1);
    printf("座標(%d, %d)のHSV値は(%d, %d, %d)です.\n",x,y,h1,s1,v1);

    printf("Please input the next command.\n");
  }
  }
  //解放
  cvReleaseCapture(&capture);
  cvDestroyWindow("Capture");

  return 0;
}


シャノン  2005-12-14 05:39:11  No: 59936

> getpixelではHSVの値を取得することは出来ないのでしょうか?

image->imageData に HSV 値が格納されていなければ、このコードでは無理でしょう。

> また、出来ないのであればどのような関数を使うことによって取得できるのでしょうか?

IPL に関する知識がないのでわかりません。
IPL のリファレンスを見て探すなり、IpImage::imageData の内部形式が載っているならそれを見て変換関数を書くなりしてください。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加