http://image.onishi-lab.jp/002.html#1
ここを参考にsobelオペレータによるエッジ検出をしようとしています。
fxとfyのところを考えるのですが、とりあえず1にして出力したら文字化けしました。
文字化けの原因を教えてください。
読み込む画像は横160ピクセル、縦70ピクセルのP2形式のpgmファイルです。
#include <stdio.h>
#include <stdlib.h>
int pgm_read(char *filename, unsigned char *pimage){
FILE *fp;
if((fp=fopen(filename,"rb"))==NULL){
printf("ファイル%sが開けません\n",filename);
exit(-1);
}
fscanf(fp,"P2\n160 70\n255\n"); //ヘッダを読み飛ばす
fread(pimage,sizeof(char),160*70,fp);
fclose(fp);
return 0;
}
int pgm_write(char *filename, unsigned char *pimage){
FILE *fp;
fp=fopen(filename,"wb");
fprintf(fp,"P2\n160 70\n255\n");
fwrite(pimage,sizeof(char),160*70,fp);
fclose(fp);
return 0;
}
main(){
unsigned char *image; //取り込む画像
unsigned char *edge; //エッジ画像
int x,y;
int fx,fy; //オペレータグラジエントの強度
FILE *fp;
image = malloc(sizeof(char)*160*70); //メモリの確保
edge = malloc(sizeof(char)*160*70);
pgm_read("input.pgm", image); //ファイルの読み込み
for(y=1;y<70-1;y++){ //Sobel オペレータ
for(x=1;x<160-1;x++){
fx = 1;// ここを考える
fy = 1;// ここを考える
if(fx*fx+fy*fy>500) *(edge+160*y+x) = 0x00; //閾値より大きいところは黒
else *(edge+160*y+x) = 0xff; //それ以外は白
}
}
pgm_write("output.pgm", edge); //ファイルの書き込み
free(image); //メモリの開放
free(edge);
}
文字化けの様子は
P2
160 70
255
^@^@^@^@^@^@^@^@・・・
^@\377\377\377・・・
みたいな感じです。
No.4ベストアンサー
- 回答日時:
>平滑化してからsobelフィルタをかけたものも作ったのですが、
>平滑化だけのものと、その後にsobelフィルタをかけたもので、
>差がありませんでしたなぜなのでしょうか・・・
今度まともにソースすら見ていません
ブログラムを2つに分けてみてください
平滑化のみを行った画像
平滑化を行った画像を使ってそーべる処理を行った結果
これを比較してください
多分動いてるんじゃないですか?
両方まとめて処理した時に動いていないのは
動いていないのではなくて両方の処理したデータだけを
連続的に同じファイルに書いているからです
この回答への補足
それは既にしてみたのですが、あなたがそう仰るなら、たぶんそこに原因はなく、フィルタ自体に原因があるとみて、焦点を絞って調べようと思います。
補足日時:2013/06/30 08:31解決しました。元々違和感はあったのですが、*rに、フィルタリングした数値を一々入れていたのが原因でした。これではエッジ検出できないわけです。tmpに直接代入したらいけました。
前回同様デバッグが苦手です・・・隅から隅まで見たらどうでもいいところばかり試行錯誤し、焦点を絞ったら初歩的ミスや盲点を見逃す・・・
ご回答ありがとうございました。
No.3
- 回答日時:
No2 の補足に関して (質問文と合わせて全文ちゃんと見てません)
if(fprintf(fp,"%d\n",tmp) < 0)
tmpに値を代入してる部分がどこにもないようですが・・・・
デバックモードなどでたまたま0になってるってだけの話ではないですか?
この回答への補足
うっかりしていました。
tmpもいれ、sobelフィルタを3×3にして作りました。
するとQRコードみたいな画像が出力されました・・・。
また、平滑化してからsobelフィルタをかけたものも作ったのですが、平滑化だけのものと、その後にsobelフィルタをかけたもので、差がありませんでした。
なぜなのでしょうか・・・
以下、平滑化→sobelフィルタをかけるプログラムです。
/*平滑化ここから*/~/*平滑化ここまで*/を取り除いたプログラムが、sobelフィルタだけのプログラム(QRコードが出力)です。
Picture* edge(FILE* fp,Picture* pPic,int type){
int i,j,k; /* ループ用変数 */
unsigned char tmp; /* 作業用変数 */
unsigned char *r,*g,*b; /* 作業に使用するポインタ */
if(fp == NULL ||
pPic == NULL ||
(type < 1 || type >6)) /* 引数が異常 */
return NULL;
r = pPic->r;
g = pPic->g;
b = pPic->b;
/* ファイルヘッダの出力 */
if(fprintf(fp,"P%d\n%d %d\n",type,pPic->x,pPic->y) < 0)
return NULL;
if(type == 2 || type == 3 || type == 5 || type == 6){
if(fprintf(fp,"255\n") < 0)
return NULL;
}
/* 画像データの出力 */
/* 2値ascii形式 */
/*平滑化ここから*/
for(i=0 ; i<pPic->y ; i++){
for(j=0 ; j<pPic->x ; j++){
*r =(*(r-1)+*r+*(r+1))/3; //平滑化
tmp=*r;
r++;
if(fprintf(fp,"%d\n",tmp) < 0)
return NULL;
}
}
r=r-(pPic->x*pPic->y);
/*平滑化ここまで*/
for(i=0 ; i<pPic->y ; i++){
for(j=0 ; j<pPic->x ; j++){
*r=*(r-1-(pPic->x))*(-1)+*(r+1-(pPic->x))+*(r-1)*(-2)+*(r+1)*2+*(r-1+(pPic->x))*(-1)+*(r+1+(pPic->x));
tmp = (int)sqrt(*r**r);
r++;
//printf("%d\n",tmp);
if(fprintf(fp,"%d\n",tmp) < 0)
return NULL;
}
}
return pPic;
}
int main(void)
{
FILE *fpi,*fpo;
char *fnamei = "input.pgm";
char *fnameo = "output.pgm";
fpi = fopen( fnamei, "r" );
if( fpi == NULL ){
printf( "%s error", fnamei );
return -1;
}
fpo=fopen(fnameo,"w");
edge(fpo,getPpm(fpi),2);
fclose;
return 0;
}
No.2
- 回答日時:
そのpgmファイルをcatしたのですか?
このコードから察するに、pgmファイルは端末に出力して読める形式ではなく、ビットマップ画像を表示できる類の専用のソフトを用いなければならないバイナリファイルになっているはずです。
端末に出力してその結果になった場合、恐らく^@は0x00を、\377は0xffを指します。動作は正常です。
不安であればbviやhexdump等のバイナリビュワーを用いて見てみましょう。
あるいは、専用の画像ビュワーを用いてpgmファイルを開いてみてはどうでしょう?
この回答への補足
バイナリ形式なのが問題だったのですね。みなさんご回答ありがとうございます。
今度は
http://www.mm2d.net/c/c-08.shtml
を参考に、アスキー形式で作りました。
しかし出力が全部0になってしまい、画像は真っ黒です。
なにが原因なのか教えていただけないでしょうか。
sobelオペレータをかけた関数部とmain関数だけ抜粋しました(字数上)
getPpmとputPpmは、入力関数と出力関数です。
*gとか*bとかtypeとかはいらないですが気にしないでください・・・
Picture* edge(FILE* fp,Picture* pPic,int type){
int i,j,k; /* ループ用変数 */
unsigned char tmp; /* 作業用変数 */
unsigned char *r,*g,*b; /* 作業に使用するポインタ */
if(fp == NULL ||
pPic == NULL ||
(type < 1 || type >6)) /* 引数が異常 */
return NULL;
r = pPic->r;
g = pPic->g;
b = pPic->b;
/* ファイルヘッダの出力 */
if(fprintf(fp,"P%d\n%d %d\n",type,pPic->x,pPic->y) < 0)
return NULL;
if(type == 2 || type == 3 || type == 5 || type == 6){
if(fprintf(fp,"255\n") < 0)
return NULL;
}
/*処理*/
for(i=0 ; i<pPic->y ; i++){
for(j=0 ; j<pPic->x ; j++){
*(r++) =*(r-1)*(-1)+*(r+1); //-1 0 1のsobelフィルタにかけたつもり…
if(fprintf(fp,"%d\n",tmp) < 0)
return NULL;
}
}
return pPic;
}
int main(void)
{
FILE *fpi,*fpo;
char *fnamei = "input.pgm";
char *fnameo = "output.pgm";
fpi = fopen( fnamei, "r" );
if( fpi == NULL ){
printf( "%s error", fnamei );
return -1;
}
fpo=fopen(fnameo,"w");
edge(fpo,getPpm(fpi),2);
fclose;
return 0;
}
No.1
- 回答日時:
>
http://image.onishi-lab.jp/002.html#1参考にされているurlに書かれているプログラムはP5やP6のバイナリファーマット用なのに、それをほぼそのままASCII形式のP2で使用してるからです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【C言語】ファイルを読み込んで...
-
ファイルへの書込み処理が異常...
-
C言語にてXMLファイルから任意...
-
C言語による画像処理で出力時に...
-
C言語 複数指定したファイルの...
-
ファイル出力で改行を入れたい!
-
C言語におけるファイル読み込み...
-
複数ファイルの同時読み込みの...
-
csvファイルの読み込みで失敗し...
-
ファイルの特定行の抽出
-
c言語でのfscanfについて
-
初心者のc言語
-
ファイルを読み込んだ時に同じ...
-
C言語 連番データの読み込み
-
テキストファイル内に対して, ...
-
c言語でデータの指定列の度数分...
-
エラーがわかりません、、
-
ボイヤームーア法について
-
fopen用の関数を作りたいです。
-
「指定されたキャストは有効で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
複数ファイルの同時読み込みの...
-
c言語でのfscanfについて
-
ガンマ変換 C言語でプログラ...
-
fopenでファイル名に、変数を使...
-
エラーがわかりません、、
-
ファイル出力で改行を入れたい!
-
C言語でクロマキー合成をする方法
-
C言語でファイル読み書きを早く...
-
ファイルが読み込めない・・・
-
テキストファイル内に対して, ...
-
ファイルへの書込み処理が異常...
-
fscanfでループしてしまう。
-
音声データを出力するCプログラ...
-
fgets関数の利用 c言語
-
fgets( ) の返り値は何?
-
日本語ファイル名のFTPについて
-
大量の入力ファイルを扱うとき...
-
二分探索木への挿入
-
【C言語】ファイルを読み込んで...
-
[C言語]2つのファイルを用いた...
おすすめ情報