前提・実現したいこと
ここに質問の内容を詳しく書いてください。
Segmentation faultを解決したいのですが自分では全然できません。教えてください。
発生している問題・エラーメッセージ
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> /* 関数のプロトタイプ宣言*/ unsigned char *read_ppm(char *fname, int *width, int *height); void save_pgm(char *fname, unsigned char *gray, int width, int height); void trans(unsigned char *src, unsigned char *out, int width, int height, int g[]); void edge5(unsigned char *src, unsigned char *out, int width, int height, int threshold); void edge6(unsigned char *src, unsigned char *out, int width, int height, int threshold); void edge7(unsigned char *src, unsigned char *out, int width, int height, int threshold); void edge8(unsigned char *src, unsigned char *out, int width, int height, int threshold); int getThreshold(int *hist,int n); int main(int argc, char* argv[]) { int width, height; /* 入力画像のサイズ*/ unsigned char *src, *out; /* 白黒画像:それぞれ入力用と出力用に対応*/ int th; int hist[256]; int x1,x2,y1,y2; x1=0; y1=0; int kadai = 0; /* 課題番号: 実行ファイルの引数で値を指定<== argv[3][0] (一文字) */ /* 入力ファイル名<== argv[1], 出力ファイル名<== argv[2] */ if(argc != 4){ printf("usage: %s <source-image.ppm> <output-image.pgm> <kadai No.>\n", argv[0]); return 0; } /* 課題番号*/ kadai = argv[3][0] - '0'; /* 1 文字目を数値化 */ /* カラー画像のファイルを白黒化して読み込み*/ src = read_ppm(argv[1], &width, &height); out=(unsigned char*)malloc(width *height); memset(hist,0,sizeof(hist)); if(kadai == 1){ /* 白黒化した入力画像の保存*/ save_pgm(argv[2], src, width, height); free(src); return 0; } /* 出力画像バッファの作成*/ out = (unsigned char *)malloc(width * height); switch(kadai){ case 5: /* エッジ検出: 図2(a) */ for(int i=0;i<width*height;i++){ hist[src[i]]++; } th=getThreshold(hist,256); edge5(src, out, width, height, th); break; case 6: /* エッジ検出: 図2(b) */ for(int i=0;i<width*height;i++){ hist[src[i]]++; } th=getThreshold(hist,256); edge6(src, out, width, height, th); break; case 7: /* エッジ検出: sobel */ for(int i=0;i<width*height;i++){ hist[src[i]]++; } th=getThreshold(hist,256); edge7(src, out, width, height, th); break; case 8: /* エッジ検出: ラプラシアン*/ for(int i=0;i<width*height;i++){ hist[src[i]]++; } th=getThreshold(hist,256); edge8(src, out, width, height, th); break; default: fprintf(stderr, "正しい課題番号を指定してください!\n"); free(src); free(out); return -1; } /* 出力画像の保存*/ save_pgm(argv[2], out, width, height); free(src); free(out); return 0; } int getThreshold(int *hist,int n) { int th; int i,j; double max; int sa,sb,da,db; double ma,mb,mt; double wa,wb,wt; double kai; max=(-1000.0); th=0; for(i=1;i<n-1;i++){ da=0; sa=0; for(j=0;j<i;j++){ da+=(hist[j]*j); sa+=hist[j]; } db=0; sb=0; for(j=i;i<n;j++){ db+=(hist[j]*j); sb+=hist[j]; } if(sa!=0.0) ma=(double)da/(double)sa; else ma=0.0; if(sb!=0.0) mb=(double)db/(double)sb; else mb=0.0; mt=(double)(da+db)/(double)(sa+sb); wa=(double)sa/(double)(sa+sb); wb=(double)sb/(double)(sa+sb); kai=wa*(ma-mt)*(ma-mt)+wb*(mb-mt)*(mb-mt); if(max<kai){ max=kai; th=i; } } return th; } void trans(unsigned char *src, unsigned char *out, int width, int height, int g[]) { int x, y, i; for(y = 0; y < height; y++){ for(x = 0; x < width; x++){ i = width * y + x; out[i] = g[src[i]]; } } return; } void edge5(unsigned char *src, unsigned char *out, int width, int height, int threshold) { int x, y, i, val; int op[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; /* 上下左右の縁*/ for(x = 0; x < width; x++){ out[x] = 0; /* 上端*/ out[width*(height-1) + x] = 0; /* 下端*/ } for(y = 1; y < height-1; y++){ out[width * y] = 0; /* 左端*/ out[width * y + width-1] = 0; /* 右端*/ } /* 内側の処理*/ for(y = 1; y < height-1; y++){ for(x = 1; x < width-1; x++){ i = width * y + x; val = op[0] * src[i - width -1] + op[1] * src[i - width] + op[2] * src[i - width + 1] + op[3] * src[i -1] + op[4] * src[i ] + op[5] * src[i + 1] + op[6] * src[i + width -1] + op[7] * src[i + width] + op[8] * src[i + width + 1]; /* 2 値化*/ } } } void edge6(unsigned char *src, unsigned char *out, int width, int height, int threshold) { int x, y, i, val; int op[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; /* 上下左右の縁*/ for(x = 0; x < width; x++){ out[x] = 0; /* 上端*/ out[width*(height-1) + x] = 0; /* 下端*/ } for(y = 1; y < height-1; y++){ out[width * y] = 0; /* 左端*/ out[width * y + width-1] = 0; /* 右端*/ } /* 内側の処理*/ for(y = 1; y < height-1; y++){ for(x = 1; x < width-1; x++){ i = width * y + x; val = op[0] * src[i - width -1] + op[1] * src[i - width] + op[2] * src[i - width + 1] + op[3] * src[i-1] + op[4] * src[i] + op[5] * src[i + 1] + op[6] * src[i + width - 1] + op[7] * src[i + width] + op[8] * src[i + width + 1]; /* 2 値化*/ if(val >= threshold) out[i] = 255; else out[i] = 0; } } return; } void edge7(unsigned char *src, unsigned char *out, int width, int height, int threshold) { int x, y, i, val2,val, FX,FY; int fx[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; int fy[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; /* 上下左右の縁*/ for(x = 0; x < width; x++){ out[x] = 0; /* 上端*/ out[width*(height-1) + x] = 0; /* 下端*/ } for(y = 1; y < height-1; y++){ out[width * y] = 0; /* 左端*/ out[width * y + width-1] = 0; /* 右端*/ } /* 内側の処理*/ for(y = 1; y < height-1; y++){ for(x = 1; x < width-1; x++){ i = width * y + x; FX = fx[0] * src[i - width -1] + fx[1] * src[i - width] + fx[2] * src[i - width + 1] + fx[3] * src[i -1] + fx[4] * src[i ] + fx[5] * src[i + 1] + fx[6] * src[i + width -1] + fx[7] * src[i + width] + fx[8] * src[i + width + 1]; FY = fy[0] * src[i - width -1] + fy[1] * src[i - width] + fy[2] * src[i - width + 1] + fy[3] * src[i -1] + fy[4] * src[i ] + fy[5] * src[i + 1] + fy[6] * src[i + width -1] + fy[7] * src[i + width] + fy[8] * src[i + width + 1]; val2=(FX * FX+FY * FY); val=sqrt(val2); /* 2 値化*/ if(val >= threshold) out[i] = 255; else out[i] = 0; } } return; } void edge8(unsigned char *src, unsigned char *out, int width, int height, int threshold) { int x, y, i, val; int op[9] = {1,1,1,1,-8,1,1,1,1}; /* 上下左右の縁*/ for(x = 0; x < width; x++){ out[x] = 0; /* 上端*/ out[width*(height-1) + x] = 0; /* 下端*/ } for(y = 1; y < height-1; y++){ out[width * y] = 0; /* 左端*/ out[width * y + width-1] = 0; /* 右端*/ } /* 内側の処理*/ for(y = 1; y < height-1; y++){ for(x = 1; x < width-1; x++){ i = width * y + x; val = op[0] * src[i - width -1] + op[1] * src[i - width] + op[2] * src[i - width + 1] + op[3] * src[i -1] + op[4] * src[i ] + op[5] * src[i + 1] + op[6] * src[i + width -1] + op[7] * src[i + width] + op[8] * src[i + width + 1] ; if(val < 0) val = -val; /* 2 値化*/ if(val >= threshold) out[i] = 255; else out[i] = 0; } } return; } unsigned char *read_ppm(char *fname, int *width, int *height) { char str[256], c; int max = 0; unsigned char *gray = NULL; int r = 0, g = 0, b = 0; int size = 0; int i; FILE *fp = fopen(fname,"rb"); if(fp == NULL){ fprintf(stderr, "error: %s cannot open!", fname); exit(-1); } /* ------------ Magic number ---------- */ fscanf(fp, "%s", str); c = str[1]; if(c == '3' || c == '6'){ /* ------------ comment, space, or size ---------- */ fscanf(fp, "%s", str); if(str[0] == '#' || str[0] == '\n' ){ while(fscanf(fp,"%c",&str[0])){ /* comment skip */ if(str[0] == '\n') break; } fscanf(fp, "%d %d", width, height); } else{ sscanf(str, "%d", width); fscanf(fp, "%d", height); } /* ------------ comment, space, or max value ---------- */ fscanf(fp, "%d", &max); /* ------------ memory create ---------- */ size = (*width) * (*height); gray = (unsigned char *)malloc(size); /* ------------ pixel value ---------- */ if(c == '3'){ /* テキストデータ */ for(i = 0; i < size; i++){ fscanf(fp, "%d %d %d", &r, &g, &b); gray[i] = (unsigned char)(0.299 * r + 0.587 * g + 0.114 * b + 0.5); } } else{ /* バイナリデータ */ fread(&r,1,1,fp); /* LF */ for(i = 0; i < size; i++){ fread(&r,1,1,fp); fread(&g,1,1,fp); fread(&b,1,1,fp); gray[i] = (unsigned char)(0.299 * r + 0.587 * g + 0.114 * b + 0.5); } } } else fprintf(stderr, "[%s] is not a ppm-file!\n", fname); fclose(fp); return gray; } void save_pgm(char *fname, unsigned char *gray, int width, int height) { int x, y; FILE *fp = fopen(fname, "wb"); fprintf(fp, "P5\n"); fprintf(fp, "%d %d\n", width, height); fprintf(fp, "255\n"); for(y = 0; y < height; y++){ for(x = 0; x < width; x++) /*fprintf(fp, "%d ", gray[width * y + x]); fprintf(fp, "\n")*/ fwrite(&gray[width * y + x],sizeof(unsigned char),1,fp); } fclose(fp); return; } ```Segmentation fault: 11