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

20151109_13번_일일업무일지_박서연_영상처리(패딩, RGB컨트롤,히스토그램평활화)

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

2015-11-09

*영상처리


#Pading 처리

 가로의 길이가 4의 배수가 아닌 이미지의 경우 픽셀만 차곡차곡 읽어들이면 출력되는 이미지가 밀리는 현상이 발생할텐데, 이것은 패딩(padding)을 고려하지 않았기 때문이다. 예를 들어, bitmap type가 24bit인 경우, 한 픽셀의 크기는 3 바이트다. 그러나, 메모리에 존재하는 비트맵 이미지의 한 줄의 길이는 너비값 * 3이 아닐수도 있다(가로의 길이가 4가 아닌 경우). 한 줄의 길이를 4로 나누어 떨어지도록, 추가 바이트가 존재하기 때문이다. 따라서, 메모리에서 실제 스캔 라인의 길이는 너비와 픽셀 크기를 곱한 값에 패딩 바이트를 더한 값이다. 물론, 너비와 픽셀 당 바이트 수를 곱한 값이 4의 배수라면 추가 바이트는 없다.

그래서 이 패딩을 삽입하여 이미지가 밀리는 현상을 잡아보자.

기존의 코드는 다음과 같다.

 ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 0)= 0;

 ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 1)] = 0;

 ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 2)] = 0;


여기서 비트맵 사이즈를 읽어들인 뒤 uiPad = ST_BFInfor.biWidth % 4;를 추가해준다.

가로가 4의 배수가 아닐때 그 나머지를 패딩에 저장한 뒤 실제 사용할 때에는 패딩비트에 값을 쓰지않고 바로 다음줄로 넘어가기 위한 코드이다.

 ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 0) + (iCount_Y * uiPad)] = 0;

 ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 1) + (iCount_Y * uiPad)] = 0;

 ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 2) + (iCount_Y * uiPad)] = 0;


이런식으로 코딩을 해주면 가로가 401이라도 올바르게 이미지가 표현이 된다.


#Bitmap 이미지 Gray(흑백) 만들기

칼라 이미지를 흑백만으로 표현된 Gray 로 만들어 보자.

Gray로 표현하기 위해서는 한픽셀의 RBG값의 평균을 구하여 그 평균값으로 픽셀의 RGB를 구성해주면 된다.

for (iCount_Y = 0; iCount_Y < ST_BFInfor.biHeight; iCount_Y++) 

{
  
   for (iCount_X = 0; iCount_X < ST_BFInfor.biWidth; iCount_X++) 
   {
     uiAverage = (ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 0) + (iCount_Y * uiPad)]
          + ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 1) + (iCount_Y * uiPad)]
          + ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 2) + (iCount_Y * uiPad)]) / 3;

     ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 0) + (iCount_Y * uiPad)] = uiAverage;
     ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 1) + (iCount_Y * uiPad)] = uiAverage;
     ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 2) + (iCount_Y * uiPad)] = uiAverage;      
  }
}

uiAverage에 픽셀의 RBG평균값을 넣어주고, 그값을 각각의 RGB에 동일하게 넣어준다.




#RGB 밝게 만들기

RGB값을 밝게 만들어 보자. RGB값을 밝게 만들기 위해서 현재 값에서 일정 수를 더해주면 된다.

 for (iCount_Y = 0; iCount_Y < ST_BFInfor.biHeight; iCount_Y++) 

  {
    
     for (iCount_X = 0; iCount_X < ST_BFInfor.biWidth; iCount_X++) 
     {
      //B 밝게하기
      uiAverage = ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 0) + (iCount_Y * uiPad)] + 50;
      if (uiAverage > 255)
      {
        uiAverage = 255;
      }
      ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 0) + (iCount_Y * uiPad)] = uiAverage;

      //G 밝게하기
      uiAverage = ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 1) + (iCount_Y * uiPad)] + 0;
      if (uiAverage > 255)
      {
        uiAverage = 255;
      }
      ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 1) + (iCount_Y * uiPad)] = uiAverage;

      //R 밝게하기
      uiAverage = ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 2) + (iCount_Y * uiPad)] + 0;
      if (uiAverage > 255)
      {
        uiAverage = 255;
      }
      ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 2) + (iCount_Y * uiPad)] = uiAverage;
      
    }
  }

이런식으로 하면 각각의 색만 밝게 만들어 볼 수 있다.






# 히스토그램 평탄화



이러한 기본 지식을 알고 코딩을 해보자


1단계. 히스토그램 구성하기

 // 1단계 히스토그램 만들기

  for (iCount_Y = 0; iCount_Y < ST_BFInfor.biHeight; iCount_Y++) 
  {    
    for (iCount_X = 0; iCount_X < ST_BFInfor.biWidth; iCount_X++) 
    {      
      ++(uiCountB[ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 0) + (iCount_Y * uiPad)]]);  //Blue값 카운터증가
      ++(uiCountG[ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 1) + (iCount_Y * uiPad)]]);  //Green값 카운터증가
      ++(uiCountR[ucBuf[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 2) + (iCount_Y * uiPad)]]);  //Red값 카운터증가
    }
  }


2단계. 누적합 구하기

 //2단계 누적합 구하기

  //초기화
  uiSumR[0= uiCountR[0];
  uiSumG[0= uiCountG[0];
  uiSumB[0= uiCountB[0];

  //누적합 구하기
  
  for (iCount_X = 1; iCount_X < MAXCOLORLEVEL; iCount_X++)
  {
    uiSumR[iCount_X] = uiSumR[iCount_X - 1] + uiCountR[iCount_X];
    uiSumG[iCount_X] = uiSumG[iCount_X - 1] + uiCountG[iCount_X];
    uiSumB[iCount_X] = uiSumB[iCount_X - 1] + uiCountB[iCount_X];
  }


3단계. 정규화

  //3단계 정규화

  uiAverage = ST_BFInfor.biHeight * ST_BFInfor.biWidth;
  for (iCount_X = 0; iCount_X < MAXCOLORLEVEL; iCount_X++)
  {
    uiCountR[iCount_X] = (uiSumR[iCount_X] * 255) / uiAverage;
    uiCountG[iCount_X] = (uiSumG[iCount_X] * 255) / uiAverage;
    uiCountB[iCount_X] = (uiSumB[iCount_X] * 255) / uiAverage;
  }


마지막으로 값 대입하기

 //기존값에 정규화 시킨값 대체

  for (iCount_Y = 0; iCount_Y < ST_BFInfor.biHeight; iCount_Y++)
  {

    for (iCount_X = 0; iCount_X < ST_BFInfor.biWidth; iCount_X++)
    {      
      ucBuf[(iCount_Y* ST_BFInfor.biWidth * 3) + (iCount_X * 3) + 0 + (iCount_Y*uiPad)] =
        uiCountB[ucOrg[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 0) + (iCount_Y * uiPad)]];

      ucBuf[(iCount_Y* ST_BFInfor.biWidth * 3) + (iCount_X * 3) + 1 + (iCount_Y*uiPad)] =
        uiCountG[ucOrg[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 1) + (iCount_Y * uiPad)]];

      ucBuf[(iCount_Y* ST_BFInfor.biWidth * 3) + (iCount_X * 3) + 2 + (iCount_Y*uiPad)] =
        uiCountR[ucOrg[(iCount_Y * ST_BFInfor.biWidth * 3) + (iCount_X * 3 + 2) + (iCount_Y * uiPad)]];

    }
  }


이러한 과정을 거치면 다음과 같은 변화를 알 수 있다. 평할화를 거치면 선명함이 올라간다.(옷의 주름등이 자세히 보인다.)






728x90