重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

IplImageをHSの閾値から2値化をしようとしています.
表示させたい画像は1920x1080で取り込んだ1枚の画像の2値化です.
しかし以下のプログラムを実行し実際画像を見てみると,
1枚の画像の中にx=1080以降から
同じ画像がもう一枚でてきます.

どうすれば一枚の画像をそのまま2値化して表示することができますか?
よろしくおねがいします.

xx=1920;
yy=1080;

for(yy = 0; yy < frame->height; yy++)
{
  for(xx = 0; xx < frame->width; xx++)
  {
if(HSV[yy][xx].H > HMin && HSV[yy][xx].H < HMax && HSV[yy][xx].S > SMin && HSV[yy][xx].S < SMax)
{
  src_buf[frame->width * yy + xx] = 1;
  frame->imageData[frame->widthStep * yy + xx * 3] = 0x00;
  frame->imageData[frame->widthStep * yy + xx * 3 + 1] = 0x00;
  frame->imageData[frame->widthStep * yy + xx * 3 + 2] = 0x00;
}
else{
  src_buf[frame->width * yy + xx] = 0;
  frame->imageData[frame->widthStep * yy + xx * 3] = 0xff;
  frame->imageData[frame->widthStep * yy + xx * 3 + 1] = 0xff;
  frame->imageData[frame->widthStep * yy + xx * 3 + 2] = 0xff;
}
  }
}

「IplImageをHSの閾値から2値化を」の質問画像

A 回答 (1件)

・frameの中身: cvCreateImage等の設定はどうなっているのか


・src_bufの中身: 変数宣言、領域確保など
・HSVの中身: 変数宣言、領域確保、この箇所に来た段階での値など
・画像の作成方法: frame をcvSaveImageしたもの?

と、わからない点が多いので、この部分が正しいかどうか判断できません。

また
> xx=1920;
> yy=1080;
としたものをループカウンタに使ってしまっていますが、これはよいのですか?
ループ終了時点で xx = frame->width, yy=frame->heghtになって、元にもどっているかもしれませんが。

この回答への補足

説明が不足していてすみません.
一応デバックして,2値化の処理の手前までは通常に画像が表示されていたので,
ここの部分が原因かと思い貼り付けてしまいました…

>> xx=1920;
>> yy=1080;
>としたものをループカウンタに使ってしまっていますが、これはよいのですか?
>ループ終了時点で xx = frame->width, yy=frame->heghtになって、元にもどっているかもしれませんが。

の部分ですが,これは掲示板で書き込む際に間違えて書き込んでしまいました.ややこしくてすみません.

不足していたプログラムを以下に貼り付けます.
この続きが上記のプログラムへ続きます.
bmpへの表示はSaveImage("output.bpm",frame);をつかっています.

struct _HSV
{
int H;
int S;
int V;
}HSV[1920][1080];

int main (int argc, char **argv)
{
…  //初期設定

// (1)コマンド引数によって指定された番号のカメラに対するキャプチャ構造体を作成する
if (argc == 1 || (argc == 2 && strlen (argv[1]) == 1 && isdigit (argv[1][0])))
capture = cvCreateCameraCapture (argc == 2 ? argv[1][0] - '0' : 0);
/* この設定は,利用するカメラに依存する*/
// (2)キャプチャサイズを設定する.
cvNamedWindow ("Capture", CV_WINDOW_AUTOSIZE);
frame = cvQueryFrame (capture);
src_buf = new short[ frame->width * frame->height ];
// (3)カメラから画像をキャプチャする
while (1)
  {
  frame = cvQueryFrame (capture);
for(y = 0; y < frame->height; y++)
{
for(x = 0; x < frame->width; x++)
{
  p[0] = frame->imageData[frame->widthStep * y + x * 3]; // B
  p[1] = frame->imageData[frame->widthStep * y + x * 3 + 1]; // G
  p[2] = frame->imageData[frame->widthStep * y + x * 3 + 2]; // R
  if (p[0] >= p[1] && p[0] >= p[2]){max = p[0];} //Bがmax
  else if (p[1] >= p[0] && p[1] >= p[2]){max = p[1];} //Gがmax
  else{max = p[2];} //Rがmax

  if (p[0] <= p[1] && p[0] <= p[2]){min = p[0];} //Bがmin
  else if (p[1] <= p[0] && p[1] <= p[2]){min = p[1];} //Gがmin
  else{min = p[2];} //Rがmin

  if(max==min){
HSV[y][x].H = 0;
HSV[y][x].S = 0;
HSV[y][x].V = p[0]; //R
  }
  else
  {
if(max==p[2])
        {
  HSV[y][x].H = 60 * (p[1]-p[0])/(max-min);
}
else if(max==p[1])
{
  HSV[y][x].H = 60 * (p[0]-p[2])/(max-min);
  HSV[y][x].H += 120;
}
else
{
  HSV[y][x].H = 60 * (p[2]-p[1])/(max-min);
  HSV[y][x].H += 240;
}

補足日時:2010/01/27 07:49
    • good
    • 0
この回答へのお礼

ややこしくなってすみません、以下に続きです。
if(HSV[y][x].H<0){ HSV[y][x].H += 360;}
  HSV[y][x].S = 256*(max-min)/max;//s /= max; 円柱モデルの場合
  HSV[y][x].V = max;
  }
}
  }
です.

・frameの中身: cvCreateImage等の設定はどうなっているのか
動画像をの一枚の静止画を取り込んでいます.
frameに移すときはcvQueryFrameを使用しています.

・src_bufの中身: 変数宣言、領域確保など
>src_buf = new short[ frame->width * frame->height ];
で領域を確保しています.

・HSVの中身: 変数宣言、領域確保、この箇所に来た段階での値など
>HSVはプログラムの最初に示していた構造体を使用しています.
今プログラムを動かせる環境ではないために値を見ることができませんが正常値でした.

・画像の作成方法: frame をcvSaveImageしたもの?
>cvSaveImageを使用しています.

長々と申し訳ありません.
回答ありがとうございます.
よろしくおねがいします.

お礼日時:2010/01/27 08:01

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!