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

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

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

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

Q&A

解決済

2回答

1039閲覧

C言語で画像処理におけるラベリング処理をしようとすると実行エラーがでる

sabo-rino33

総合スコア7

C

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

0グッド

0クリップ

投稿2019/07/30 15:28

編集2019/07/30 17:13

前提・実現したいこと

C言語で画像処理の際に使用するラベリング関数を作っています。
int labeling(char* output,int bright);の関数部分でラベリング処理を行おうとしています。

同じフォルダーに星の画像を入れ星が何個あるかを数えるプログラムを作っています。
(field1.bmp)が星の画像です。

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

mainメソッドなどは問題ないのですがlabeling関数の部分で実行エラーが出てしまいます。
0,1に二値化された場所にラベリング処理をしている際に、コンパイルは成功するのですが実行エラーが起き動作が停止してしまいます。(1)以降のif文をコメントすると一応実行はできるようになるので、
その近辺でバグが起きているのだと思いますがデバッグの方法が分かりません。

エラーメッセージですが、「動作が終了しました」と出てしまい、プログラムが停止してしまいます

該当のソースコード

C

1#define _CRT_SECURE_NO_WARNINGS 2 3#include <stdio.h> 4#include <stdlib.h> 5 6#define NX 2048 //Image size X 7#define NY 2048 //Image size Y 8#define HEADER_SIZE 300 //maximum header size 9 10void readImageFile(char*, char*, char*, int, int, int*); 11void writeImageFile(char*, char*, char*, int, int, int); 12int labeling(char* ,int); 13 14void main(int argc, char *argv[]) 15{ 16 char *input, *output, *header; 17 int hSize; 18 int j,i; //ループ変数 19 int cnt = 0; //星の数を数える変数 20 int sepbright = 10; //星を分ける大きさ(ここに二値化の最善の値を入れる) 21 int bright = 1; //星の返す色 22 23 input = (char*)malloc(NX*NY * 1); 24 output = (char*)malloc(NX*NY * 1); 25 header = (char*)malloc(HEADER_SIZE); 26 27 // read image file 28 readImageFile("field1.bmp", input, header, NX, NY, &hSize); 29 30// getchar(); //なくてもいい(実行時returnですすむ) 31 32 //Image processing ここ変える 33 for (j = 0; j < NY; j++) { 34 for (i = 0; i < NX; i++) { 35 output[j*NX + i] = input[j*NX + i]; 36 37 //適当な二値化 38 if(output[j*NX + i] >=sepbright){ 39 output[j*NX + i] = bright;//bright は1設定 40 }else if(output[j*NX + i] <sepbright){ 41 output[j*NX + i] = 0; 42 } 43 44 }//printf("%d ",j); 45 } 46 47 cnt = labeling(output,bright); 48 printf("星の数:%d",cnt); 49 // write image file 50 writeImageFile("output1.bmp", output, header, NX, NY, hSize); 51 52 free(header); 53 free(output); 54 free(input); 55 56} 57 58 59//jは縦、iは横 60//output:読み込んだ画像, 61//bright:二値化された場所が0か1を判定するための引数 62int labeling(char* output,int bright){ 63 int* look; //ルックアップカウンタ 64 look =(int *)malloc(2000); 65 int lookcnt =0; //lookを書き換えたやつ 66 int num =2; //ラベリングした回数の変数 67 int min = num; //最小の番号を振り割るための変数 68 int j,i,k; //for文変数 69 70 for (j = 0; j < NY; j++) { 71 for (i = 0; i < NX; i++) { 72 //二値化されたものがbrightであれば 73 if(output[j*NX + i] == bright){ 74 //左上、上、右上、左の画素番号がすべて0なら 75 //numの値を振り分けていく 76 //(1)ここ以下のif文でエラー? 77 if(output[(j-1)*NX+i-1]==0 && output[(j-1)*NX+i]==0 && 78 output[(j-1)*NX+i+1] ==0 && output[j*NX+i-1]==0) 79 { 80 output[j*NX + i]=num; //numは2から 81 look[num]=num; 82 num++; 83 } 84 //左上、上、右上、左の画素番号のうち0以外が複数あるなら 85 else{ 86 if(output[(j-1)*NX+i-1] != 0 && output[(j-1)*NX+i-1]<min){ 87 min = output[(j-1)*NX+i-1]; 88 //look[num]の値と左上の値が違うならlookを書き換える 89 if(look[num] != output[(j-1)*NX+i-1]){ 90 look[num] = output[(j-1)*NX+i-1]; 91 lookcnt++; 92 } 93 } 94 95 else if(output[(j-1)*NX+i] != 0 && output[(j-1)*NX+i]<min){ 96 min = output[(j-1)*NX+i]; 97 98 //look[num]の値と上の値が違うならlookを書き換える 99 if(look[num] != output[(j-1)*NX+i]){ 100 look[num] = output[(j-1)*NX+i]; 101 lookcnt++; 102 } 103 104 } 105 106 else if(output[(j-1)*NX+i+1] != 0 && output[(j-1)*NX+i+1]<min){ 107 min = output[(j-1)*NX+i+1]; 108 109 //look[num]の値と右上の値が違うならlookを書き換える 110 if(look[num] != output[(j-1)*NX+i+1]){ 111 look[num] = output[(j-1)*NX+i+1]; 112 lookcnt++; 113 } 114 115 } 116 else if(output[j*NX+i-1] != 0 && output[j*NX+i-1]<min){ 117 min = output[j*NX+i-1]; 118 119 //look[num]の値と左の値が違うならlookを書き換える 120 if(look[num] != output[j*NX+i-1]){ 121 look[num] = output[j*NX+i-1]; 122 lookcnt++; 123 } 124 } 125 output[j*NX+i]=min; 126 } 127 } 128 } 129 } 130 131 return num-2-lookcnt; 132} 133 134 135void readImageFile(char* fileName, char* input, char* header, int xsize, int ysize, int *headerSize) 136{ 137 FILE *fp; 138 int imageSize = xsize*ysize * 3; 139 int j; 140 141 fp = fopen(fileName, "rb"); 142 if (fp == NULL) { 143 fprintf(stderr, "File open error: %s", fileName); 144 exit; 145 } 146 147 fseek(fp, 0, SEEK_END); 148 int fileSize = ftell(fp); 149 *headerSize = fileSize - imageSize; 150 printf("%d %d %d\n", imageSize, fileSize, *headerSize); 151 152 fseek(fp, 0, SEEK_SET); 153 154 fread(header, *headerSize, 1, fp); //read header 155 156 for (j = 0; j < xsize*ysize; j++) { 157 input[j] = fgetc(fp); 158 fgetc(fp); 159 fgetc(fp); 160 } 161} 162 163void writeImageFile(char* fileName, char* input, char* header, int xsize, int ysize, int headerSize) 164{ 165 FILE *fp; 166 int imageSize = xsize*ysize * 3; 167 int j; 168 169 fp = fopen(fileName, "wb"); 170 if (fp == NULL) { 171 fprintf(stderr, "File open error: %s", fileName); 172 exit; 173 } 174 175 fwrite(header, headerSize, 1, fp); //read header 176 177 for (j = 0; j < xsize*ysize; j++) { 178 fputc(input[j], fp); 179 fputc(input[j], fp); 180 fputc(input[j], fp); 181 } 182} 183

###修正した箇所
(1)以下の処理をコメントしたときは実行が通ったので、
それ以降が間違っていそうなのですが修正する方法がわかりません。

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

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

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

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

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

pepperleaf

2019/07/30 15:34

> コンパイルは成功するのですが実行エラーが起き それを普通、バグと言います。 どんなエラーが出ているか、具体的に記述しましょう。(エラーメッセージはそのまま) また、コードは、コードタグで括ってください。"<code>" アイコン。
sabo-rino33

2019/07/30 16:24

内容が伝わりにくく申し訳ございません。 まだ伝わりづらいでしょうか。
guest

回答2

0

ベストアンサー

ソースを読んでられないので。

実行時エラーの殆どは、確保した領域の外をアクセスしている、ために起こるものです
がんばって、確保サイズ内に収まっているのかをチェックするしかないですね。

で、ちょっと気になったところを指摘しておきます

look =(int *)malloc(2000);

mallocで指定するのはバイト数ですんで、ここでのintのサイズを4バイトだとすると、
look には500個分だけの領域しか割り当てられてませんがそこらへんは大丈夫でしょうか。

これだけのサイズのコードを書くなら、VisualStudioとかEclipseとかのデバッグできる環境を整えましょう。
任意の行で止めて変数のナカミを確認したり、1行づつ実行したりすることもできます。
これで、アテずっぽでコードを書かなくて済むようになります

投稿2019/07/30 23:49

y_waiwai

総合スコア87782

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

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

0

開示されているソースがコピー&ペーストのものだとすると

c

1//二値化されたものがbrightであれば 2if(output[j*NX + i] = bright){

条件判断しているつもりのif文で、評価する対象に別の値を代入しています。
充分誤動作する可能性があります。

投稿2019/07/30 16:53

KoichiSugiyama

総合スコア3041

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

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

sabo-rino33

2019/07/30 17:03

回答ありがとうございます。確かに条件判断のところを代入していました。 ですが、まだ実行時にエラーが出てしまい、どうしたらいいでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問