Search

숙제로 만들었는데, 꽤 잘 구현한거 같다 ㅡㅡ;;

이젠 자화자찬 하는 미친경지다..이 지겨운 숙제는 언제까지 계속 나오려고 이러지 -_-;

/***********************************************************

  제목 : Sobel Mask 와 Roberts Mask 를 이용한 Edge 검출
  과목 : 영상신호처리
  이름 : 이영곤
  학번 : 1999108145
***********************************************************/
#include <stdio.h>
#include <stdlib.h>
#define ROW 512  
#define COL 512
#define IMG_SIZE (ROW*COL)
#define THRESHOLD 93 // sobel 기준으로 threshold값 설정
void edgeDetect(unsigned char *input , unsigned char *output , int method)
{
int i,j;
int gx=0,gy=0,prevR=0,prevC=0,nextR=0,nextC=0;
for (i = 0 ; i < ROW ; i++) // row
{
 for (j = 0 ; j < COL ; j++) // col
 {
  // 이전 행렬의 범위 제한
  prevR = (i-1 < 0) ? 0 : i-1;
  prevC = (j-1 < 0) ? 0 : j-1;
  nextR = (i+1 > ROW-1) ? ROW-1 : i+1;
  nextC = (j+1 > COL-1) ? COL-1 : j+1;
 
  // 3가지 방법에 따른 gx , gy 값을 구한다.
  if ( method == 0) // robert-cross gradiant
  {
   gx = input[i*ROW+j] - input[prevR*ROW+prevC] ;
   gy = input[i*ROW + prevC] - input[prevR*ROW+j];
  }
  else if ( method == 1) //sobel
  {
   gx = (input[nextR*ROW+prevC] + 2*input[nextR*ROW+j] + input[nextR*ROW+nextC]) -
     (input[prevR*ROW+prevC] + 2*input[prevR*ROW+j] + input[prevR*ROW+nextC]);
   gy = (input[nextR*ROW+nextC] + 2*input[i*ROW+nextC] + input[nextR*ROW+nextC]) -
     (input[prevR*ROW+prevC] + 2*input[i*ROW+prevC] + input[nextR*ROW+prevC]);
  }
  else if ( method == 2) //prewitt
  {
   gx = (input[nextR*ROW+prevC] + input[nextR*ROW+j] + input[nextR*ROW+nextC]) -
     (input[prevR*ROW+prevC] + input[prevR*ROW+j] + input[prevR*ROW+nextC]);
   gy = (input[nextR*ROW+nextC] + input[i*ROW+nextC] + input[nextR*ROW+nextC]) -
     (input[prevR*ROW+prevC] + input[i*ROW+prevC] + input[nextR*ROW+prevC]);
  }
  else
   ;
  output[i*ROW+j] = abs(gx) + abs(gy); // approximatation
 }
}
}
/****************************************************************
** 영상을 이진화 시키는 함수
** result : 입력 영상 결과를 해당 픽셀에 덮어 씌운다.
** threshold : threshold보다 크면 흰색, 작으면 검정
****************************************************************/
void makeBinary(unsigned char* result , int threshold)
{
int i,j;
for (i = 0 ; i < ROW ; i++) // row
{
 for (j = 0 ; j < COL ; j++) // column loop
 {
  result[i*ROW+j] = (result[i*ROW+j] > threshold) ? 255 : 0;
 }
}
}
int main ( void )
{
/***********************************************************************
** 파일 포인터 선언
**  fpIn  : 읽기용
**  fpOut : 쓰기용
***********************************************************************/
FILE *fpIn;
FILE *fpOut;
/***********************************************************************
** 입출력 파일 선언
** inFilename[0] : MIT 영상
** inFilename[1] : Lena 영상
** outFilename[0][0] : MIT Robert edgemap
** outFilename[0][1] : MIT threshold Robert edgemap
** outFilename[0][2] : MIT Sobel edgemap
** outFilename[0][3] : MIT threshold Sobel edgemap
** outFilename[0][4] : MIT Prewitt edgemap
** outFilename[0][5] : MIT threshold Prewitt edgemap
** outFilename[1][0] : Lena Robert edgemap
** outFilename[1][1] : Lena threshold Robert edgemap
** outFilename[1][2] : Lena Sobel edgemap
** outFilename[1][3] : Lena threshold Sobel edgemap
** outFilename[1][4] : Lena Prewitt edgemap
** outFilename[1][5] : Lena threshold Prewitt edgemap
***********************************************************************/
char *inFilename[2] = {"Mit(512x512).raw","Lena(512x512).RAW"};
char *outFilename[2][6] = {"mit_r_edge.raw" , "mit_r_thresh.raw" , "mit_s_edge.raw" , "mit_s_thresh.raw" , "mit_p_edge.raw" , "mit_p_thresh.raw" , "lena_r_edge.raw" , "lena_r_thresh.raw" , "lena_s_edge.raw" , "lena_s_thresh.raw" , "lena_p_edge.raw" , "lena_p_thresh.raw"};
 
/***********************************************************************
** 이미지 포인터 선언
**  pImgSrc : 입력 -> 포인터 배열 사용
**  pImgDst : 출력 -> 포인터 배열 사용
***********************************************************************/
unsigned char *pImgSrc;
unsigned char *pImgDst;
int i,j=0;

for ( i = 0 ; i < 2 ; i++)
{
 /***********************************************************************
 ** 파일을 연다.
 ***********************************************************************/
 fpIn = fopen(inFilename[i],"rb");
 if(fpIn == NULL)
 {
  printf("Can not open file : %s \n", inFilename[i]);
  exit(-1);
 }
 /***********************************************************************
 ** 입.출력 파일이 모두 성공적으로 열렸으면
 ** 이미지들 저장한 포인터에 메모리를 할당한다.
 ***********************************************************************/
 pImgSrc = (unsigned char *) malloc(sizeof(char) * IMG_SIZE);
 if(pImgSrc == NULL)
 {
  printf("Can not allocate memory for pImgSrc\n");
  exit(-1);
 }
 
 pImgDst = (unsigned char *) malloc(sizeof(char) * IMG_SIZE);
 if(pImgDst == NULL)
 {
  printf("Can not allocate memory for pImgDst\n");
  exit(-1);
 }
 /***********************************************************************
 ** 파일에서 이미지 데이터를 읽어서 이미지 버퍼(pImgSrc)에 저장한다.
 ***********************************************************************/
 fread(pImgSrc, sizeof(char),IMG_SIZE, fpIn);
 fclose(fpIn);
 
 /***********************************************************************
 ** j : 0 obert cross edge detect
 ** j : 1 robert edge 영상의 이진화
 ** j : 2 sobel edge detect
 ** j : 3 sobel edge 영상의 이진화
 ** j : 4 prewitt edge detect
 ** j : 5 prewitt edge 영상의 이진화
 ***********************************************************************/
 for ( j = 0 ; j < 6 ; j++)
 {  
  // file open
  fpOut = fopen(outFilename[i][j],"wb");
  if(fpOut == NULL)
  {
   printf("Can not Create file : %s \n", outFilename[i][j]);  
   exit(-1);
  }   
  //edge detect
  edgeDetect(pImgSrc,pImgDst,j/2);
  // data save
  fwrite(pImgDst,sizeof(char),IMG_SIZE, fpOut);
  fclose(fpOut);
 
  j++; // next file
 
  // file open
  fpOut = fopen(outFilename[i][j],"wb");
  if(fpOut == NULL)
  {
   printf("Can not Create file : %s \n", outFilename[i][j]);  
   exit(-1);
  } 
  // make binary image
  makeBinary(pImgDst,THRESHOLD);
  // data save
  fwrite(pImgDst,sizeof(char),IMG_SIZE, fpOut);
  fclose(fpOut);
 } //each image process end
} // all process end
/***********************************************************************
** 이미지 버퍼의 메모리 할당을 해제한다.
***********************************************************************/
free(pImgSrc);
free(pImgDst);
return 0;
}