- ベストアンサー
C言語による画像処理で出力時に文字化け
- C言語による画像処理で出力時に文字化けが発生しています。fxとfyの数値を修正しても問題が解決しません。
- 画像の読み込み、Sobelオペレータによるエッジ検出、画像の書き込みまでの処理に問題はありません。
- 文字化けの原因を特定するために、画像データの形式やファイルの読み書き処理を確認してください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>平滑化してからsobelフィルタをかけたものも作ったのですが、 >平滑化だけのものと、その後にsobelフィルタをかけたもので、 >差がありませんでしたなぜなのでしょうか・・・ 今度まともにソースすら見ていません ブログラムを2つに分けてみてください 平滑化のみを行った画像 平滑化を行った画像を使ってそーべる処理を行った結果 これを比較してください 多分動いてるんじゃないですか? 両方まとめて処理した時に動いていないのは 動いていないのではなくて両方の処理したデータだけを 連続的に同じファイルに書いているからです
その他の回答 (3)
- koi1234
- ベストアンサー率53% (1866/3459)
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; }
- pixie-grasper
- ベストアンサー率49% (28/57)
その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; }
- wormhole
- ベストアンサー率28% (1626/5665)
>http://image.onishi-lab.jp/002.html#1 参考にされているurlに書かれているプログラムはP5やP6のバイナリファーマット用なのに、それをほぼそのままASCII形式のP2で使用してるからです。
お礼
解決しました。元々違和感はあったのですが、*rに、フィルタリングした数値を一々入れていたのが原因でした。これではエッジ検出できないわけです。tmpに直接代入したらいけました。 前回同様デバッグが苦手です・・・隅から隅まで見たらどうでもいいところばかり試行錯誤し、焦点を絞ったら初歩的ミスや盲点を見逃す・・・ ご回答ありがとうございました。
補足
それは既にしてみたのですが、あなたがそう仰るなら、たぶんそこに原因はなく、フィルタ自体に原因があるとみて、焦点を絞って調べようと思います。