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

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

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

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

Q&A

解決済

1回答

1656閲覧

sobelフィルタの実装

esodermaso

総合スコア15

C

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

0グッド

0クリップ

投稿2019/05/08 12:44

編集2019/05/08 13:09

前提・実現したいこと

(カラー)ppm画像を(白黒)pgm化した後、その画像を濃度やガンマ変換、エッジ検出やSobel,ラプラシアンフィルタでpgm画像で様々な変換を行おうとしたプログラムを作っています。
Sobelフィルタを実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

Sobel(eage7)のみ、実装しようとした場合に上手く変換されず、宣言(case7)を入れなおす度に『多すぎる、少なすぎる』となり、エラーでコンパイル出来ません。

エラーメッセージ

コンパイル時「関数が多すぎる、sqrt関数が互換性がない、関数が少なすぎる」等

該当のソースコード

C言語

1#define _CRT_SECURE_NO_WARNINGS 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <math.h> 6/* 関数のプロトタイプ宣言 */ 7unsigned char *read_ppm(char *fname, int *width, int *height); 8void save_pgm(char *fname, unsigned char *gray, int width, int height); 9void trans(unsigned char *src, unsigned char *out, int width, int height, int g[]); 10void edge5(unsigned char *src, unsigned char *out, int width, int height, int threshold); 11void edge6(unsigned char *src, unsigned char *out, int width, int height, int threshold); 12void edge7(unsigned char *src, unsigned char *out, int width, int height, int threshold, double sqrt); 13void edge8(unsigned char *src, unsigned char *out, int width, int height, int threshold); 14int main(int argc, char* argv[]) 15{ 16int width, height; /* 入力画像のサイズ */ 17unsigned char *src, *out; /* 白黒画像:それぞれ入力用と出力用に対応 */ 18int f; /* 入力の画素値(入力:図 1 の横軸に相当) */ 19int g[256] = {0}; /* 出力の画素値(出力:図 1 の縦軸に相当) */ 20int f_L = 0, f_H = 20; /* 適切に値を変更 : 必ず f_L < f_H とすること */ 21double gamma = 5; 22int kadai = 0; /* 課題番号 : 実行ファイルの引数で値を指定 <== argv[3][0] (一文字) */ 23int threshold = 200;/* 入力ファイル名 <== argv[1], 出力ファイル名 <== argv[2] */ 24if(argc != 4){ 25printf("usage: %s <source-image.ppm> <output-image.pgm> <kadai No.>\n", argv[0]); 26return 0; 27} 28 /* 課題番号 */ 29kadai = argv[3][0] - '0'; /* 1 文字目を数値化 */ 30 /* カラー画像のファイルを白黒化して読み込み */ 31src = read_ppm(argv[1], &width, &height); 32if(kadai == 1){ /* 白黒化した入力画像の保存 */ 33save_pgm(argv[2], src, width, height); 34free(src); 35return 0; 36} 37 38/* 出力画像バッファの作成 */ 39out = (unsigned char *)malloc(width * height); 40switch(kadai){ 41case 2: /* 濃度変換 : 白黒反転 */ 42for(f = 0; f <= 255; f++){ 43g[f] = 255 - f; /* ルックアップテーブル */ 44} 45/* 濃度変換関数を用いた変換 */ 46trans(src, out, width, height, g); 47break; 48case 3: /* 濃度変換 : 図 1 */ 49for(f = 0; f < f_L; f++){ 50g[f] = 0; /* ルックアップテーブル */ 51} 52for(f = f_L; f < f_H; f++){ 53g[f] = (int)(255.0 / (f_H - f_L) * (f - f_L) + 0.5); /* ルックアップテーブル */ 54} 55for(f = f_H; f <= 255; f++){ 56g[f] = 255; /* ルックアップテーブル */ 57} 58/* 濃度変換関数を用いた変換 */ 59trans(src, out, width, height, g); 60break; 61case 4: /* 濃度変換 : ガンマ変換 */ 62for(f = 0; f <= 255; f++){ 63g[f] = (int)(255.0*pow(f / 255.0, 1.0 / gamma) + 0.5); /* ルックアップテーブル */ 64} 65/* 濃度変換関数を用いた変換 */ 66trans(src, out, width, height, g); 67break; 68case 5: /* エッジ検出 : 図 2(a) */ 69edge5(src, out, width, height, 50); 70break; 71case 6: /* エッジ検出 : 図 2(b) */ 72edge6(src, out, width, height, 50); 73break; 74case 7: /* エッジ検出 : sobel */ 75edge7(src, out, width, height, threshold,50); 76break; 77case 8: /* エッジ検出 : ラプラシアン */ 78edge8(src, out, width, height, 50); 79break; 80default: 81fprintf(stderr, "正しい課題番号を指定してください!\n"); 82free(src); 83free(out); 84return -1; 85} 86/* 出力画像の保存 */ 87save_pgm(argv[2], out, width, height); 88free(src); 89free(out); 90return 0; 91} 92void trans(unsigned char *src, unsigned char *out, int width, int height, int g[]) 93{ 94int x, y, i; 95for(y = 0; y < height; y++){ 96for(x = 0; x < width; x++){ 97i = width * y + x; 98out[i] = g[src[i]]; 99} 100} 101return; 102} 103void edge5(unsigned char *src, unsigned char *out, int width, int height, int threshold) 104{ 105int x, y, i, val; 106int op[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; 107/* 上下左右の縁 */ 108for(x = 0; x < width; x++){ 109out[x] = 0; /* 上端 */ 110out[width*(height-1) + x] = 0; /* 下端 */ 111} 112for(y = 1; y < height-1; y++){ 113out[width * y] = 0; /* 左端 */ 114out[width * y + width-1] = 0; /* 右端 */ 115} 116/* 内側の処理 */ 117for(y = 1; y < height-1; y++){ 118for(x = 1; x < width-1; x++){ 119i = width * y + x; 120val = op[0] * src[i - width -1] + op[1] * src[i - width] + op[2] * src[i - width + 1] + 121op[3] * src[i -1] + op[4] * src[i ] + op[5] * src[i + 1] + 122op[6] * src[i + width -1] + op[7] * src[i + width] + op[8] * src[i + width + 1]; 123/* 2 値化 */ 124if(val >= threshold) 125out[i] = 255; 126else 127out[i] = 0; 128} 129} 130return; 131} 132void edge6(unsigned char *src, unsigned char *out, int width, int height, int threshold) 133{ 134int x, y, i, val; 135int op[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; 136/* 上下左右の縁 */ 137for(x = 0; x < width; x++){ 138out[x] = 0; /* 上端 */ 139out[width*(height-1) + x] = 0; /* 下端 */ 140} 141for(y = 1; y < height-1; y++){ 142out[width * y] = 0; /* 左端 */ 143out[width * y + width-1] = 0; /* 右端 */ 144} 145/* 内側の処理 */ 146for(y = 1; y < height-1; y++){ 147for(x = 1; x < width-1; x++){ 148i = width * y + x; 149val = op[0] * src[i - width -1] + op[1] * src[i - width] + op[2] * src[i - width + 1] + 150op[3] * src[i -1] + op[4] * src[i ] + op[5] * src[i + 1] + 151op[6] * src[i + width -1] + op[7] * src[i + width] + op[8] * src[i + width + 1]; 152/* 2 値化 */ 153if(val >= threshold) 154out[i] = 255; 155else 156out[i] = 0; 157} 158} 159return; 160} 161void edge7(unsigned char *src, unsigned char *out, int width, int height, int threshold, double sqrt) { 162 /* 内側の処理 : 端の処理はテキスト C-1.pdf 参照 */ 163 int x = 0, y = 0, i = 0; 164 double val = 0.0, fx = 0.0, fy = 0.0; 165 double fxa[9] = { -1.0,0.0,1.0,-2.0,0.0,2.0,-1.0,0.0,1.0 }; 166 double fyb[9] = { -1.0,0.0,1.0,-2.0,0.0,2.0,-1.0,0.0,1.0 }; 167 /* 上下左右の縁 */ 168 for (x = 0; x < width; x++) { 169 out[x] = 0; /* 上端 */ 170 out[width*(height - 1) + x] = 0; /* 下端 */ 171 } 172 for (y = 1; y < height - 1; y++) { 173 out[width * y] = 0; /* 左端 */ 174 out[width * y + width - 1] = 0; /* 右端 */ 175 } 176 for (y = 1; y < height - 1; y++) { 177 for (x = 1; x < width - 1; x++) { 178 i = width * y + x; /* 1 次元で見た注目画素の位置 */ 179 fx = fxa[0] * src[i - width - 1] + fxa[1] * src[i - width] + fxa[2] * src[i - width + 1] + fxa[3] * src[i - 1] + fxa[4] * src[i] + fxa[5] * src[i + 1] + 180 fxa[6] * src[i + width - 1] + fxa[7] * src[i + width] + fxa[8] * src[i + width + 1]; 181 fy = fyb[0] * src[i - width - 1] + fyb[1] * src[i - width] + fyb[2] * src[i - width + 1] + fyb[3] * src[i - 1] + fyb[4] * src[i] + fyb[5] * src[i + 1] + 182 fyb[6] * src[i + width - 1] + fyb[7] * src[i + width] + fyb[8] * src[i + width + 1]; 183 double val = sqrt*(fx * fx + fy * fy)+0.5; 184 if (val > threshold) { 185 out[i] = 255; 186 } 187 else { 188 out[i] = 0; 189 } 190 } 191 } 192} 193void edge8(unsigned char *src, unsigned char *out, int width, int height, int threshold){ 194/* 内側の処理 : 端の処理はテキスト C-1.pdf 参照 */ 195 int x = 0,y = 0,i = 0; 196 double val = 0.0; 197 double op[9]={1.0,1.0,1.0,1.0,-8.0,1.0,1.0,1.0,1.0}; 198/* 上下左右の縁 */ 199 for(x = 0; x < width; x++){ 200 out[x] = 0; /* 上端 */ 201 out[width*(height-1) + x] = 0; /* 下端 */ 202 } 203 for(y = 1; y < height-1; y++){ 204 out[width * y] = 0; /* 左端 */ 205 out[width * y + width-1] = 0; /* 右端 */ 206 } 207 for(y = 1; y < height-1; y++){ 208 for(x = 1; x < width-1; x++){ 209 i = width * y + x; /* 1 次元で見た注目画素の位置 */ 210 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]; /* 絶対値をとる */ 211 if(val < 0) 212 val = -val; /* 符号反転 */ 213 if(val > threshold){ 214 out[i]= 255; 215 } 216 else 217 { 218 out[i]= 0; 219 } 220 } 221 } 222} 223unsigned char *read_ppm(char *fname, int *width, int *height) 224{ 225 char str[256], c; 226 int max = 0; 227 unsigned char *gray = NULL; 228 int r = 0, g = 0, b = 0; 229 int size = 0; 230 int i; 231 FILE *fp = fopen(fname, "rb"); 232 if (fp == NULL) { 233 fprintf(stderr, "error: %s cannot open!", fname); 234 exit(-1); 235 } 236 /* ------------ Magic number ---------- */ 237 fscanf(fp, "%s", str); 238 c = str[1]; 239 if (c == '3' || c == '6') { 240 /* ------------ comment, space, or size ---------- */ 241 fscanf(fp, "%s", str); 242 if (str[0] == '#' || str[0] == ' ') { 243 while (fscanf(fp, "%c", &str[0])) { /* comment skip */ 244 if (str[0] == '\n') 245 break; 246 } 247 fscanf(fp, "%d %d", width, height); 248 } 249 else { 250 sscanf(str, "%d", width); 251 fscanf(fp, "%d", height); 252 } 253 /* ------------ comment, space, or max value ---------- */ 254 fscanf(fp, "%d", &max); 255 /* ------------ memory create ---------- */ 256 size = (*width) * (*height); 257 gray = (unsigned char *)malloc(size); 258 /* ------------ pixel value ---------- */ 259 if (c == '3') { /* テキストデータ */ 260 for (i = 0; i < size; i++) { 261 fscanf(fp, "%d %d %d", &r, &g, &b); 262 gray[i] = (unsigned char)(0.299 * r + 0.587 * g + 0.114 * b + 0.5); 263 } 264 265 } 266 else { /* バイナリデータ */ 267 fread(&r, 1, 1, fp); /* LF */ 268 for (i = 0; i < size; i++) { 269 fread(&r, 1, 1, fp); 270 fread(&g, 1, 1, fp); 271 fread(&b, 1, 1, fp); 272 gray[i] = (unsigned char)(0.299 * r + 0.587 * g + 0.114 * b + 0.5); 273 } 274 } 275 } 276 else 277 fprintf(stderr, "[%s] is not a ppm-file!\n", fname); 278 fclose(fp); 279 return gray; 280} 281void save_pgm(char *fname, unsigned char *gray, int width, int height) 282{ 283 int x, y; 284 FILE *fp = fopen(fname, "w"); 285 fprintf(fp, "P2\n"); 286 fprintf(fp, "%d %d\n", width, height); 287 fprintf(fp, "255\n"); 288 for (y = 0; y < height; y++) { 289 for (x = 0; x < width; x++) 290 fprintf(fp, "%d ", gray[width * y + x]); /* (注) %d の後にスペースあり */ 291 fprintf(fp, "\n"); 292 } 293 fclose(fp); 294 return; 295} 296

試したこと

問題点が分からず、どう試せばいいのか分からないままです

補足情報(FW/ツールのバージョンなど)

VS code にて制作しています。
実行する際の環境は仮想Linuxでコンパイルを行っています

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

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

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

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

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

guest

回答1

0

ベストアンサー

edge7関数の引数sqrtは、math.hが持つsqrt関数と名前が被っているのが原因ではないでしょうか。
別の名前に変更してみてはどうでしょう。

投稿2019/05/09 01:11

ttyp03

総合スコア16998

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問