下記のプログラムはPGM画像に組織的ディザ法を行い、2値化を行うプログラムなのですがうまく作動しません。
どこがダメなのかわかる方回答お願いします。
また、PGMのフォーマットをP5しか読み込むことしか出来ないのですが、これを
P2のアスキーで読み込めるように変更できないでしょうか?
/* 組織的ディザ法のプログラム dither.c */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"mypgm.h"
#define BLOCK_SIZE 4 /* ブロックの横(=縦)画素数 */
#define NEW_LEVEL 16 /* 擬似階調数(= BLOCK_SIZE の2乗) */
#define MAXWIDTH 1000
#define MAXHEIGHT 1000
/* 原画像 image1[y][x] のディザ画像を作り image2[y][x] に代入 */
void make_dither_image( )
{
double width; /* 16段階画像の階調値の単位幅 */
int x,y,i,j,m,n;
int x_block = x_size1 / BLOCK_SIZE; /* 横のブロック数 */
int y_block = y_size1 / BLOCK_SIZE; /* 縦のブロック数 */
int gray_16 = (int)( image1[y][x] / width ); /* 新しい階調(16階調での値) */
/* Bayer 型ディザ行列 */
int dither_matrix [4][4] = {
{ 0, 8, 2, 10},
{12, 4, 14, 6},
{ 3, 11, 1, 9},
{15, 7, 13, 5}
};
/* 横,縦の画素数がBLOCK_SIZEの倍数であるかのチェック */
if ( x_size1 % BLOCK_SIZE != 0 || y_size1 % BLOCK_SIZE != 0 ){
printf("原画像の横・縦の画素数が不適切です.\n");
exit(1);
}
/* 16階調の画像を作る */ //一度、画像を16階調に変換して(正確にはディザブロック分の1)さらに2階調(白黒)に変換する。
width = MAX_BRIGHTNESS / (double)NEW_LEVEL;
x_size2 = x_size1; y_size2 = y_size1;
for (y = 0; y < y_size1; y ++ ){
for (x = 0; x < x_size1; x ++ ){
if ( gray_16 > NEW_LEVEL - 1 ) gray_16 = NEW_LEVEL - 1;
image2[y][x] = (unsigned char)gray_16;
}
}
/* ディザ画像を作る */
printf("ディザ画像を作ります.\n");
for (i = 0; i < y_block; i ++ ){
for (j = 0; j < x_block; j ++ ){
int x = BLOCK_SIZE * j;
int y = BLOCK_SIZE * i;
for (m = 0; m < BLOCK_SIZE; m ++ ){
for (n = 0; n < BLOCK_SIZE; n ++ ){
if ( image2[y + m][x + n] <= dither_matrix[m][n] ) image2[y + m][x + n] = 0;
else image2[y + m][x + n] = MAX_BRIGHTNESS;
}
}
}
}
}
【mypgm.h】
http://cis.k.hosei.ac.jp/~wakahara/mypgm.h
No.1ベストアンサー
- 回答日時:
P2形式のPGMに対応したいのであれば、画像読み込みルーチンの方をP2に対応させる必要がありますが、
今回挙げられているディザ処理そのものは、今のままでまったく問題はありません。
画像読み込み部の対応ですが、ヘッダ部はP5もP2も同じです。
実データ読み取り部で、P2だった時は fgetc の代わりに、
---
int value;
fscanf(fp, "%d", &value);
image[y][x] = value;
---
といったコードにするだけでいけます。
あと、今回の質問とは直接関係ありませんが、
4×4のディザの階調数は16ではなく17です。(「1が0個」~「1が16個」の17通り)
今のコードだと、一番明るい白が輝度値15にしていますが、15の時は4x4の左下が0になってしまい、全面白ではなく、黒の点が出てきます
この回答への補足
mtaka2さん
回答ありがとうございます。
mtaka2さんの言われたとおりに
int value;
fscanf(fp, "%d", &value);
image[y][x] = value;
に変更いたしましたが、P2のPGMファイルを読み込むと
「ファイルのフォーマットがP5ではありません」
と出てきて、操作を終了してしまいます。
下記のプログラムを変えなければならないのでしょうか?
初心者のために答えがわかりません。教えていただけないでしょうか。
fgets(buffer, MAX_BUFFERSIZE, fp);
if (buffer[0] != 'P' || buffer[1] != '5')
{
printf(" ファイルのフォーマットがP5ではありません\n\n");
exit(1);
No.2
- 回答日時:
・P2(テキスト)形式のpgmは、ファイルの先頭(1行目)が「P2」で始まります。
・P5(バイナリ)形式のpgmは、ファイルの先頭(1行目)が「P5」で始まります。
> if (buffer[0] != 'P' || buffer[1] != '5')
このif文は、「1文字目がP以外」もしくは「2文字目が5以外」だったら、真になり、printfとexitを実行します。
その結果、2文字が「P5」だった時にかぎり、exitしないという動作になります。
ですから「P2専用」にするなら、ここの「5」を「2」にすればOKです。
余力があるなら、「P2」と「P5」のどちらでも終了しないようにして、
P2のときはデータ読み込みにfscanfを使い、P5の時はfgetc、と使い分けるようなコードにした方がいいでしょう。
この回答への補足
コンパイルに成功し、P2のPGMデータも読み込み、ディザ画像を作ることに成功しました。本当にありがとうございます。
しかし、その画像が真っ黒でした…
どうしてなのでしょうか?
何度も初心者の質問をしてしまい、本当にすいません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・【大喜利】【投稿~1/31】『寿司』がテーマの本のタイトル
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
2の補数を計算するプログラム
-
C言語の問題
-
OpenCVでのメモリエラーについて
-
DXライブラリによるパズルゲー...
-
コマンドプロンプトのウィンド...
-
C++ Debug Errorについて教えて
-
rand()の乱数は何故良くないの?
-
C++で表を作成したいのです ...
-
再帰処理をループ処理に変換
-
16bitで乱数を生成する方法
-
迷路を脱出する経路探索プログ...
-
画像の拡大・縮小
-
intとlongは同じ?
-
カードシャッフルのブログラム...
-
信頼区間の1.96や1.65ってどこ...
-
「Aに対するBの割合」と「Aに対...
-
エクセルの問題です。絶対値の...
-
Aの値からBの値を除するとは??
-
プログラミング初心者です。 Py...
-
C言語 エラーの原因がわからな...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
おすすめ情報