質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Cygwin

Cygwinは、Unixのような環境を、Windows上で構築させるコマンドラインインターフェースです。

Q&A

解決済

4回答

5458閲覧

<c言語>画像のモザイク処理を実現したい

iisan

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Cygwin

Cygwinは、Unixのような環境を、Windows上で構築させるコマンドラインインターフェースです。

0グッド

0クリップ

投稿2021/10/16 13:36

編集2021/10/16 23:52

c言語 画像のモザイク処理を実現したい

画像の左半分を16×16 画素のモザイクをかけて、出力するプログラムを作成したいのですが、現在のプログラムだと一番左の16×16が真っ黒になってしまいます。また、モザイク処理した見本の画像より、モザイクの色が濃くなっています。
これらを解決したいです

発生している問題・エラーメッセージ

出力された画像
イメージ説明
答えの画像
イメージ説明

該当のソースコード

#include <stdio.h> #include "image1.h" #define N 16 void bmp_cool(bmp_header_t *hd, pixel_t img[MAX_Y][MAX_X]); int main(void) { bmp_header_t hd; pixel_t img [MAX_Y][MAX_X]; bmp_read("in.bmp", &hd, img); /* in.bmp から読み込む */ bmp_cool(&hd, img); /* 処理の呼び出し */ bmp_write("out.bmp", &hd, img); /* out.bmp への書き出し */ return 0; } /* 画像処理の関数の本体 */ void bmp_cool(bmp_header_t *hd, pixel_t img[MAX_Y][MAX_X]) { int i, j; pixel_t a[MAX_Y][MAX_X]; //配列aの初期化 for (i=0; i< hd->biHeight; i++) { for (j=0; j< hd->biWidth; j++) { a[i/N][j/N].r = img[i][j].r; a[i/N][j/N].g = img[i][j].g; a[i/N][j/N].b = img[i][j].b; } } //モザイク処理の計算 for (i=0; i< hd->biHeight; i++) { for (j=0; j< hd->biWidth/2; j++) { a[i/N][j/N].r += img[i][j].r; a[i/N][j/N].g += img[i][j].g; a[i/N][j/N].b += img[i][j].b; if(j%16==0) { a[i/N][j/N].r = a[i/N][j/N].r/N; a[i/N][j/N].g = a[i/N][j/N].g/N; a[i/N][j/N].b = a[i/N][j/N].b/N; for(j=0; j< hd->biWidth/2; j++) { img[i][j].r=a[i/N][j/N].r; img[i][j].g=a[i/N][j/N].g; img[i][j].b=a[i/N][j/N].b; } } } } }

補足情報

Cygwinでコンパイルを行っています。
また、現在のプログラムでは3重ループを使っていますが、できるだけ多重ループは避けたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2021/10/16 17:53 編集

画像が表示されていません。``` の囲みを外す等して頂けませんか。
iisan

2021/10/16 23:51

申し訳ありません。教えてくださりありがとうございます。変更いたしました。
jimbe

2021/10/17 03:48 編集

画像表示されました。ありがとうございます。 ただ"モザイク"と言っても、使用する色をどう求めるかは必ずしもRGBの平均を取るとは決まっていないと思うのですが、アルゴリズムは決まって(合って)いるのでしょうか。
iisan

2021/10/17 04:39

16×16 画素毎に (その 256 画素の) 平均値を計算し, その値をその 16×16 画素すべてに代入せよ、という決まりが与えられています。
退会済みユーザー

退会済みユーザー

2021/10/18 04:27 編集

そもそも、学校の課題は非推奨質問です。 https://teratail.com/help/avoid-asking > コードをください・デバッグしてください等の丸投げの質問 > 何かを作りたいのでコードを書いてほしい、学校の課題を解いてほしい等の質問は、具体的にプログラミングで困っている質問ではないと考え、推奨していません。 授業で習ってる範疇の技術で解けるような課題しか出してない筈だから、復習したり学校の先生に判らない点を聞いたりして解決してください。
guest

回答4

0

「//モザイク処理の計算」の三重ループのループカウンタが i,j,j ですので、内側のループがおかしくなっているのではないでしょうか。

投稿2021/10/17 03:57

jimbe

総合スコア13170

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

「16x16 の領域毎に平均値に置き換えたい」という話なのであれば,その話を素直に実装すればよいのではないでしょうか.
(配列 a とかいう謎の物を持ち出したりせずに,16x16の小領域毎に愚直に処理をするコードを書けばよいのでは?)

C

1#define N 16 2 3void bmp_cool( int W, int H, pixel_t img[MAX_Y][MAX_X]) 4{ 5 const int hW = W/2; 6 for( int ymin=0; ymin<H; ymin+=N ) //ymin : 小領域の上端 7 { 8 int ymax = ymin+N-1; //ymax : 小領域の下端 9 if( ymax >= H )ymax = H-1; //※「画像サイズがNの倍数」みたいな前提があるなら不要 10 11 for( int xmin=0; xmin<hW; xmin+=N ) //xmin : 小領域の左端 12 { 13 int xmax = xmin+N-1; //xmax : 小領域の右端 14 if( xmax >= hW )xmax = hW-1; //※「画像横幅の半分がNの倍数」みたいな前提があるなら不要 15 16 //小領域内の合計を求む 17 int R=0, G=0, B=0; 18 for( int y=ymin; y<=ymax; ++y ) 19 { 20 for( int x=xmin; x<=xmax; ++x ) 21 { 22 R += img[y][x].r; 23 G += img[y][x].g; 24 B += img[y][x].b; 25 } 26 } 27 {//平均値にする 28 int n = (ymax-ymin+1) * (xmax-xmin+1); 29 R /= n; 30 G /= n; 31 B /= n; 32 } 33 //結果を格納する 34 for( int y=ymin; y<=ymax; ++y ) 35 { 36 for( int x=xmin; x<=xmax; ++x ) 37 { 38 img[y][x].r = R; 39 img[y][x].g = G; 40 img[y][x].b = B; 41 } 42 } 43 } 44 } 45}

投稿2021/10/18 04:38

編集2021/10/18 04:43
fana

総合スコア11954

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こちらが参考になるかもしれません。

■ 画像処理のモザイクの仕方について
https://teratail.com/questions/219277

投稿2021/10/17 01:25

cx20

総合スコア4646

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iisan

2021/10/17 02:30

回答ありがとうございます。拝見いたしました。こちらで紹介されているプログラムだと、モザイクはかかるのですが、どこか答えとおかしい色のモザイクになってしまいます。
guest

0

C

1#define CEIL(a,b) ((a+b-1)/b) 2void bmp_cool(bmp_header_t *hd, pixel_t img[MAX_Y][MAX_X]) 3{ 4 int i, j; 5 struct{int r, g, b;} a[CEIL(MAX_Y,N)][CEIL(MAX_X,N)] = {0}; 6 for(i=0; i< hd->biHeight; i++){ 7 for(j=0; j< hd->biWidth/2; j++){ 8 a[i/N][j/N].r += img[i][j].r; 9 a[i/N][j/N].g += img[i][j].g; 10 a[i/N][j/N].b += img[i][j].b; 11 } 12 } 13 for(i=0; i<CEIL(hd->biHeight,N); i++){ 14 for(j=0; j<CEIL(hd->biWidth/2,N); j++){ 15 a[i][j].r /= N*N; // 修正 16 a[i][j].g /= N*N; // 修正 17 a[i][j].b /= N*N; // 修正 18 } 19 } 20 for(i=0; i< hd->biHeight; i++){ 21 for(j=0; j< hd->biWidth/2; j++){ 22 img[i][j].r = a[i/N][j/N].r; 23 img[i][j].g = a[i/N][j/N].g; 24 img[i][j].b = a[i/N][j/N].b; 25 } 26 } 27}

(スマホからの投稿のため、動作未確認です)
こんな感じで、サンプリング、平均化、結果の格納を分離してみては?

追記:オーバーフローに関するバグと、2つ目の平均化のループにバグがあった(インデックスがiではなくi/Nになっていた、jも同様)ので修正しました。

投稿2021/10/16 14:21

編集2021/10/18 03:33
majiponi

総合スコア1722

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iisan

2021/10/16 14:52

回答ありがとうございます。実行してみたところ、カラフルなモザイクが左半分に16*16画素で出力されました。見た感じだと、ぼかしたようなモザイクが実現されるだろうと思ったのですが、なぜカラフルなモザイクになるのでしょうか?
majiponi

2021/10/16 15:31

あっ…pixel_t型の正体って、char型だったりしますか?
iisan

2021/10/16 23:55

返信が遅くなり申し訳ありません。pixel_t img[][]のr,g,bはunsigned charです。
y_waiwai

2021/10/17 00:36

平均化するときの積算に問題があります unsigned char では、1バイトしかないため、積算していくとオーバーフローしてワケワカラン値となってしまいますね unsigned char の数値を、16回積算してもオーバーフローしないような変数で積算、平均化する必要があります #はやいはなしが、int型でr,g,bの変数用意してそれ使いましょう。
iisan

2021/10/17 01:00

学校の課題の性質上、投稿したプログラムの部分しか変更できないです。申し訳ありません。型を変更しないで、となると厳しいでしょうか?
y_waiwai

2021/10/17 01:44

変更の必要はなく、積算用の変数を作ればいいです
iisan

2021/10/17 02:36

majiponiさんのプログラムのa[][]の型を、typedef struct { int rr; int gg; int bb; } pixel_s; pixel_s a[CEIL(MAX_Y,N)][CEIL(MAX_X,N)] = {0}; としてみたのですが、変わりませんでした。こういうことではないのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問