
初歩的な質問なんですが、この下のプログラムは画像全体にモザイクをかけているものですが、画像上の範囲を指定して、その範囲内の領域だけモザイクをかけるにはどうしたらいいでしょうか?
void make_cmosaic_image()
{
int i,j,x,y,k;
int bsz; /*ブロックサイズ*/
int bx,by;
int bvaIR,bvaIG,bvaIB; /*ブロックの平均値*/
int pels;
int X,Y; /*ピクセルの位置*/
printf("カラー画像のモザイク化\n");
pXdim2=pXdim1;
pYdim2=pYdim1;
printf("ブロックサイズを入力してください(1より大きい値):");
scanf("%d",&bsz);
printf("ブロックサイズは%dである。",bsz);
if(pXdim1 % bsz ==0)
bx= pXdim1 / bsz;
else
bx=pXdim1 / bsz+1;
if(pYdim1 % bsz ==0)
by=pYdim1/bsz;
else
by=pYdim1/bsz+1;
/*モザイク化する*/
for(j=0;j<by;j++)
for(i=0;i<bx;i++){ /*ブロックごと に 計算する*/
/*各ブロックのピクセル平均値を計算する*/
bvaIR = bvaIG =bvaIB=0;
pels=0;
/*各ブロックのピクセル値の和を計算する*/
for(y=0;y<bsz;y++)
for(x=0;x<bsz;x++){
/*現在のピクセルの位置を計算する*/
X=i*bsz+x;
Y=j*bsz+y;
/*この位置が有効であれば、和を計算する*/
if(X>=0 && X<pXdim1 && Y>=0 && Y<pYdim1){
pels++;
/*和を計算する*/
bvaIR +=pimage1[0][Y][X];
bvaIG +=pimage1[1][Y][X];
bvaIB +=pimage1[2][Y][X];
}
}
bvaIR /=pels;
bvaIG /=pels;
bvaIB /=pels;
/*計算した平均値を目的画像へ代入する*/
for(y=0;y<bsz;y++)
for(x=0;x<bsz;x++){
X=i*bsz+x;
Y=j*bsz+y;
if(X>=0 && X<pXdim1 && Y>=0 && Y<pYdim1){
else
pimage2[0][Y][X]=bvaIR;
pimage2[1][Y][X]=bvaIG;
pimage2[2][Y][X]=bvaIB;
} } } }
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
追記。
追加するif文の位置と、条件成立時の文の範囲、不成立時の文の範囲を工夫すれば「今から処理するモザイク1ブロック分が指定範囲外なら、ピクセルの平均や和を演算しなくて済むので演算させないで、元画像を目的画像に単にコピーするだけ」と言う最適化が行えます。
しかし「今から処理するモザイク1ブロック分が指定範囲外かどうかの判定」が複雑になるので、あまりお勧め出来ません。
今から処理するモザイク1ブロック分が、指定範囲と一部分だけ重なってたりした場合など、領域の重なりの判定が複雑になり、下手をすると「判定する処理の方が増えてしまい、逆に遅くなってしまう」と言う事が起きてしまいます。
No.2
- 回答日時:
pimage2[0][Y][X]=bvaIR;
pimage2[1][Y][X]=bvaIG;
pimage2[2][Y][X]=bvaIB;
を
if ((X >= 矩形範囲のX軸の小さいほう) && (X <= 矩形範囲のX軸の大きいほう) && (Y >= 矩形範囲のY軸の小さいほう) && (Y <= 矩形範囲のY軸の大きいほう)) {
pimage2[0][Y][X]=bvaIR;
pimage2[1][Y][X]=bvaIG;
pimage2[2][Y][X]=bvaIB;
} else {
pimage2[0][Y][X]=pimage1[0][Y][X];
pimage2[1][Y][X]=pimage1[1][Y][X];
pimage2[2][Y][X]=pimage1[2][Y][X];
}
にすればよい。例えば(100,150)-(199-249)の矩形の範囲だけにしたいなら
if ((X >= 100) && (X <= 199) && (Y >= 150) && (Y <= 249)) {
pimage2[0][Y][X]=bvaIR;
pimage2[1][Y][X]=bvaIG;
pimage2[2][Y][X]=bvaIB;
} else {
pimage2[0][Y][X]=pimage1[0][Y][X];
pimage2[1][Y][X]=pimage1[1][Y][X];
pimage2[2][Y][X]=pimage1[2][Y][X];
}
にする。
こうすると、モザイクの演算処理は「画像全体に行う」けども「指定範囲外は元画像をそのまま代入し、指定範囲内は画像平均値を代入してモザイクを掛ける」ので、目的通りになる。
なお、元のプログラムは「元画像pimage1から、目的画像pimage2を作る」と言う処理をしているので「必ず、処理は画像全体に対して行う必要がある」ので注意すること。
もし「上記以外の変更を行う」と、つまり「ループの開始値や終了値を変えてしまう」と、目的画像pimage2全体への処理が部分的に欠落し、目的画像pimageが正しく生成されない。
なので「forループの初期値や終了値、関数の冒頭の初期化処理は絶対に変更しない」ように注意する事。
つ~か「この回答で示した部分以外は絶対に変更しない事」です。
ANo.1の回答のような事をすると「目的画像pimage2の範囲外の部分の画素情報が不定になる」ので絶対にダメ。
No.1
- 回答日時:
たぶん、二箇所ある
if(X>=0 && X<pXdim1 && Y>=0 && Y<pYdim1)
の0を開始位置 pXdim1とpYdim1を終了位置の変数に置き換えれば出来ると思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# プログラミング実行後に表示される値を答えよ #include <stdio.h> void main 4 2022/05/28 10:20
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
円の自転のさせ方
-
他のフォームから別のフォーム...
-
アクセスできない保護レベルエ...
-
ユーザーフォームへのデータ入...
-
Access ○or△文の書き方
-
C#のループでtextboxに値を入れ...
-
チェックボックスを操作できな...
-
VB.NETでのイベントの途中終了
-
【VB.NET】テキストボックスに...
-
変数に「.」が含まれる場合...
-
リストビューの列ヘッダーの幅...
-
Excel ユーザーフォームで計算 ...
-
文字列をINTEGER型に変換
-
ループを使ってテキストボック...
-
【VB6.0】 あるフォームから他...
-
テキストボックスかラベル上の...
-
VBA public変数はどのようなこ...
-
助けてください!
-
時間の計算
-
レコードセットにnullの場合
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ボールが壁に当たって跳ね返る...
-
画像処理
-
Matlabでsin波を使って矩形波を...
-
VB6でマウスのドラッグで範囲を...
-
BMPファイルを作成し保存
-
マウスポインタの変更
-
Picture1.Printとしてもpicture...
-
FlexGridで文字色を変更。
-
ピクチャーボックスの画像を印...
-
ベンチマークの実行結果の表示...
-
VB6から.NETへの移行
-
文字間の幅の設定
-
ピクチャボックスの使用方法
-
VBで問題集を作りたい
-
Visual Bassicで画像を回転させ...
-
SCALEの使い方教えてください
-
ピッ、ってアルファベットでど...
-
複雑な条件の書き方
-
Matlab/SimulinkのChirp信号に...
-
[ASP]小数点第2位以下をカット!
おすすめ情報