==================================Outline====================================
BMP파일 가로 크기 패딩 처리
컬러 BMP파일 회색 변환
히스토그램을 사용한 평활화
명암 증가
----------------------------------------------------------------------------
BMP파일 가로 크기 패딩 처리
BMP파일의 가로 크기는 4의 배수여야 하는 규칙을 가지고 있다. 가로의 크기가 4의 배수가 아닐 경우에 사용자가 임의적으로 파일을 쓰게 되면 패딩에 값이 들어가기 때문에 BMP파일의 이미지가 깨지게 된다.
RGB BMP파일을 가로 픽셀의 크기가 401, 세로 픽셀의 크기가 400일로 만들 경우 파일의 용량은 헤더파일 54byte까지 추가하여 481,254byte이다.
![](https://t1.daumcdn.net/cfile/tistory/265C4637564024EB1E)
하지만 패딩이 발생하여 이미지의 크기는 481,654byte가 된다. 올바른 자리에 데이터를 삽입하기 위하여 패딩 값을 고려해주어야 한다.
패딩은 가로 픽셀의 크기를 4의 배수로 맞춰주기 위한 보수 값이다.
BMP파일의가로의 크기는 4의 배수일 때만 정상적으로 수정이 가능하기 때문에 패드 값을 처리해주는 코드를 삽입 한다.
가로의 값이 401일 경우를 생각해보자. 각 픽셀당 RGB로 3byte를 차지함으로 한 줄의 크기는 1203이되고 이 때 4의 배수를 위한 패딩의 값은 1이다.
402일 경우에는 패딩 값이 2, 403일 경우는 패딩 값이 3이다. 즉, 4로 나눈 나머지의 값이 패딩이 된다.
uiPad = stBIHead.biWidth % 4; //패딩 값
패딩 값이 설정되고 나면 이 값을 데이터의 값을 입력하는 이중 for문에 삽입하여 패딩 값을 처리해 주어야한다. 패딩 값은 ‘라인 수 * 패딩 값’이 되는 것을 유의하여야 한다.
for(uiCntY=0; uiCntY < stBIHead.biHeight; ++uiCntY)
{
for(uiCntX=0; uiCntX < stBIHead.biWidth; ++uiCntX)
{
//평균값 연산
uiAVG = ( ucpORG[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 0 + (uiCntY*uiPad)] +
ucpORG[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 1 + (uiCntY*uiPad)] +
ucpORG[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 2 + (uiCntY*uiPad)] )/3;
ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 0 + (uiCntY*uiPad)] = uiAVG;
//blue
ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 1 + (uiCntY*uiPad)] = uiAVG;
//green
ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 2 + (uiCntY*uiPad)] = uiAVG;
/
/red
}
}
패딩 설정을 해주고나면 가로 픽셀이 4의 배수가 아니더라도 데이터가 원하는대로 입력된다.
![](https://t1.daumcdn.net/cfile/tistory/27586B37564024ED22)
컬러 BMP파일 회색 변환
컬러 BMP사진을 흑백으로 변환해보자. 컬러를 흑백으로 변환하는 건 쉽다. 원래의 이미지를 저장한 다음 RGB의 각 값만을 추출하여 표시해보자.
동적할당을 받아 원래의 이미지를 저장한다. 이 때 메모리를 복사하는 ‘memcopy'함수를 사용한다.
![](https://t1.daumcdn.net/cfile/tistory/24680D37564024EE12)
원하는 색만 추출하기 위해서는 다른 값은 ‘0’을 삽입하고 원하는 색은 주석 처리해준다.
원하는 값이 나오는 것을 확인할 수 있다.
![](https://t1.daumcdn.net/cfile/tistory/246BEC37564024F00E)
디지털 영상의 히스토그램
RGB의 값의 정도를 나타내주는 그래프이다. 히스토그램을 활용하여 평활화를 시켜보자. 히스토그램의 평활화는 비슷한 값의 집단을 하나로 합쳐준다.
평활화의 단계는 다음과 같다.
1단계: 각 픽셀의 명도수를 구한다.
![](https://t1.daumcdn.net/cfile/tistory/2471FB37564024F108)
2단계: 명도의 단계별로 누적합을 구하는 작업이다.
![](https://t1.daumcdn.net/cfile/tistory/2546FC37564024F232)
3단계: 누적된 값을 픽셀의 개수로 나눈 후 명도의 단계 - 1의 값으로 곱해준다.
요약하면 아래와 같다.
![](https://t1.daumcdn.net/cfile/tistory/27759D37564024F302)
![](https://t1.daumcdn.net/cfile/tistory/25228339564024F427)
히스토그램을 사용한 평활화
히스토그램을 위한 코딩을 해보자.
1. 히스토그램의 생성
//// Equialization
//// 1단계: 히스토그램 생성
for(uiCntY=0; uiCntY < stBIHead.biHeight; ++uiCntY)
{
for(uiCntX=0; uiCntX < stBIHead.biWidth; ++uiCntX)
{
++uiCntB[ ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 0 + (uiCntY*uiPad)] ]; //blue
++uiCntG[ ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 1 + (uiCntY*uiPad)] ]; //green
++uiCntR[ ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 2 + (uiCntY*uiPad)] ]; //red
}
}
각 픽셀 값의 RGB 값을 추출하여 각 값이 몇 개나 있는지 빈도수를 계산해준다.
2. 누적합 계산
정규화를 연산을 위해 누적합을 계산해준다.
//// 2단계: 누적합 계산
uiSumR[0] = uiCntR[0];
uiSumG[0] = uiCntG[0];
uiSumB[0] = uiCntB[0];
for(uiCntX = 1; 256 > uiCntX; ++uiCntX)
{
uiSumR[uiCntX] = uiSumR[uiCntX-1] + uiCntR[uiCntX];
uiSumG[uiCntX] = uiSumG[uiCntX-1] + uiCntG[uiCntX];
uiSumB[uiCntX] = uiSumB[uiCntX-1] + uiCntB[uiCntX];
}
3. 정규화
//// 3단계: 정규화uiCntY = stBIHead.biWidth * stBIHead.biHeight;for(uiCntX = 0; 256 > uiCntX; ++uiCntX) { uiCntR[uiCntX] = (uiSumR[uiCntX]*255)/uiCntY; uiCntG[uiCntX] = (uiSumG[uiCntX]*255)/uiCntY; uiCntB[uiCntX] = (uiSumB[uiCntX]*255)/uiCntY; }
정규화 계산식을 이용하여 정규화해준다.
4. 이미지에 적용
/// 이미지에 적용for(uiCntY=0; uiCntY < stBIHead.biHeight; ++uiCntY) { for(uiCntX=0; uiCntX < stBIHead.biWidth; ++uiCntX) { ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 0 + (uiCntY*uiPad)] = uiCntB[ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 0 + (uiCntY*uiPad)]]; //blue ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 1 + (uiCntY*uiPad)] = uiCntG[ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 1 + (uiCntY*uiPad)]]; //green ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 2 + (uiCntY*uiPad)] = uiCntR[ucpBuf[uiCntY * (stBIHead.biWidth * 3) + (uiCntX * 3) + 2 + (uiCntY*uiPad)]]; //red }}
정규화된 값을 이미지에 적용하여 평활화시킨다.
![](https://t1.daumcdn.net/cfile/tistory/263D8A3356404AFA13)
![](https://t1.daumcdn.net/cfile/tistory/25255E3356404AFB28)
명암 증가
RBG값에 50을 더하여 값을 삽입해보자. 값이 255를 넘을 경우 최대 값이 255가 되도록 설정한다.
![](https://t1.daumcdn.net/cfile/tistory/2650093356404AFF05)
//jpg파일은 압축기법을 공부하지 않고서는 BMP파일처럼 조작하기 어렵다.