#1
by MEA » 3年前
線形補完の式を使って画像処理をしているのですが、Segmentation fault: 11が出て原因が全くわからないので原因になっているところを教えていただきたいです。(真ん中の方に線形補完の関数があります。)
コード:
#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);
/* 丸め込み関数*/
float f_round(float val);
/* 画像変数のメモリを開放する関数*/
void freeImage(ColorImage *ci);
// プログラムを自作する関数
/* 出力画像の変数を生成する関数*/
void createImage(ColorImage *ci);
/* 拡大1(アップサンプリング) */
void scale_up_US(ColorImage *outimage, const ColorImage *inimage ,int M ,int N);
/* 拡大2(最近傍法) */
void scale_up_NN(ColorImage *outimage, const ColorImage *inimage);
/* 拡大3(線形補間) */
void scale_up_IP(ColorImage *outimage, const ColorImage *inimage);
/* 縮小1(ダウンサンプリング) */
void scale_down_DS(ColorImage *outimage, const ColorImage *inimage);
/* 縮小2(平均値) */
void scale_down_Mean(ColorImage *outimage, const ColorImage *inimage);
/* トリミング */
void trimming(ColorImage *outimage, const ColorImage *inimage, int ypos, int xpos);
int main(void)
{
// 変数宣言
char *outputfile={"output_senkeihokan.ppm"};
char *inputfile={"zoneplate256.ppm"};
ColorImage inimage;
ColorImage outimage;
int pros=2; // 手法指定変数 0:拡大1, 1:拡大2, 2:拡大3, 3:縮小1, 4:縮小2, 5:トリミング
float scaleH, scaleW; //倍率の指定
int xpos, ypos; //トリミング用
// ここから処理
loadPPM(inputfile, &inimage);
if(pros==0){ /* 拡大1(アップサンプリング) */
scaleH=3; scaleW=3;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_up_US(&outimage, &inimage,scaleH, scaleW);
}
else if(pros==1){ /* 拡大2(最近傍法) */
scaleH=2; scaleW=2;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_up_NN(&outimage, &inimage);
}
else if(pros==2){/* 拡大3(線形補間) */
scaleH=2; scaleW=2;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_up_IP(&outimage, &inimage);
}
else if(pros==3){/* 縮小1(ダウンサンプリング) */
scaleH=1.0/2; scaleW=1.0/2;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_down_DS(&outimage, &inimage);
}
else if(pros==4){/* 縮小2(平均値) */
scaleH=1.0/2; scaleW=1.0/2;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_down_Mean(&outimage, &inimage);
}
else{/* トリミング */
outimage.width = 64; outimage.height = 64;
xpos = 32; ypos = 32;
createImage(&outimage);
trimming(&outimage, &inimage, ypos, xpos);
}
savePPM(outputfile, &outimage);
freeImage(&inimage);
freeImage(&outimage);
return 0;
}
void createImage(ColorImage *ci)
{
int i,j;
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[i]==NULL||ci->b[i]==NULL) {
printf("Error in malloc");
exit(0);
}
}
for(i=0;i<ci->height;i++){
for(j=0;j<ci->width;j++){
ci->r[i][j]=0;
ci->g[i][j]=0;
ci->b[i][j]=0;
}
}
}
/* 拡大1(アップサンプリング) */
void scale_up_US(ColorImage *outimage, const ColorImage *inimage, int M, int N)
{
int i,j;
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
if(fmod((float)i/M,1)==0 && fmod((float)j/N,1)==0){
outimage->r[i][j]=inimage->r[i/M][j/N];
outimage->g[i][j]=inimage->g[i/M][j/N];
outimage->b[i][j]=inimage->b[i/M][j/N];
}
else{
outimage->r[i][j]=0;
outimage->g[i][j]=0;
outimage->b[i][j]=0;
}
}
}
}
/* 拡大2(最近傍法) */
void scale_up_NN(ColorImage *outimage, const ColorImage *inimage)
{
int i,j;
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
outimage->r[i][j]=round(inimage->r[i/2][j/2]);
outimage->g[i][j]=round(inimage->g[i/2][j/2]);
outimage->b[i][j]=round(inimage->b[i/2][j/2]);
}
}
}
/* 拡大3(線形補間) */
void scale_up_IP(ColorImage *outimage, const ColorImage *inimage)
{
int i,j,I,J;
float M=2,N=2,a,b;
I=i/M;
a=i/M-I;
J=j/N;
b=j/N-J;
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
outimage->r[i][j]=(1-a)*(1-b)*inimage->r[I][J]
+a*(1-b)*inimage->r[I][J+1]
+(1-a)*b*inimage->r[I+1][J]
+a*b*inimage->r[I+1][J+1];
outimage->g[i][j]=(1-a)*(1-b)*inimage->g[I][J]
+a*(1-b)*inimage->g[I][J+1]
+(1-a)*b*inimage->g[I+1][J]
+a*b*inimage->g[I+1][J+1];
outimage->b[i][j]=(1-a)*(1-b)*inimage->b[I][J]
+a*(1-b)*inimage->b[I][J+1]
+(1-a)*b*inimage->b[I+1][J]
+a*b*inimage->b[I+1][J+1];
}
}
}
/* 縮小1(ダウンサンプリング) */
void scale_down_DS(ColorImage *outimage, const ColorImage *inimage)
{
int i,j;
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
outimage->r[i][j]=inimage->r[2*i][2*j];
outimage->g[i][j]=inimage->g[2*i][2*j];
outimage->b[i][j]=inimage->b[2*i][2*j];
}
}
}
/* 縮小2(平均値) */
void scale_down_Mean(ColorImage *outimage, const ColorImage *inimage)
{
int i,j,k,l;
int M=2,N=2; //縦M倍,横N倍に縮小
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
for(k=0;k<M;k++){
for(l=0;l<N;l++){
outimage->r[i][j]+=(1/M/N)*inimage->r[M*i+k][N*j+l];
outimage->g[i][j]+=(1/M/N)*inimage->g[M*i+k][N*j+l];
outimage->b[i][j]+=(1/M/N)*inimage->b[M*i+k][N*j+l];
}
}
}
}
}
/* トリミング */
void trimming(ColorImage *outimage, const ColorImage *inimage, int ypos, int xpos)
{
/* プログラムを書く.*/
}
/* ここから下は修正する必要はありません */
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);
/* 画素値を書き出す */
for(i=0;i<ci->height;i++){
for(j=0;j<ci->width;j++){
if(ci->r[i][j] > 255.0f) ci->r[i][j]=255.0f;
if(ci->g[i][j] > 255.0f) ci->g[i][j]=255.0f;
if(ci->b[i][j] > 255.0f) ci->b[i][j]=255.0f;
if(ci->r[i][j] < 0.0f) ci->r[i][j]=0.0f;
if(ci->g[i][j] < 0.0f) ci->g[i][j]=0.0f;
if(ci->b[i][j] < 0.0f) ci->b[i][j]=0.0f;
}
}
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[i]==NULL||ci->b[i]==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);
}
}
void freeImage(ColorImage *ci)
{
int i;
for(i=0;i<ci->height;i++)
{
free(ci->r[i]);
free(ci->g[i]);
free(ci->b[i]);
}
free(ci->r);
free(ci->g);
free(ci->b);
}
float f_round(float val)
{
float fval=0.0;
fval = floor(val + 0.5);
return fval;
}
線形補完の式を使って画像処理をしているのですが、Segmentation fault: 11が出て原因が全くわからないので原因になっているところを教えていただきたいです。(真ん中の方に線形補完の関数があります。)
[code]
#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);
/* 丸め込み関数*/
float f_round(float val);
/* 画像変数のメモリを開放する関数*/
void freeImage(ColorImage *ci);
// プログラムを自作する関数
/* 出力画像の変数を生成する関数*/
void createImage(ColorImage *ci);
/* 拡大1(アップサンプリング) */
void scale_up_US(ColorImage *outimage, const ColorImage *inimage ,int M ,int N);
/* 拡大2(最近傍法) */
void scale_up_NN(ColorImage *outimage, const ColorImage *inimage);
/* 拡大3(線形補間) */
void scale_up_IP(ColorImage *outimage, const ColorImage *inimage);
/* 縮小1(ダウンサンプリング) */
void scale_down_DS(ColorImage *outimage, const ColorImage *inimage);
/* 縮小2(平均値) */
void scale_down_Mean(ColorImage *outimage, const ColorImage *inimage);
/* トリミング */
void trimming(ColorImage *outimage, const ColorImage *inimage, int ypos, int xpos);
int main(void)
{
// 変数宣言
char *outputfile={"output_senkeihokan.ppm"};
char *inputfile={"zoneplate256.ppm"};
ColorImage inimage;
ColorImage outimage;
int pros=2; // 手法指定変数 0:拡大1, 1:拡大2, 2:拡大3, 3:縮小1, 4:縮小2, 5:トリミング
float scaleH, scaleW; //倍率の指定
int xpos, ypos; //トリミング用
// ここから処理
loadPPM(inputfile, &inimage);
if(pros==0){ /* 拡大1(アップサンプリング) */
scaleH=3; scaleW=3;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_up_US(&outimage, &inimage,scaleH, scaleW);
}
else if(pros==1){ /* 拡大2(最近傍法) */
scaleH=2; scaleW=2;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_up_NN(&outimage, &inimage);
}
else if(pros==2){/* 拡大3(線形補間) */
scaleH=2; scaleW=2;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_up_IP(&outimage, &inimage);
}
else if(pros==3){/* 縮小1(ダウンサンプリング) */
scaleH=1.0/2; scaleW=1.0/2;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_down_DS(&outimage, &inimage);
}
else if(pros==4){/* 縮小2(平均値) */
scaleH=1.0/2; scaleW=1.0/2;
outimage.width = scaleW*(inimage.width);
outimage.height = scaleH*(inimage.height);
createImage(&outimage);
scale_down_Mean(&outimage, &inimage);
}
else{/* トリミング */
outimage.width = 64; outimage.height = 64;
xpos = 32; ypos = 32;
createImage(&outimage);
trimming(&outimage, &inimage, ypos, xpos);
}
savePPM(outputfile, &outimage);
freeImage(&inimage);
freeImage(&outimage);
return 0;
}
void createImage(ColorImage *ci)
{
int i,j;
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[i]==NULL||ci->b[i]==NULL) {
printf("Error in malloc");
exit(0);
}
}
for(i=0;i<ci->height;i++){
for(j=0;j<ci->width;j++){
ci->r[i][j]=0;
ci->g[i][j]=0;
ci->b[i][j]=0;
}
}
}
/* 拡大1(アップサンプリング) */
void scale_up_US(ColorImage *outimage, const ColorImage *inimage, int M, int N)
{
int i,j;
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
if(fmod((float)i/M,1)==0 && fmod((float)j/N,1)==0){
outimage->r[i][j]=inimage->r[i/M][j/N];
outimage->g[i][j]=inimage->g[i/M][j/N];
outimage->b[i][j]=inimage->b[i/M][j/N];
}
else{
outimage->r[i][j]=0;
outimage->g[i][j]=0;
outimage->b[i][j]=0;
}
}
}
}
/* 拡大2(最近傍法) */
void scale_up_NN(ColorImage *outimage, const ColorImage *inimage)
{
int i,j;
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
outimage->r[i][j]=round(inimage->r[i/2][j/2]);
outimage->g[i][j]=round(inimage->g[i/2][j/2]);
outimage->b[i][j]=round(inimage->b[i/2][j/2]);
}
}
}
/* 拡大3(線形補間) */
void scale_up_IP(ColorImage *outimage, const ColorImage *inimage)
{
int i,j,I,J;
float M=2,N=2,a,b;
I=i/M;
a=i/M-I;
J=j/N;
b=j/N-J;
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
outimage->r[i][j]=(1-a)*(1-b)*inimage->r[I][J]
+a*(1-b)*inimage->r[I][J+1]
+(1-a)*b*inimage->r[I+1][J]
+a*b*inimage->r[I+1][J+1];
outimage->g[i][j]=(1-a)*(1-b)*inimage->g[I][J]
+a*(1-b)*inimage->g[I][J+1]
+(1-a)*b*inimage->g[I+1][J]
+a*b*inimage->g[I+1][J+1];
outimage->b[i][j]=(1-a)*(1-b)*inimage->b[I][J]
+a*(1-b)*inimage->b[I][J+1]
+(1-a)*b*inimage->b[I+1][J]
+a*b*inimage->b[I+1][J+1];
}
}
}
/* 縮小1(ダウンサンプリング) */
void scale_down_DS(ColorImage *outimage, const ColorImage *inimage)
{
int i,j;
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
outimage->r[i][j]=inimage->r[2*i][2*j];
outimage->g[i][j]=inimage->g[2*i][2*j];
outimage->b[i][j]=inimage->b[2*i][2*j];
}
}
}
/* 縮小2(平均値) */
void scale_down_Mean(ColorImage *outimage, const ColorImage *inimage)
{
int i,j,k,l;
int M=2,N=2; //縦M倍,横N倍に縮小
for(i=0;i<outimage->height;i++){
for(j=0;j<outimage->width;j++){
for(k=0;k<M;k++){
for(l=0;l<N;l++){
outimage->r[i][j]+=(1/M/N)*inimage->r[M*i+k][N*j+l];
outimage->g[i][j]+=(1/M/N)*inimage->g[M*i+k][N*j+l];
outimage->b[i][j]+=(1/M/N)*inimage->b[M*i+k][N*j+l];
}
}
}
}
}
/* トリミング */
void trimming(ColorImage *outimage, const ColorImage *inimage, int ypos, int xpos)
{
/* プログラムを書く.*/
}
/* ここから下は修正する必要はありません */
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);
/* 画素値を書き出す */
for(i=0;i<ci->height;i++){
for(j=0;j<ci->width;j++){
if(ci->r[i][j] > 255.0f) ci->r[i][j]=255.0f;
if(ci->g[i][j] > 255.0f) ci->g[i][j]=255.0f;
if(ci->b[i][j] > 255.0f) ci->b[i][j]=255.0f;
if(ci->r[i][j] < 0.0f) ci->r[i][j]=0.0f;
if(ci->g[i][j] < 0.0f) ci->g[i][j]=0.0f;
if(ci->b[i][j] < 0.0f) ci->b[i][j]=0.0f;
}
}
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[i]==NULL||ci->b[i]==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);
}
}
void freeImage(ColorImage *ci)
{
int i;
for(i=0;i<ci->height;i++)
{
free(ci->r[i]);
free(ci->g[i]);
free(ci->b[i]);
}
free(ci->r);
free(ci->g);
free(ci->b);
}
float f_round(float val)
{
float fval=0.0;
fval = floor(val + 0.5);
return fval;
}
[/code]