現在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;
}
です。よろしくおねがいします。
No.3ベストアンサー
- 回答日時:
★自分のソースと下のソースを全面的に比較してみて下さい。
・コメント、解説、アドバイスなどを注意深く読んで下さい。
/* 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 って使っていないでしょ。必要なの?
No.6
- 回答日時:
★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 さん、ご指摘、本当に有り難うございました。
・以上。
回答ありがとうございました。
お蔭様で無事に作り上げることができました。
ソースまで載せていただき大変感謝しております。
誠にありがとうございました。
No.5
- 回答日時:
#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番目がスルーするのではないかと、
思うのです。
思い違いでしたらすみません。
No.4
- 回答日時:
>●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ピクセル分のデータ
をスルーさせてしませんか?
気のせいかもしれませんが・・・。
No.2
- 回答日時:
勘違いでした、すみません。
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)
だと思いますよ。
No.1
- 回答日時:
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++;
}
}
}
じゃないですか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# プログラミングのペーパーテスト 実行結果の表示を答えてください #include <stdio.h> 2 2022/07/09 16:14
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語 エラーの原因がわからな...
-
比較回数と交換回数表示について
-
複数桁10進数の*桁目だけを抽出...
-
nCmの関数
-
構造体の勉強中です 合計点の高...
-
C言語 配列と関数の練習問題
-
[C言語] 関数を利用する計算
-
実数の整数部,小数部の取得
-
C言語での引数の省略方法
-
数字列を3桁ごとにカンマで区切...
-
アスタリスクでダイヤ型を作る
-
覆面算のプログラムが分かりません
-
C言語の基礎 . 2乗値の差につ...
-
c言語
-
プログラミング
-
【C++】関数ポインタの使い方
-
毎回違う乱数を生成するにはど...
-
if と配列の組み合わせ
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
「指定されたキャストは有効で...
-
C言語 配列と関数の練習問題
-
複数桁10進数の*桁目だけを抽出...
-
(int *)の意味
-
if と配列の組み合わせ
-
ラップ関数とはどんなものですか?
-
卒業研究でよく分からないとこ...
-
【C++】関数ポインタの使い方
-
c言語
-
足して100になるような乱数のア...
-
C言語初心者です、、、お助けく...
-
数字列を3桁ごとにカンマで区切...
-
C言語 エラーの原因がわからな...
-
実数の整数部,小数部の取得
-
課題でつまってます・・・
-
商と剰余を同時に求める(C言語)
-
C言語の配列をC++のvectorに高...
-
std::set<int> で、ある値が何...
おすすめ情報