Segmentation fault: 11の原因

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
MEA
記事: 12
登録日時: 3年前

Segmentation fault: 11の原因

#1

投稿記事 by MEA » 3年前

以下のコードで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={"outputchroma.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->width;i++){
  for(j=0;j<cimage->height;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->width;i++){
  for(j=0;j<cimage->height;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->width;i++){
  for(j=0;j<cimage->height;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->width;i++){
  for(j=0;j<cimage->height;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 α=12, β=80, γ=50;
for(i=0;i<fg->width;i++){
  for(j=0;j<fg->height;j++){
    if(fg->r[i][j]<=α && fg->g[i][j]>=β && fg->g[i][j]<=γ){
      fg->r[i][j]=bg->r[i][j];
      fg->g[i][j]=bg->g[i][j];
      fg->b[i][j]=bg->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);
	}
}

Bull
記事: 149
登録日時: 9年前

Re: Segmentation fault: 11の原因

#2

投稿記事 by Bull » 3年前

全体をよく見てはいないのですが、おそらく

コード:

// insert forground image into background.
void chroma_key(ColorImage *fg, ColorImage *bg)
{
int i,j;
int α=12, β=80, γ=50;
//for(i=0;i<fg->width;i++){
for(i=0;i<fg->height;i++){
//  for(j=0;j<fg->height;j++){
  for(j=0;j<fg->width;j++){
    if(fg->r[i][j]<=α && fg->g[i][j]>=β && fg->g[i][j]<=γ){
      fg->r[i][j]=bg->r[i][j];
      fg->g[i][j]=bg->g[i][j];
      fg->b[i][j]=bg->b[i][j];
    }
  }
}
}
ではないかと

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: Segmentation fault: 11の原因

#3

投稿記事 by みけCAT » 3年前

ループ条件のwidthとheightが逆ですね。
他の関数にも同じ間違いが見られます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

MEA
記事: 12
登録日時: 3年前

Re: Segmentation fault: 11の原因

#4

投稿記事 by MEA » 3年前

指摘された点を書き直したら、実行できたのですがクロマキー合成されてない前景画像が表示されます。他に間違っている点はありますか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: Segmentation fault: 11の原因

#5

投稿記事 by みけCAT » 3年前

fg->g[i][j]<=γ

という条件がおかしいですね。
緑を2回比較してしまっています。
正しくは

fg->b[i][j]<=γ

でしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

MEA
記事: 12
登録日時: 3年前

Re: Segmentation fault: 11の原因

#6

投稿記事 by MEA » 3年前

こんな小さなミスだったとは、、、無事にできました。ありがとうございます。

返信

“C言語何でも質問掲示板” へ戻る