質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

1799閲覧

Segmentation fault: 11の原因

mothi5656

総合スコア27

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2020/10/29 12:55

編集2020/10/30 16:25

以下のコードでforeground.ppmを前景画像,background.ppmを背景画像として 前景画像の各画素値において赤の値がα以下, かつ緑の値がβ以上, かつ青の値がγ以下の時, その画素を背景画像の同じ場所の画素に置き換え, その結果を画像output.ppmに出力したいのですが、Segmentation fault: 11とエラーが出ました。chroma_key関数を書き終えてからエラーが出始めたのでそこが原因だとは思うのですが、原因がわからないので教えて欲しいです。

#include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #include <ctype.h> /* 画像の構造体 */ typedef struct{ int width; int height; float **r; float **g; float **b; }ColorImage; /* 1ワード読み込む関数 */ void getword(FILE *fp, char *word); /* PPMフォーマットの画像を読み込む関数 */ void loadPPM(char* filename, ColorImage *ci); /* 画像をPPMフォーマットで書き出す関数 */ void savePPM(char* filename, ColorImage *ci); /* ネガポジ変換 */ void nega_posi(ColorImage *cimage); /* コントラスト強調 */ void contrast(ColorImage *cimage); /* ガンマ補正 */ void gamma_ps(ColorImage *cimage); /* 量子化 */ void quantize(ColorImage *cimage); /* クロマキー */ void chroma_key(ColorImage *fg, ColorImage *bg); int main(void) { char *outputfile={"output.ppm"}; char *inputfile={"peppers.ppm"}; ColorImage cimage[2]; int pros=4; /*0:ネガポジ、1:コントラスト強調、2:ガンマ補正、 3:量子化、4:クロマキー*/ if(pros==0){ //ネガポジ loadPPM(inputfile, cimage); nega_posi(cimage); savePPM(outputfile, cimage); } else if(pros==1){ loadPPM(inputfile, cimage); contrast(cimage); savePPM(outputfile, cimage); } else if(pros==2){ loadPPM(inputfile, cimage); gamma_ps(cimage); savePPM(outputfile, cimage); } else if(pros==3){ loadPPM(inputfile, cimage); quantize(cimage); savePPM(outputfile, cimage); } //Chroma Key else { loadPPM("foreground.ppm", cimage); loadPPM("background.ppm", &cimage[1]); chroma_key(cimage, &cimage[1]); savePPM(outputfile, cimage); } return 0; } void nega_posi(ColorImage *cimage) { /*y(i, j) = 255 − x(i, j) に基づいてネガポジ変換する*/ int i,j; for(i=0;i<cimage->height;i++){ for(j=0;j<cimage->width;j++){ cimage->r[i][j]=255-cimage->r[i][j]; cimage->g[i][j]=255-cimage->g[i][j]; cimage->b[i][j]=255-cimage->b[i][j]; } } } void contrast(ColorImage *cimage) { int i,j; for(i=0;i<cimage->height;i++){ for(j=0;j<cimage->width;j++){ cimage->r[i][j]=1.5*cimage->r[i][j]-10; cimage->g[i][j]=1.5*cimage->g[i][j]-10; cimage->b[i][j]=1.5*cimage->b[i][j]-10; } } } void gamma_ps(ColorImage *cimage) { int i,j; for(i=0;i<cimage->height;i++){ for(j=0;j<cimage->width;j++){ cimage->r[i][j]=powf(cimage->r[i][j],1.4); cimage->g[i][j]=powf(cimage->g[i][j],1.4); cimage->b[i][j]=powf(cimage->b[i][j],1.4); } } } void quantize(ColorImage *cimage) { int i,j; for(i=0;i<cimage->height;i++){ for(j=0;j<cimage->width;j++){ /*この場合は7ビットにビットシフトを用いて量子化する*/ cimage->r[i][j]=((int)cimage->r[i][j]>>(8-1))<<(8-1); cimage->g[i][j]=((int)cimage->g[i][j]>>(8-1))<<(8-1); cimage->b[i][j]=((int)cimage->b[i][j]>>(8-1))<<(8-1); } } } // insert forground image into background. void chroma_key(ColorImage *fg, ColorImage *bg) { int i,j; int a,b,c; a=150; b=150; c=150; for(i=0;i<fg->height;i++){ for(j=0;j<fg->width;j++){ if(fg->r[i][j]<a && fg->g[i][j]>b && fg->g[i][j]<c) { fg->r[i][j]=bg->r[i][j]; fg->g[i][j]=bg->g[i][j]; fg->b[i][j]=bg->b[i][j]; } else { fg->r[i][j]=fg->r[i][j]; fg->g[i][j]=fg->g[i][j]; fg->b[i][j]=fg->b[i][j]; } } } } void savePPM(char* filename, ColorImage *ci) { /* save file in PGM P3 format */ int i, j; FILE *out; /* ファイルをオープン */ out=fopen(filename, "w"); /* ファイルが存在しなければエラー */ if (out==NULL){ printf("Cannot open file\n"); exit(0); } /* ファイルのヘッダ情報を書き出す */ fprintf(out, "P3\n%d %d\n255\n", ci->width, ci->height); /* 画素値を書き出す */ /* 画素値を0~255に制限するプログラム */ for(i=0;i<ci->height;i++){ for(j=0;j<ci->width;j++){ if(ci->r[i][j]<0){ ci->r[i][j]=0; } if(ci->r[i][j]>=255){ ci->r[i][j]=255; } if(ci->g[i][j]<0){ ci->g[i][j]=0; } if(ci->g[i][j]>=255){ ci->g[i][j]=255; } if(ci->b[i][j]<0){ ci->b[i][j]=0; } if(ci->b[i][j]>=255){ ci->b[i][j]=255; } } } for(i=0;i<ci->height;i++){ for(j=0;j<ci->width;j++){ fprintf(out, "%d ", (int)ci->r[i][j]); fprintf(out, "%d ", (int)ci->g[i][j]); fprintf(out, "%d ", (int)ci->b[i][j]); } } fclose(out); } void loadPPM(char* filename, ColorImage *ci) { char word[1000]; int i,j; FILE *in; in=fopen(filename, "rb"); if(in==NULL){ printf("Cannot open file\n"); exit(0); } getword(in, word); getword(in, word); sscanf(word,"%d",&(ci->width)); getword(in, word); sscanf(word,"%d",&(ci->height)); getword(in, word); ci->r=(float **)malloc(ci->height*sizeof(float *)); ci->g=(float **)malloc(ci->height*sizeof(float *)); ci->b=(float **)malloc(ci->height*sizeof(float *)); if(ci->r==NULL||ci->g==NULL||ci->b==NULL) { printf("Error in malloc"); exit(0); } for(i=0;i<ci->height;i++){ ci->r[i]=(float *)malloc(ci->width*sizeof(float)); ci->g[i]=(float *)malloc(ci->width*sizeof(float)); ci->b[i]=(float *)malloc(ci->width*sizeof(float)); if(ci->r[i]==NULL||ci->g==NULL||ci->b==NULL) { printf("Error in malloc"); exit(0); } } /*discard one CR*/ fgetc(in); for(i=0;i<ci->height;i++){ for(j=0;j<ci->width;j++){ int tmpr, tmpg, tmpb; fscanf(in, "%s", word); sscanf(word,"%d",&(tmpr)); fscanf(in, "%s", word); sscanf(word,"%d",&(tmpg)); fscanf(in, "%s", word); sscanf(word,"%d",&(tmpb)); ci->r[i][j]=(float)tmpr; ci->g[i][j]=(float)tmpg; ci->b[i][j]=(float)tmpb; } } fclose(in); } void getword(FILE *fp, char *word) { fscanf(fp, "%s", word); /* while(word[0]=='#'){ fscanf(fp, "%s", word); }*/ if(word[0]=='#'){ while(word[0]!=10){ word[0]=(int)fgetc(fp); } fscanf(fp, "%s", word); } } コード

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2020/10/29 14:07

chroma_key()関数をコメントアウトして、エラーが出なければ、可能性は高いですね。fg と bgのサイズが同じ前提となっていますが、それも問題ないでしょうか? 丁寧にみる気合がないので、ざっと気が付いたところで。
thkana

2020/10/29 21:46

foreground.ppmとbackground.ppmの先頭部分(画像の情報)はそれぞれどうなっていますか。
mothi5656

2020/10/30 00:41

一応どちらもサイズ、階調は同じです
DreamTheater

2020/10/30 01:41

書き換える苗のchroma_key関数とコード比較しては? 添え字の範囲とか変わってないですか?
mothi5656

2020/10/30 06:08

66,67行目の画像を他のものにしたらコンパイル自体はとおりました、、、
mothi5656

2020/10/30 16:27

height と width を入れ替えたら、実行はできるが特に変化のない画像が出力されました。
guest

回答1

0

ベストアンサー

画像形式がPPMとの事ですが、最初のマジックナンバーを判定しなくても良いでしょうか?
P3(PPM ASCII)以外では正しく動作しません。(Segmentation faultの原因)
また、LoadPPM()関数の if(ci->r[i]==NULL||ci->g==NULL||ci->b==NULL) { は正しくNULL判定できません。

直接の原因ではありませんが、chroma_key()関数のif(fg->r[i][j]<=α && fg->g[i][j]>=β && fg->g[i][j]<=γ){も間違えてます。

あとは、異なる画像ファイル(最初は、小さいもの)で動作するか、調べましょう。その際には、デバッガの使用を勧めます。無ければ、途中途中に、printf()を入れるなどして、どこまで動作しているか確認しましょう。

投稿2020/10/30 13:41

pepperleaf

総合スコア6385

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問