下記のプログラムは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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- HTML・CSS ブロックエディターで作りつつ、画像を挿入しつつ、画像にスタイルシートのコードを付ける方法はありますか 1 2022/08/23 18:46
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- JavaScript htmlとcssに関する質問です 3 2022/12/06 05:36
- HTML・CSS ヘッダーの画像にメインエリアがかぶってしまいます 1 2022/11/28 14:06
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- HTML・CSS アコーディオンメニューが思うように動作しません。 1 2023/08/20 16:48
- PHP 記述のおかしいところを教えて下さい。 1 2023/02/03 11:25
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・2024年に成し遂げたこと
- ・3分あったら何をしますか?
- ・何歳が一番楽しかった?
- ・治せない「クセ」を教えてください
- ・【大喜利】看板の文字を埋めてください
- ・【大喜利】【投稿~12/17】 ありそうだけど絶対に無いことわざ
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・【穴埋めお題】恐竜の新説
- ・我がまちの「給食」自慢を聞かせてっ!
- ・冬の健康法を教えて!
- ・一番好きな「クリスマスソング」は?
- ・集合写真、どこに映る?
- ・自分の通っていた小学校のあるある
- ・フォントについて教えてください!
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・10代と話して驚いたこと
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
迷路を脱出する経路探索プログ...
-
コマンドプロンプトのウィンド...
-
カードシャッフルのブログラム...
-
C++で表を作成したいのです ...
-
階乗のプログラム
-
迷路の解を見つけるアルゴリズム
-
main関数について
-
c言語8クイーン問題が分かりません
-
四則演算プログラム
-
OpenCVによる4値化について
-
再帰処理をループ処理に変換
-
Cプログラムによる画像の高速フ...
-
C言語プログラミング。
-
条件が多い場合
-
2の補数を計算するプログラム
-
画像の拡大・縮小
-
unsigned int に0xffffffを代入...
-
opencvとmbedのシリアル通信で...
-
信頼区間の1.96や1.65ってどこ...
-
main.c:7:43: warning: implici...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
2の補数を計算するプログラム
-
intとlongは同じ?
-
再起呼び出しの回数をカウント...
-
強連結判定を行うプログラムに...
-
C言語で%を使わない余りの出し方
-
画像の拡大・縮小
-
関数とビット列
-
C++で表を作成したいのです ...
-
カードシャッフルのブログラム...
-
C++ bmp 透過処理
-
プログラミングに関して
-
分数の足し算をさせるプログラ...
-
C言語
-
コマンドプロンプトのウィンド...
-
条件が多い場合
-
迷路を脱出する経路探索プログ...
-
OpenCVによる4値化について
-
opencvとmbedのシリアル通信で...
-
C言語で簡単なパックマンゲーム...
-
3のつく数と3の倍数を表示 C言語
おすすめ情報