C

C言語での画像処理

風邪で倒れておりました…(┐「ε:)

今回は画像処理についてのプログラムです。
それぞれの詳細について後々追記予定です。
まずは入力カラー画像をグレー画像に変換。

カラー画像 -> グレー画像

#include <gd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(const int argc, const char *argv[]){
  FILE *out,*in;
  gdImagePtr im,im_new;
  int width,height,i,j,color,r,g,b,pixel,y;

  if(argv[1]==NULL||argv[2]==NULL||!strcmp(argv[1],argv[2])){
    printf("argument error\n");
    exit(-1);
  }

  //第一引数で指定されたファイルを読み出し用にオープン
  if((in=fopen(argv[1],"r"))==NULL){
    printf("file open error for %s\n",argv[1]);
    exit(-1);
  }
  //第二引数で指定されたファイルを書き出し用にオープン
  if((out=fopen(argv[2],"wb"))==NULL){
    printf("file open error for %s\n",argv[2]);
    exit(-1);
  }

  //im に画像を読み込み
  im = gdImageCreateFromJpeg(in);

  //入力画像のサイズを取得
  width=gdImageSX(im);
  height=gdImageSY(im);

  //新しい画像を用意
  im_new= gdImageCreateTrueColor(width,height);

  for(i=0;i<width;i++){
    for(j=0;j<height;j++){

      //im の (i,j) におけるカラーインデックスの取得
      pixel=gdImageGetPixel(im,i,j);

      //im の (i,j) における r,g,b の値を取得
      r=gdImageRed(im,pixel);
      g=gdImageGreen(im,pixel);
      b=gdImageBlue(im,pixel);

      //yへ変換して、colorを割り当て
      y = 0.299*r + 0.587*g + 0.144*b;
      color=gdImageColorExact(im_new,y,y,y);

      //im_new の (i,j) におけるピクセル値を color で設定
      gdImageSetPixel(im_new,i,j,color);
    }
  }

  gdImageJpeg(im_new,out,-1);

  fclose(in);
  fclose(out);

  return 0;

}

お次は入力カラー画像にメディアンフィルタをかけます。

メディアンフィルタ

#include <gd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int compare_int(const void *a, const void *b){
  return *(int*)a - *(int*)b;
}

int main(const int argc, const char *argv[]){
  FILE *out,*in;
  gdImagePtr im,im_new;
  int width,height,i,j,k,color,m,n,count,
      red[9],green[9],blue[9],pixels[9];

  if(argv[1]==NULL||argv[2]==NULL||!strcmp(argv[1],argv[2])){
    printf("argument error\n");
    exit(-1);
  }

  //第一引数で指定されたファイルを読み出し用にオープン
  if((in=fopen(argv[1],"r"))==NULL){
    printf("file open error for %s\n",argv[1]);
    exit(-1);
  }
  //第二引数で指定されたファイルを書き出し用にオープン
  if((out=fopen(argv[2],"wb"))==NULL){
    printf("file open error for %s\n",argv[2]);
    exit(-1);
  }

  //im に画像を読み込み
  im = gdImageCreateFromJpeg(in);

  //入力画像のサイズを取得
  width=gdImageSX(im);
  height=gdImageSY(im);

  //新しい画像を用意
  im_new= gdImageCreateTrueColor(width,height);

  for(i=0;i<width;i++){
    for(j=0;j<height;j++){
      //端っこは無視
      if (i==0 || i==width-1 || j==0 || j==height-1){
        //im の (i,j) におけるカラーインデックスの取得
        pixels[0]=gdImageGetPixel(im,i,j);

        //im の (i,j) における r,g,b の値を取得
        r[0]=gdImageRed(im,pixels[0]);
        g[0]=gdImageGreen(im,pixels[0]);
        b[0]=gdImageBlue(im,pixels[0]);

        //r,g,b 値から color を割り当て
        color=gdImageColorExact(im_new,r[0],g[0],b[0]);

        //im_new の (i,j) におけるピクセル値を color で設定
        gdImageSetPixel(im_new,i,j,color);
      }else{
        //im の (i,j) の周りにおけるカラーインデックスの取得
        for(m = -1, count = 0; m <= 1; m++){
          for(n = -1; n <= 1; n++){
            pixels[count++] = gdImageGetPixel(im, i+m, j+n);
          }
        }

        //im の (i,j) の周りにおける r,g,b の値を取得
        for(k = 0; k<9; k++){
          red[k]   = gdImageRed(im,pixels[k]);
          green[k] = gdImageGreen(im,pixels[k]);
          blue[k]  = gdImageBlue(im,pixels[k]);
        }

        //中央値を取るためにsort
        qsort(red,   9, sizeof(int), compare_int);
        qsort(green, 9, sizeof(int), compare_int);
        qsort(blue,  9, sizeof(int), compare_int);

        //中央値から color を割り当て
        color=gdImageColorExact(im_new,red[4],green[4],blue[4]);

        //im_new の (i,j) におけるピクセル値を color で設定
        gdImageSetPixel(im_new,i,j,color);
      }
    }
  }
  gdImageJpeg(im_new,out,-1);

  fclose(in);
  fclose(out);

  return 0;
}

お次は入力カラー画像にエッジフィルター(ラプラシアンフィルター)をかけます。

#include <gd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define N 3

int compare_int(const void *a, const void *b){
    return *(int*)a - *(int*)b;
}

int main(const int argc, const char *argv[]){
  FILE *out,*in;
  gdImagePtr im,im_new;
  int width,height,i,j,k,color,m,n,pixel,sumred,sumgreen,sumblue,
      y,count,red[N*N],green[N*N],blue[N*N],pixels[N*N];
  // ラプラシアン
  int filter[N*N]={1,  1,  1,
                   1, -8,  1,
                   1,  1,  1};

  if(argv[1]==NULL||argv[2]==NULL||!strcmp(argv[1],argv[2])){
    printf("argument error\n");
    exit(-1);
  }

  //第一引数で指定されたファイルを読み出し用にオープン
  if((in=fopen(argv[1],"r"))==NULL){
    printf("file open error for %s\n",argv[1]);
    exit(-1);
  }
  //第二引数で指定されたファイルを書き出し用にオープン
  if((out=fopen(argv[2],"wb"))==NULL){
    printf("file open error for %s\n",argv[2]);
    exit(-1);
  }

  //im に画像を読み込み
  im = gdImageCreateFromJpeg(in);

  //入力画像のサイズを取得
  width=gdImageSX(im);
  height=gdImageSY(im);

  //新しい画像を用意
  im_new= gdImageCreateTrueColor(width,height);

  for(i = 0; i < width; i++){
    for(j = 0; j < height; j++){

      //端っこは無視
      if (i==0 || i==width-1 || j==0 || j==height-1){
        //im の (i,j) におけるカラーインデックスの取得
        pixels[0]=gdImageGetPixel(im,i,j);

        //im の (i,j) における r,g,b の値を取得
        r[0]=gdImageRed(im,pixels[0]);
        g[0]=gdImageGreen(im,pixels[0]);
        b[0]=gdImageBlue(im,pixels[0]);

        //r,g,b 値から color を割り当て
        color=gdImageColorExact(im_new,r[0],g[0],b[0]);

        //im_new の (i,j) におけるピクセル値を color で設定
        gdImageSetPixel(im_new,i,j,color);
    }else{
        //im の (i,j) との周りのカラーインデックスの取得
        for(m = -(N/2), count = 0; m <= N/2; m++)
          for(n = -(N/2); n <= N/2; n++)
            pixels[count++] = gdImageGetPixel(im, i+m, j+n);

        //im の(i,j)とその周りにおける r,g,b の値を取得
        for(k = 0; k < N*N; k++){
          red[k]   = gdImageRed(im, pixels[k]);
          green[k] = gdImageGreen(im, pixels[k]);
          blue[k]  = gdImageBlue(im, pixels[k]);
        }

        for(k = 0,sumred=0,sumgreen=0,sumblue=0; k < N*N; k++){
          sumred   += red[k]   * filter[k];
          sumgreen += green[k] * filter[k];
          sumblue  += blue[k]  * filter[k];
        }

        y = 0.299*sumred + 0.587*sumgreen + 0.114*sumblue;

        //y値から color を割り当て
        color = gdImageColorExact(im_new, y, y, y);

        //im_new の (i,j) におけるピクセル値を color で設定
        gdImageSetPixel(im_new,i,j,color);


      }
    }
  }
  gdImageJpeg(im_new,out,-1);

  fclose(in);
  fclose(out);

  return 0;
}