본문 바로가기
코스웨어/15년 스마트컨트롤러

20151110 안향진 영상처리 대칭, 회전

by 알 수 없는 사용자 2015. 11. 11.
728x90
반응형

<영상처리>


=회전

-90도 회전 가능

-90도 이외 -> 삼각함수(cos, sin, tan) 도입되어야 함

 

=미러링

-y축 대칭

<mirrory.c>

#include <stdio.h>
#include <fcntl.h>
#include <windows.h>

int main(int iNum, char * cpArr[])
{
  
int iRtn;
  
int iFd;

  BITMAPFILEHEADER stBFHead;
  BITMAPINFOHEADER stBFInfo;
  
unsigned char * ucpOrg;
  
unsigned char * ucpBuf;
  
int iCntX;
  
int iCntY;
  
unsigned int uiPad;  

  
if(2 > iNum)
  {
    
return -1;
  }

  iFd 
= open(cpArr[1], O_RDWR | O_BINARY); 
  
if(iFd < 0)
  {
    printf(
"파일을 열 수 없습니다.\n");
    
return -1;
  }

  iRtn 
= read(iFd, &stBFHead, sizeof(BITMAPFILEHEADER));
  
if(iRtn == 0)
  {
    printf(
"파일을 읽을 수 없습니다.\n");
    close(iFd); 
    
return -1;
  }
  
if0x4D42 != (stBFHead.bfType) )
  {
    printf(
"BMP파일이 아닙니다.\n");
    close(iFd); 
    
return -1;
  }

  iRtn 
= read(iFd, &stBFInfo, sizeof(BITMAPINFOHEADER));
  
if(iRtn == 0)
  {
    printf(
"Info 헤더가 존재하지 않습니다..\n");
    close(iFd); 
    
return -1;
  }  
  uiPad 
= stBFInfo.biWidth%4;// padding 추출

  ucpBuf = (unsigned char *)malloc(stBFInfo.biSizeImage);
  
if(0 == ucpBuf)
  {
    printf(
"Malloc Fail\n");
    
return -1;
  }

  ucpOrg 
= (unsigned char *)malloc(stBFInfo.biSizeImage);
  
if(0 == ucpOrg)
  {
    printf(
"Malloc Fail\n");
    free(ucpBuf);
    
return -1;
  }
  
  iRtn 
= read(iFd, ucpOrg, stBFInfo.biSizeImage);
  
if(iRtn == 0)
  { 
    free(ucpBuf);
    free(ucpOrg);
    
return -1;

  }
  close(iFd);
  

  
for(iCntY =0 ; iCntY < stBFInfo.biHeight; ++iCntY )
  {
    
for(iCntX = 0; iCntX < stBFInfo.biWidth; ++iCntX)
    {    
      ucpBuf[(iCntY*stBFInfo.biWidth*
3) - ((iCntX)*3)-0) - (iCntY*uiPad)-3] = 

       ucpOrg[(iCntY*stBFInfo.biWidth*3) + (iCntX*3)+0 + (iCntY*uiPad)];
      
      ucpBuf[((iCntY+
1)*stBFInfo.biWidth*3) - ((iCntX*3)-1) - (iCntY*uiPad)-3] = 

       ucpOrg[(iCntY*stBFInfo.biWidth*3) + (iCntX*3)+1 + (iCntY*uiPad)];
      
      ucpBuf[((iCntY+
1)*stBFInfo.biWidth*3) - ((iCntX*3)-2) - (iCntY*uiPad)-3] = 

       ucpOrg[(iCntY*stBFInfo.biWidth*3) + (iCntX*3)+2 + (iCntY*uiPad)];
    }
    
  }

  iFd 
= open("mirror.bmp", O_CREAT | O_TRUNC | O_BINARY | O_WRONLY, 0666); 
  
  
if(iFd < 0)
  {
    printf(
"MIRROR 파일을 열 수 없습니다.\n");
    free(ucpBuf);
    free(ucpOrg);
    
return -1;
  }

  iRtn 
= write(iFd, &stBFHead, sizeof(BITMAPFILEHEADER));
  
if(iRtn == 0)
  {
    printf(
"MIRROR 파일을 쓸 수 없습니다.\n");
    close(iFd);
    free(ucpBuf);
    free(ucpOrg);  
    
return -1;
  }
  iRtn 
= write(iFd, &stBFInfo, sizeof(BITMAPINFOHEADER));
  
if(iRtn == 0)
  {
    printf(
"MIRROR 파일을 쓸 수 없습니다.\n");
    close(iFd);
    free(ucpBuf);  
    free(ucpOrg);  
    
return -1;
  }
  iRtn 
= write(iFd, ucpBuf, stBFInfo.biSizeImage);
  
if(iRtn == 0)
  {
    printf(
"MIRROR 파일을 쓸 수 없습니다.\n");
    close(iFd);
    free(ucpBuf);  
    free(ucpOrg);  
    
return -1;
  }

  close(iFd);


  free(ucpBuf);  
  free(ucpOrg);
  
return 0;
}




=x축 대칭


<mirrorx.c>

  for(iCntY =0 ; iCntY < stBFInfo.biHeight; ++iCntY )
  {
    
for(iCntX = 0; iCntX < stBFInfo.biWidth; ++iCntX)
    {    
      ucpBuf[((stBFInfo.biHeight-
1-iCntY)*stBFInfo.biWidth*3) + ((iCntX*3)+0) + (iCntY*uiPad)] = 

       ucpOrg[(iCntY*stBFInfo.biWidth*3) + (iCntX*3)+0 + (iCntY*uiPad)];      
      ucpBuf[((stBFInfo.biHeight-
1-iCntY)*stBFInfo.biWidth*3) + ((iCntX*3)+1) + (iCntY*uiPad)] = 

       ucpOrg[(iCntY*stBFInfo.biWidth*3) + (iCntX*3)+1 + (iCntY*uiPad)];      
      ucpBuf[((stBFInfo.biHeight-
1-iCntY)*stBFInfo.biWidth*3) + ((iCntX*3)+2) + (iCntY*uiPad)] = 

       ucpOrg[(iCntY*stBFInfo.biWidth*3) + (iCntX*3)+2 + (iCntY*uiPad)];
    }
    
  }
  













=원점대칭


<rotate180.c>

  for(iCntY =0 ; iCntY < stBFInfo.biHeight; ++iCntY )
  {
    
for(iCntX = 0; iCntX < stBFInfo.biWidth; ++iCntX)
    {    
      ucpBuf[((stBFInfo.biHeight-
1-iCntY)*stBFInfo.biWidth*3) + (((stBFInfo.biWidth-1-iCntX)*3)+0) + (iCntY*uiPad)] = 

       ucpOrg[(iCntY*stBFInfo.biWidth*3) + (iCntX*3)+0 + (iCntY*uiPad)];      
      ucpBuf[((stBFInfo.biHeight-
1-iCntY)*stBFInfo.biWidth*3) + (((stBFInfo.biWidth-1-iCntX)*3)+1) + (iCntY*uiPad)] = 

       ucpOrg[(iCntY*stBFInfo.biWidth*3) + (iCntX*3)+1 + (iCntY*uiPad)];      
      ucpBuf[((stBFInfo.biHeight-
1-iCntY)*stBFInfo.biWidth*3) + (((stBFInfo.biWidth-1-iCntX)*3)+2) + (iCntY*uiPad)] = 

       ucpOrg[(iCntY*stBFInfo.biWidth*3) + (iCntX*3)+2 + (iCntY*uiPad)];
    }    
  }











=90도 회전


<main.c>

#include <stdio.h>

#define MX 3
#define MY 4

int main()
{
  
int A[MY][MX];
  
int B[MX][MY];
  
int ix;
  
int iy;

  printf(
"-Origin \n");
  
for(iy = 0; iy < MY; ++iy)
  {
    
for(ix = 0; ix <MX; ++ix)
    {
      A[iy][ix] 
= 1 + (iy*MX) +ix;
      printf(
"%2d ",A[iy][ix]);
    }
    printf(
"\n");
  }
  
  
for(iy = 0; iy < MY; ++iy)
  {
    
for(ix = 0; ix <MX; ++ix)
    {
      B[ix][MY-
1-iy] = A[iy][ix]; // 이미지 270도
      //B[MX-1-ix][iy] = A[iy][ix];  // 이미지 90도    
    }
  }
  printf(
"\n-Rotate 90 \n");
  
for(iy = 0; iy < MX; ++iy)
  {
    
for(ix = 0; ix < MY; ++ix)
    {
      printf(
"%2d ",B[iy][ix]);
    }
    printf(
"\n");
  }
  
  
return 0;
}


















=

가로, 세로 달라짐

패딩값이 달라지면 용량도 달라짐 ==> 헤더에 새로 써넣어야 함

Org, Buf의 메모리 할당도 달라짐


=이미지 사이즈 일반화

가로*((세로*3)+(세로%4))



=상하반전이므로


=>B[ix][MY-1-iy] = A[iy][ix]; // 이미지 270도 회전

B[0][2]=A[0][0]

B[1][2]=A[0][1]

B[2][2]=A[0][2]




=>B[MX-1-ix][iy] = A[iy][ix];  // 이미지 90도 회전

B[2][0]=A[0][0]

B[1][0]=A[0][1]

B[0][0]=A[0][2]

















<rotate90.c>

#include <stdio.h>
#include <fcntl.h>
#include <windows.h>

int main(int iNum, char * cpArr[])
{
  
int iRtn;
  
int iFd;

  BITMAPFILEHEADER stBFHead;
  BITMAPINFOHEADER stBFInfo;
  
unsigned char * ucpOrg;
  
unsigned char * ucpBuf;
  
int iCntX;
  
int iCntY;
  
unsigned int uiPad;  
  
unsigned int uiPad2;  

  
if(2 > iNum)
  {
    
return -1;
  }

  iFd 
= open(cpArr[1], O_RDWR | O_BINARY); 
  
if(iFd < 0)
  {
    printf(
"파일을 열 수 없습니다.\n");
    
return -1;
  }

  iRtn 
= read(iFd, &stBFHead, sizeof(BITMAPFILEHEADER));
  
if(iRtn == 0)
  {
    printf(
"파일을 읽을 수 없습니다.\n");
    close(iFd); 
    
return -1;
  }
  
if0x4D42 != (stBFHead.bfType) )
  {
    printf(
"BMP파일이 아닙니다.\n");
    close(iFd); 
    
return -1;
  }

  iRtn 
= read(iFd, &stBFInfo, sizeof(BITMAPINFOHEADER));
  
if(iRtn == 0)
  {
    printf(
"Info 헤더가 존재하지 않습니다..\n");
    close(iFd); 
    
return -1;
  }  
  uiPad 
= stBFInfo.biWidth%4;// padding 추출

  ucpOrg = (unsigned char *)malloc(stBFInfo.biSizeImage);
  
if(0 == ucpOrg)
  {
    printf(
"Malloc Fail\n");    
    
return -1;
  }

  iRtn 
= read(iFd, ucpOrg, stBFInfo.biSizeImage);
  
if(iRtn == 0)
  { 
    
//free(ucpBuf);
    free(ucpOrg);
    
return -1;

  }
  
  stBFInfo.biSizeImage 
= stBFInfo.biWidth*((stBFInfo.biHeight*3)+(stBFInfo.biHeight%4));
  ucpBuf 
= (unsigned char *)malloc(stBFInfo.biSizeImage); // 새로운 사이즈로 메모리 할당
  if(0 == ucpBuf)
  {
    printf(
"Malloc Fail\n");
    free(ucpOrg);
    
return -1;
  }  

  close(iFd);
  
  uiPad2 
= stBFInfo.biHeight%4;// padding 추출
  for(iCntY =0 ; iCntY < stBFInfo.biHeight; ++iCntY )
  {
    
for(iCntX = 0; iCntX < stBFInfo.biWidth; ++iCntX)
    {    
      ucpBuf[((stBFInfo.biWidth -
1 -iCntX)*stBFInfo.biHeight*3) + (((iCntY)*3)+0) + ((stBFInfo.biWidth -1-iCntX)*uiPad2)] = 
      ucpOrg[(iCntY*stBFInfo.biWidth*
3) + (iCntX*3)+0 + (iCntY*uiPad)];
      
      ucpBuf[((stBFInfo.biWidth -
1 -iCntX)*stBFInfo.biHeight*3) + (((iCntY)*3)+1) + ((stBFInfo.biWidth -1-iCntX)*uiPad2)] = 
      ucpOrg[(iCntY*stBFInfo.biWidth*
3) + (iCntX*3)+1 + (iCntY*uiPad)];

      ucpBuf[((stBFInfo.biWidth -
1 -iCntX)*stBFInfo.biHeight*3) + (((iCntY)*3)+2) + ((stBFInfo.biWidth -1-iCntX)*uiPad2)] = 
      ucpOrg[(iCntY*stBFInfo.biWidth*
3) + (iCntX*3)+2 + (iCntY*uiPad)];
    
    }  

  }
  
  iFd 
= open("rot90.bmp", O_CREAT | O_TRUNC | O_BINARY | O_WRONLY, 0666); 
  
  
if(iFd < 0)
  {
    printf(
"MIRROR 파일을 열 수 없습니다.\n");
    free(ucpBuf);
    free(ucpOrg);
    
return -1;
  }
  
  stBFHead.bfSize 
= 54 +  stBFInfo.biSizeImage;//sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
    //(stBFInfo.biWidth*((stBFInfo.biHeight*3)+(stBFInfo.biHeight%4)));
  
  iCntX 
= stBFInfo.biWidth;
  stBFInfo.biWidth 
= stBFInfo.biHeight;
  stBFInfo.biHeight 
= iCntX;
  
  iRtn 
= write(iFd, &stBFHead, sizeof(BITMAPFILEHEADER));
  
if(iRtn == 0)
  {
    printf(
"MIRROR 파일을 쓸 수 없습니다.\n");
    close(iFd);
    free(ucpBuf);
    free(ucpOrg);  
    
return -1;
  }
  
  iRtn 
= write(iFd, &stBFInfo, sizeof(BITMAPINFOHEADER));
  
if(iRtn == 0)
  {
    printf(
"MIRROR 파일을 쓸 수 없습니다.\n");
    close(iFd);
    free(ucpBuf);  
    free(ucpOrg);  
    
return -1;
  }
  iRtn 
= write(iFd, ucpBuf, stBFInfo.biSizeImage);
  
if(iRtn == 0)
  {
    printf(
"MIRROR 파일을 쓸 수 없습니다.\n");
    close(iFd);
    free(ucpBuf);  
    free(ucpOrg);  
    
return -1;
  }

  close(iFd);


  free(ucpBuf);  
  free(ucpOrg);
  
return 0;
}

















=OPEN CV =>얼굴찾기


=지문인식 => 얼굴인식


=배경 물체 구분


<소스파일>


20151110_영상처리.zip



728x90