プロが教えるわが家の防犯対策術!

現在BMPで640×480の画像の左右両端の80画素ずつ切り取り480×480の画像を作って
さらに、8×8のブロックに分けて各ブロックごとの光の強度をだすプログラミングをつくっているのですが、
(各ブロックはそれぞれ[1][1]~[8][8]となづけています)
[1][8]、[2][8]、[3][8]…と8がつくブロックの強度がすべて0になってしまいます。
いろいろと考えてみたのですが、どうにもうまくいかずに悩んでおります。
助けていただけませんでしょうか?
よろしくおねがいします。
おそらく、ここらへんがおかしいと思う部分をのせておきます。

/* 640側の左右80ずつ切り取り、480×480の正方形の画像にする */
int bunkatsu(BMP *rp,RESULT *res){
int x,y;
int a=0;

for(y = 0;y < rp->Bmpi.biHeight; y++){
for(x = 80;x < rp->Bmpi.biWidth - 80; x++){
res->data[a] = rp->blue[y * rp->Bmpi.biWidth + x] + rp->green[y * rp->Bmpi.biWidth + x] + rp->red[y * rp->Bmpi.biWidth + x];
a++;
}
}
return 0;
}

/* 480×480を8×8のブロックに分け(60×60が64ブロック) 、各ブロックの明るさを計算する */
int keisan(BMP *rp,RESULT *res){
int b,c;
int i=0,j=0;
int x,y;
for(y = 0;(y+60) < rp->Bmpi.biHeight;y+=60){
for(x = 0;(x + 60) < (rp->Bmpi.biWidth - 160);x+=60){
for(b = 0;b < 60;b++){
for(c = 0; c < 60;c++){
res->akarusa[i][j]+=res->data[(y + b) * rp->Bmpi.biWidth +(x + c)];
}
}
j++;
}
j=0;
i++;
}
max(res);
return 0;
}

/* 一番明るいブロックの特定 */
RESULT *max(RESULT *res){
int MAX1=0;
int MAX2=0;
int i=0;
int j=0;

for(i = 0;i < 8;i++){
for(j = 0;j < 8;j++){
printf("[%d][%d]=%d ",i+1,j+1,res->akarusa[i][j]);
if(MAX1 < res->akarusa[i][j]){
MAX1 = res->akarusa[i][j];
res->maxi=i;
res->maxj=j;
}
}
printf("\n");
}
printf("一番明るいブロックは[%d][%d]です\n",res->maxi + 1,res->maxj + 1);
return 0;
}
です。よろしくおねがいします。

A 回答 (6件)

★自分のソースと下のソースを全面的に比較してみて下さい。


・コメント、解説、アドバイスなどを注意深く読んで下さい。

/* 640側の左右80ずつ切り取り、480×480の正方形の画像にする */
int bunkatsu( BMP *rp, RESULT *res )
{
 int a = 0; ←分かりやすく pos の名前がよいのでは
 int x, y;
 int ofs; ←追加
 
 for ( y = 0 ; y < rp->Bmpi.biHeight ; y++ ){
  for ( x = 80 ; x < (rp->Bmpi.biWidth - 80 * 2) ; x++ ){ ←(1)
   ofs = (y * rp->Bmpi.biWidth + x); ←追加
   res->data[ a ] = rp->blue[ofs] + rp->green[ofs] + rp->red[ofs]; ←これで良いのか?
   a++;
  }
 }
 return 0;
}
●80 ではなく 160 でしょう。
間違い⇒rp->Bmpi.biWidth - 80
正しい⇒(rp->Bmpi.biWidth - 80 * 2)
※res->data[a] の行はすべてを足して代入してよいのですか?
 つまり、blue[]、green[]、red[] と分けなくてよいのか。

/* 480×480を8×8のブロックに分け(60×60が64ブロック) 、各ブロックの明るさを計算する */
int keisan( BMP *rp, RESULT *res )
{
 int x, y;
 int i, j;
 int ofs; ←追加
 
 for ( y = 0 ; y < (480 / 8) ; y++ ){
  for ( x = 0 ; x < (480 / 8) ; x++ ){
   res->akarusa[ y ][ x ] = 0; ←安全対策(初期化)
   
   for ( j = 0 ; j < 8 ; j++ ){
    for ( i = 0 ; i < 8 ; i++ ){
     ofs = (y * 8 + j) + (x * 8 + i);
     res->akarusa[ y ][ x ] += res->data[ ofs ];
    }
   }
  }
 }
 max( res );
 return 0;
}
●解説
・x, y の for 文で 8×8 のブロックを制御しています。
・i, j の for 文で 8×8 のブロック1つの領域(64)の明るさを加算しています。

/* 一番明るいブロックの特定 */
RESULT *max( RESULT *res )
{
 int MAX1 = 0;
 int MAX2 = 0; ←これ必要か?
 int i, j;
 
 for ( j = 0 ; j < 8 ; j++ ){
  for ( i = 0 ; i < 8 ; i++ ){
   printf( "[%d][%d]=%d ", (j + 1), (i + 1), res->akarusa[j][i] );
   
   if ( res->akarusa[j][i] > MAX1 ){ ←判定方向を変えた方が分かりやすい
    MAX1 = res->akarusa[ j ][ i ];
    res->maxi = i;
    res->maxj = j;
   }
  }
  printf( "\n" );
 }
 printf( "一番明るいブロックは[%d][%d]です\n", (res->maxj + 1), (res->maxi + 1) );
 return 0;
}
●アドバイス
・宣言部の i, j 変数は初期化しないてよい。→理由:for 文で初期化しているから。
・あと習慣的に内側のループに i、外側に j カウンタを使ってみる。
 res->maxi、res->maxj の意味が逆になるため注意!→printf 文の引数を見よ。
・変数 MAX2 って使っていないでしょ。必要なの?
    • good
    • 0

★VTClient さん、ご指摘有り難う。


・8×8 ブロックを 8×8 ピクセルと思い違いをしてしまいました。
 8×8 ブロックなら 60×60 ピクセルにすべきでしたね。恥ずかしいです。
・質問者さんへ。回答 No.3 の keisan() 関数に思い違いをしていたため、見なかったことに
 して下さい。お詫びに修正版を載せます。→大幅に間違っているので関数すべてを載せます。

修正版:
/* 480×480を8×8のブロックに分け(60×60が64ブロック) 、各ブロックの明るさを計算する */
int keisan( BMP *rp, RESULT *res )
{
 int x, y;
 int i, j;
 int ofs; ←追加
 
 for ( y = 0 ; y < 8 ; y++ ){
  for ( x = 0 ; x < 8 ; x++ ){
   res->akarusa[ y ][ x ] = 0; ←安全対策(初期化)
   
   for ( j = 0 ; j < (480 / 8) ; j++ ){
    for ( i = 0 ; i < (480 / 8) ; i++ ){
     ofs = (y * (480 / 8) + j);
     ofs += (x * (480 / 8) + i);
     res->akarusa[ y ][ x ] += res->data[ ofs ];
    }
   }
  }
 }
 max( res );
 return 0;
}
●解説
・x, y の for 文で 8×8 のブロックを制御しています。
・i, j の for 文で 60×60 のピクセル領域の明るさを加算しています。

★VTClientさんへ。回答 No.4 についても間違っていました。
・仰るとおりです。気のせいではありません。私の間違いです。
 質問者さんへ。bunkatsu() 関数に1行だけ間違っていました。修正します。
・修正前⇒for ( x = 80 ; x < (rp->Bmpi.biWidth - 80 * 2) ; x++ ){ ←(1)
 修正後⇒for ( x = 80 ; x < (rp->Bmpi.biWidth - 80) ; x++ ){ ←(1)
 です。この間違いから 80~(rp->Bmpi.biWidth - 80)をループするより、
 0~479 をループして +80 のオフセット値を加算した方が分かりやすいですね。
 この考えを元に bunkatsu() 関数の全体を見直してみました。
 それが下です。

/* 640側の左右80ずつ切り取り、480×480の正方形の画像にする */
int bunkatsu( BMP *rp, RESULT *res )
{
 int a = 0;
 int x, y;
 int ofs;
 
 for ( y = 0 ; y < 480 ; y++ ){ ←分かりやすく 480 にしました。
  for ( x = 0 ; x < 480 ; x++ ){ ←分かりやすく 480 にしました。
   ofs = ((y * rp->Bmpi.biWidth) + (x + 80));
   res->data[ a ] = rp->blue[ofs] + rp->green[ofs] + rp->red[ofs];
   a++;
  }
 }
 return 0;
}

最後に:
・VTClient さん、ご指摘、本当に有り難うございました。
・以上。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
お蔭様で無事に作り上げることができました。
ソースまで載せていただき大変感謝しております。
誠にありがとうございました。

お礼日時:2007/05/21 17:43

#1,#2,#4 の者です。


(Oh-Orangeさん、“さん”を付け忘れました、すみません。)

<説明追記>
for(y = 0;(y+60) < rp->Bmpi.biHeight;y+=60){
for(x = 0;(x + 60) < (rp->Bmpi.biWidth - 160);x+=60)



for(y = 0;(y+60) <= rp->Bmpi.biHeight;y+=60){
for(x = 0;(x + 60) <= (rp->Bmpi.biWidth - 160);x+=60)

と言うのは、1ベースを基に[8]の1次側、2次側共に、
たとえば、x=420,y=420 いずれの場合、(x で説明します。)
x+60=480 となり、rp->Bmpi.biWidth-160=480 なのですから
480<480 が偽となり、8番目がスルーするのではないかと、
思うのです。
思い違いでしたらすみません。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
非常にわかりやすく書いていただき大変ためになりました。
本当にありがとうございました。

お礼日時:2007/05/21 17:44

>●80 ではなく 160 でしょう。


>間違い⇒rp->Bmpi.biWidth - 80
>正しい⇒(rp->Bmpi.biWidth - 80 * 2)

Oh-Orange の仰るとおりかもしれません。
が、気にかかることがあります。

for ( x = 80 ; x < (rp->Bmpi.biWidth - 80 * 2) ; x++ )

x は初期値が80なのですから、これでは80ピクセル分のデータ
をスルーさせてしませんか?
気のせいかもしれませんが・・・。
    • good
    • 0

勘違いでした、すみません。



for(y = 0;(y+60) < rp->Bmpi.biHeight;y+=60){
for(x = 0;(x + 60) < (rp->Bmpi.biWidth - 160);x+=60)



for(y = 0;(y+60) <= rp->Bmpi.biHeight;y+=60){
for(x = 0;(x + 60) <= (rp->Bmpi.biWidth - 160);x+=60)

だと思いますよ。
    • good
    • 0

res->akarusa[i][j]+=res->data[(y + b) * rp->Bmpi.biWidth +(x + c)];


}
}
j++;
}
j=0;
i++;
}

は、

res->akarusa[i][j]+=res->data[(y + b) * rp->Bmpi.biWidth +(x + c)];
j++;
}
j=0;
i++;
}
}
}

じゃないですか?
    • good
    • 0

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