画像処理

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
カイト

画像処理

#1

投稿記事 by カイト » 14年前

C言語
[環境] Linux gcc

画像を読み込み、
--------------------------------
① 原画像        ②2値化

③dirate(8近傍     ④erode(8近傍
 膨張処理)        縮小処理)

⑤↑の(contour)    ⑥↑のcontour)
輪郭追跡        輪郭追跡
--------------------------------

このように表示させるプログラムを作っていますが、以下のようなエラーメッセージが出てしまいます。

In file included from 4.c:9:
dilate.c: In function ‘dilatation’:
dilate.c:16: error: 添字をつけられた値が配列でもポインタでもありません
dilate.c:16: error: 添字をつけられた値が配列でもポインタでもありません
dilate.c:23: error: 添字をつけられた値が配列でもポインタでもありません
dilate.c:29: error: 添字をつけられた値が配列でもポインタでもありません
dilate.c:34: error: 添字をつけられた値が配列でもポインタでもありません
dilate.c:40: error: 添字をつけられた値が配列でもポインタでもありません
dilate.c:40: error: 添字をつけられた値が配列でもポインタでもありません
In file included from 4.c:10:
erode.c: In function ‘erosion’:
erode.c:16: error: 添字をつけられた値が配列でもポインタでもありません
erode.c:16: error: 添字をつけられた値が配列でもポインタでもありません
erode.c:23: error: 添字をつけられた値が配列でもポインタでもありません
erode.c:29: error: 添字をつけられた値が配列でもポインタでもありません
erode.c:33: error: 添字をつけられた値が配列でもポインタでもありません
erode.c:39: error: 添字をつけられた値が配列でもポインタでもありません
erode.c:39: error: 添字をつけられた値が配列でもポインタでもありません
In file included from 4.c:11:
contour.c: In function ‘remove_areas’:
contour.c:80: error: 添字をつけられた値が配列でもポインタでもありません
contour.c:84: error: 添字をつけられた値が配列でもポインタでもありません
contour.c:92: error: 添字をつけられた値が配列でもポインタでもありません
contour.c:93: error: 添字をつけられた値が配列でもポインタでもありません
contour.c:98: error: 添字をつけられた値が配列でもポインタでもありません
contour.c:99: error: 添字をつけられた値が配列でもポインタでもありません
contour.c:108: error: 添字をつけられた値が配列でもポインタでもありません
contour.c:109: error: 添字をつけられた値が配列でもポインタでもありません
contour.c:113: error: 添字をつけられた値が配列でもポインタでもありません
contour.c:114: error: 添字をつけられた値が配列でもポインタでもありません


どこをどうすればよいのか全く見当もつかないので、教えてください。
以下にプログラムを示しておきます。
よろしくお願いします<(_ _)>

コード:

/*4.c*/    //mainプログラム

#include<stdio.h>
#include<stdlib.h>
#include<X11/Xlib.h>
#include<X11/Xutil.h>
#include<limits.h>

#include"mypgm.h"
#include"XDraw.h"
#include"dilate.c"
#include"erode.c"
#include"contour.c"

#define GRAY 128


main( )
{

    Window win1, win2, win3, win4, win5, win6;
    int i, j, m, n, x, y;
    double sum;

    load_image_data( image1, "lenna256.pgm");
    init_window(x_size*2, y_size*3);

    image2 == image1;

    for(y = 0; y<y_size; y++)
      for(x = 0; x <x_size; x++){
	if (image1[y][x] > 135)
	  image2[y][x] = 255;
	else 
	  image2[y][x] = 0;
      }
 
     image7 == image2;

     dilatation(image7, image3);
     dilatation(image3, image3);
     dilatation(image3, image3);

     remove_areas(image3, image5);

     erosion(image7, image4);
     erosion(image4, image4);
     erosion(image4, image4);

     remove_areas(image4, image6);



//    spacial_filtering(image4, image3,  x_size, y_size );

    win1 = gen_window(win, 0, 0, x_size, y_size, " original image");
    win2 = gen_window(win, x_size, 0, x_size, y_size, "2tika image");
    win3 = gen_window(win, 0, y_size, x_size, y_size, "dilate image");
    win4 = gen_window(win, x_size, y_size, x_size, y_size, "erode image");
    win5 = gen_window(win, 0, y_size*2, x_size, y_size, "contour_dilate image");
    win6 = gen_window(win, x_size, y_size*2, x_size, y_size, "contour_erode image");



    DrawImage(win1, image1, x_size, y_size);
    DrawImage(win2, image2, x_size, y_size);
    DrawImage(win3, image3, x_size, y_size);
    DrawImage(win4, image4, x_size, y_size);
    DrawImage(win5, image5, x_size, y_size);
    DrawImage(win6, image6, x_size, y_size);


    getchar();

    return 0;
}

コード:

/*contour.c*/

#define MAX_CNTR 5000    /* 輪郭線の想定最大構成画素数 */
#define GRAY 128

int chain_code[MAX_CNTR];
int Freeman[8][2] = {
  { 1, 0}, { 1, -1}, {0, -1}, {-1, -1},
  {-1, 0}, {-1,  1}, {0,  1}, { 1,  1},};

int obtain_contour(int x_start, int y_start)
/* 開始点(x_start, y_start)から輪郭線追跡を実行してデータを取得して
   大域変数 unsigned char chain_code[MAX_CNTR] に代入し、輪郭線に
   含まれる点の総数(num) を返す。 image1[y][x]を対称にする。     */
{
  int x, y;                /* 輪郭線上の現在の注目画素の座標 */
  int xs, ys;              /* 注目画素の周囲の探索点の座標 */
  int code, num;           /* 輪郭点のチェーンコード、総数 */
  int i, counter, detect;  /* 制御変数など*/

  /*孤立点のチェック */
  counter = 0;
  for(i = 0; i<8; i++){
    xs = x_start + Freeman[i][0];
    ys = y_start + Freeman[i][1];
    if(xs >= 0 && xs <= x_size1 && ys <= y_size1 && image1[ys][xs] == MAX_BRIGHTNESS)
      counter++;
  }
  if(counter == 0) num = 1; /* (x_start,y_start)は孤立点 */
  else{
    /* 探索開始 */
    num = -1;
    x = x_start;
    y = y_start;
    code = 0;
    do{
      detect = 0;  /* 次の点をみつけたとき1にする*/
      /* 初期探索方法の決定 */
      code =code -3;
      if(code < 0)
	code = code + 8;
      do{
	xs = x + Freeman[code][0];
	ys = y + Freeman[code][0];
	if(xs >= 0 && xs <= x_size1 && ys >= 0 &&ys <=y_size1 && image1[ys][xs] == MAX_BRIGHTNESS){
	  detect = 1;
	  num++;
	  if(num > MAX_CNTR){
	    printf("輪郭線の画素数 > %d\n", MAX_CNTR);
	    exit(1);
	  }
	  chain_code[num] = code;
	  x = xs;
	  y = ys;
	}
	code++;
	if(code > 7)
	  code = 0;
      } while(detect == 0);
    } while(x != x_start || y != y_start);  /* 開始点の検出まで */
    num = num + 2;   /* chain_code[ ]の添え字とのずれの修正 */
  }
  return(num);   /* 開始点総数を返す */
}

void remove_areas(image1, image2)
/* 2値画像の輪郭線追跡の関数 obtain_contour() を用いて */
/*  周囲長が指定した値よりも小さな領域を取り除く        */
{
  int threshold;              /* 周囲長に対するしきい値 */
  int num, x, y, xs, ys, i;
  int fill_value;

  printf("輪郭線追跡を用いた領域の除去を行います。\n");
  printf("除去対象領域の最大周囲長 =");
  scanf("%d", &threshold);
  /* 処理後画像の初期化 */
  x_size2 = x_size1;
  y_size2 = y_size1;
  for(y = 0; y < y_size1; y++)
    for(x = 0; x < x_size1; x++)
      image2[y][x] = 0;
  /* 処理開始 */
  for(y = 0; y < y_size1; y++){
    for(x = 0; x < x_size1; y++){
      if(image1[y][x] == MAX_BRIGHTNESS){
	num = obtain_contour(x, y);
	if(num > threshold)
	  fill_value = MAX_BRIGHTNESS;
	else 
	  fill_value =GRAY;
	xs = x;
	ys = y;
	image1[ys][xs] = 0;
	image2[ys][xs] = (unsigned char)fill_value;
	if(num > 1){
	  for(i = 0; i < num -1; i++){
	    xs = xs + Freeman[ chain_code[i] ][0];
	    ys = ys + Freeman[ chain_code[i] ][1];
	    image1[ys][xs] = 0;
	    image2[ys][xs] = (unsigned char)fill_value;
	  }
	}
      }
    }
  }
  /* 後処理 */
  for(y = 0; y < y_size2; y++){
    for(x = 0; x < x_size2; x++){
      if(image2[y][x] == GRAY){
	image2[y][x] = 0;
	for(i = 0; i < 8; i++){
	  xs = x + Freeman[i][0];
	  ys = y + Freeman[i][1];
	  if(xs >= 0 && xs <= x_size2 && ys >= 0 && ys <= y_size2 && image2[ys][xs] == MAX_BRIGHTNESS)
	    image2[y][x]= MAX_BRIGHTNESS;
	}
      }
    }
  }
}

コード:

/*dilate.c*/

void dilatation(image1, image2)
/* 2値画像の8近傍膨張処理                              */
/* 原画像 image1[y][x] ==> 変換後の画像 image2[y][x]   */
{
  int repetition;      /* 膨張処理の回数 */
  int counter;         /* 近傍中の図形画素の数 */
  int p_x, p_y;        /* 近傍の(x,y)座標 */
  int i, x, y, m, n;   /* ループ変数  */

  x_size1 = 256;
  y_size1 = 256;
  x_size2 = x_size1;
  y_size2 = y_size1;
  for(y=0; y < y_size2; y++)
    for(x=0; x < x_size2; x++)
      image2[y][x] = image1[y][x];
  printf("2値画像の8近傍膨張処理を行います. \n");
  printf("膨張処理を行う回数 =  ");
  scanf("%d", &repetition);
  for(i = 0; i < repetition; i++){
    for(y = 0; y < y_size1; y++){
      for(x = 0; x < x_size1; x++){
	if(image1[y][x] == 0){
	  counter = 0;
	  for(m = -1; m < 2; m++){
	    for(n = -1; n < 2; n++){
	      p_x = x + n;
	      p_y = y + m;
	      if(p_x > 0 && p_x < x_size1 && p_y > 0 && p_y < y_size1 && image1[p_y][p_x] == MAX_BRIGHTNESS)
		counter++;
	    }
	  }
	  if(counter > 0)
	    image2[y][x] = MAX_BRIGHTNESS;
	}
      }
    }
    for(y =0; y < y_size2; y++)
      for(x =0; x < x_size2; x++)
	image1[y][x] = image2[y][x];
  }
}

コード:

/*erode.c*/

void erosion(image1, image2)
/* 2値画像の8近傍収縮処理 */
/* 原画像 image1[y][x] ===> 変換後の画像 image2[y][x]*/
{
  int repetition;     /* 収縮処理の回数 */
  int counter;        /* 近傍中の背景画素の数 */
  int p_x, p_y;       /* 近傍の(x, y)座標 */
  int i, x, y, m, n;  /* 制御変数*/

  x_size1 = 256;
  y_size1 = 256;
  x_size2 = x_size1;
  y_size2 = y_size1;
  for(y=0; y < y_size2; y++)
    for(x=0; x < x_size2; x++)
      image2[y][x] = image1[y][x];
  printf("2値画像の8近傍膨張処理を行います. \n");
  printf("収縮処理を行う回数 =  ");
  scanf("%d", &repetition);
  for(i = 0; i < repetition; i++){
    for(y = 0; y < y_size1; y++){
      for(x = 0; x < x_size1; x++){
	if(image1[y][x] == MAX_BRIGHTNESS){
	  counter = 0;
	  for(m = -1; m < 2; m++){
	    for(n = -1; n < 2; n++){
	      p_x = x + n;
	      p_y = y + m;
	      if(p_x > 0 && p_x < x_size1 && p_y > 0 && p_y < y_size1 && image1[p_y][p_x] == 0)
		counter++;
	    }
	  }
	  if(counter > 0) image2[y][x] = 0;
	}
      }
    }
	for(y = 0; y< y_size2; y++)
	  for(x = 0; x < x_size2; x++)
	    image1[y][x] = image2[y][x];
  }
}

コード:

/*mypgm.h*/

#define MAX_SIZE 512
#define X_SIZE 256
#define Y_SIZE 256
#define MAX_BRIGHTNESS 255
#define GRAYLEVEL 256
#define MAX_FILENAME 256
#define MAX_BUFFERSIZE 256


unsigned char image1[MAX_SIZE][MAX_SIZE],  \\原画像
              image2[MAX_SIZE][MAX_SIZE],  \\2値化
              image3[MAX_SIZE][MAX_SIZE],  \\dilate
              image4[MAX_SIZE][MAX_SIZE],  \\erode
              image5[MAX_SIZE][MAX_SIZE],  \\輪郭(dilate)
              image6[MAX_SIZE][MAX_SIZE],  \\輪郭(erode)
              image7[MAX_SIZE][MAX_SIZE];  \\変形用原画像

char file_name[MAX_FILENAME];
int x_size, y_size, x_size1, y_size1, x_size2, y_size2;


void load_image_data();
void save_image_data();


void load_image_data(image, name)
unsigned char image[MAX_SIZE][MAX_SIZE];
unsigned char name[30];
{
  char buffer[MAX_BUFFERSIZE];
  FILE *fp;
  int max_gray;
  int x, y;

  fp = fopen(name, "rb");
  
  if(NULL == fp){
   \\ printf("その名前のファイルは存在しません\n");
	  printf("file is not exsit\n");
    exit(1);
  }
  
  fgets(buffer, MAX_BUFFERSIZE, fp);
  if(buffer[0] != 'P' || buffer[1] != '5'){
    \\printf("ファイルのフォーマットが P5 とは異なります\n");
	printf("File format is not P5 \n");
    exit(1);
  }

  x_size = 0;
  y_size = 0;
  while(x_size == 0 || y_size == 0){
    fgets(buffer, MAX_BUFFERSIZE, fp);
    if(buffer[0] != '#'){
      sscanf(buffer, "%d %d", &x_size, &y_size);
    }
  }
  max_gray = 0;
  while(max_gray == 0){
    fgets(buffer, MAX_BUFFERSIZE, fp);
    if(buffer[0] != '#'){
      sscanf(buffer, "%d", &max_gray);
    }
  }

  \* --- 画像の情報 --- *\
  \\printf("---------------------------------------\n");
  \\printf("横の画素数 = %d, 縦の画素数 = %d\n", x_size, y_size); 
  \\printf("最大階調値 = %d\n", max_gray);
  \\printf("---------------------------------------\n");
  
  if(x_size > MAX_SIZE || y_size > MAX_SIZE){
    \\printf("想定値 %d x %d を超えています\n", MAX_SIZE, MAX_SIZE);
	  printf("input value %d x %d is not proper.\n", MAX_SIZE, MAX_SIZE);
    exit(1);
  }

  if(max_gray != MAX_BRIGHTNESS){
    \\printf("最大階調値が不適切です\n");
	  printf("Max value is not good.\n");
    exit(1);
  }

  for(y=0; y<y_size; y++){
    for(x=0; x<x_size; x++){
      image[y][x] = (unsigned char)fgetc(fp);
    }
  }

  \\printf("データは正しく読み込まれました\n\n");
  printf("File is succesfully read\n\n");
  fclose(fp);
}

void save_image_data(image, x_size, y_size)
unsigned char image[MAX_SIZE][MAX_SIZE];
int x_size, y_size;
{
  FILE *fp;
  int x, y;
  char file_name[MAX_FILENAME];

 \\ printf("出力ファイル名(file_name.pgm)を入力してください : ");
  printf("Input file name:");
  scanf("%s", file_name);
  fp = fopen(file_name, "wb");
  fputs("P5\n", fp);
  fputs("# Created by Image Processing\n", fp);
  fprintf(fp, "%d %d\n", x_size, y_size);
  fprintf(fp, "%d\n", MAX_BRIGHTNESS);
  
  for(y=0; y<y_size; y++){
    for(x=0; x<x_size; x++){
      fputc(image[y][x], fp);
    }
  }

  \\printf("データは正しく出力されました\n\n");
  printf("File is succesfully written\n\n");
  fclose(fp);
}

コード:

/*XDraw.h*/
/*Xウインドウ関連*/

Display        *disp;
Window         rwin,win;
Window         gen_window();
GC gc;
Screen         *scrn;
XSetWindowAttributes att;
unsigned long  Mygraycolor(), MyColor(), graycolor[256];
int            DIRECT= 1;

int            ww, wh;
char           winname[120];
unsigned char  *datslice;
int            HEAD;

void init_window(ww, wh)
{
    int c,i,j;
    int flags = DoRed|DoGreen|DoBlue;
    unsigned long black, white;

    /****** setting display & window ******/
    disp  = XOpenDisplay (NULL);
    black = BlackPixel(disp,0);
    white = WhitePixel(disp,0);
    rwin  = RootWindow(disp,0);
    scrn  = DefaultScreenOfDisplay(disp);
    for(i=0;i<256;i++)
    {
	graycolor[i]=Mygraycolor(disp, i*256);
    }

    /****** setting window attribute & etc. ******/
    win = XCreateSimpleWindow (disp,rwin,200,50,ww,wh,2,black,white);
    att.backing_store = Always;
    att.bit_gravity = NorthWestGravity;
    XChangeWindowAttributes(disp,win,CWBackingStore|CWBitGravity,&att);
    XMapWindow(disp,win);
    XSetIconName(disp,win,"window name");
    XStoreName(disp,win,"window name");
    gc  = DefaultGC(disp, 0);
    
    XFlush(disp);
}


Window gen_window(fwin, x, y, ww, wh, name)
	 Window fwin;
     int     x, y;
     int ww, wh;
     char *name;
{
  int c, i, j;
  int flags = DoRed | DoGreen | DoBlue;
  XSetWindowAttributes att;
  unsigned long black, white;
  Window  win;
  
  /*** setting display & window ***/
  black = BlackPixel(disp, 0);
  white = WhitePixel(disp, 0);
 
  for(i=0; i<256; i++)
    graycolor[i] = Mygraycolor(disp, i*256);
  
  /*** setting window attribute & etc... ***/
  win = XCreateSimpleWindow(disp, fwin, x, y, ww, wh, 0, black, white);
  XMapWindow(disp, win);

  XSetIconName(disp, win, name);
  XStoreName(disp, win, name);
  
  gc = DefaultGC(disp, 0);
  
  att.backing_store = Always;
  att.bit_gravity = NorthWestGravity;
  XChangeWindowAttributes(disp, win, CWBackingStore | CWBitGravity, &att);
  XFlush(disp);
  return(win);
}


unsigned long MyColor (display, color)
Display *display;
char *color;
{  
  Colormap cmap;
  XColor c0,c1;

  cmap = DefaultColormap (display, 0);

  XAllocNamedColor (display, cmap, color, &c1, &c0);

  return (c1.pixel);
}


unsigned long Mygraycolor(display,gray)
Display *display;
int gray;
{
  Colormap cmap;
  XColor c0, c1;
	
  cmap = DefaultColormap(display,0);
  c0.red = gray;
  c0.green = gray;
  c0.blue = gray;
  XAllocColor(display,cmap,&c0);
  
  return(c0.pixel);
}


DrawImage(win, img, ww, wh)
Window win;
unsigned char img[MAX_SIZE][MAX_SIZE];
int ww, wh;
{
  int    i, j;
  int    intensity;
  int    off;
  
  off = 0; 
    for(j = 0; j < wh; j++)
      for(i = 0; i < ww; i++){
	intensity = img[j][i];
	if (intensity > 255) 
	  intensity = 255;   
	XSetForeground(disp, gc, graycolor[intensity]);
	XDrawPoint(disp, win, gc , i, j);
      }
    return(0);
}
長々と失礼します。

アバター
ookami
記事: 214
登録日時: 15年前
住所: 東京都

Re: 画像処理

#2

投稿記事 by ookami » 14年前

dilatation関数の引数を見ると、
void dilatation(image1, image2)
となっていて、型が宣言されていないのが「添字をつけられた値が配列でもポインタでもありません」の直接的な原因です。

閉鎖

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