해당 포스트는 "열혈강의 영상처리 프로그래밍" 책의 내용을 요약한 것이다.



※ 배경 분리를 이용한 영상 분할

앞 포스트에서 배운 이진화를 통한 영상 분할은 밝기값을 기준으로 이진화를 수행한다. 영상이 복잡해 영상의 배경과 물체의 밝기값이 비슷할 시 밝기값을 기준으로 한 이진화는 문턱값을 적절히 조절하더라도 제대로 된 영상 분할 결과를 얻지 못한다. 이렇게 복잡한 영상에 대한 영상 분할 알고리즘 중 가장 쉽게 구현하고 실제 시스템에 적용할 수 있는 배경 분리를 이용한 영상 분할 기법에 대해서 알아보자.


배경 분리를 이용한 영상 분할은 감시 시스템이나 불량 검출 시스템과 같이 배경 영상을 미리 촬영해둘 수 있는 스템에서 매우 유용하다. 예를 들어, 감시 영역을 사람이 없는 상태에서 촬영하고 이 영상을 사람이 있을 때 촬영한 영상과 비교하면 사람에 해당하는 영역을 분리할 수 있다. 단, 배경 영상과 검사 영상은 카메라의 위치가 동일해야 하며 밝기 등의 변화가 있으면 보정해야 한다.


이러한 배경 분리를 이용한 영상 분할은 입력 영상과 배경 영상의 빼서 얻은 결과에 문턱값을 적용하여 영상 이진화를 수행해 구현한다. 회색조 영상의 경우 두 영상 밝기값 차의 절대값에 문턱값을 적용하여 이진화를 수행한다. 컬러 영상은 각 채널 밝기 값의 차에 제곱한 값을 문턱값의 제곱값을 적용하여 이진화를 수행한다. 다음은 이에 관한 코드이다.


void BinarizationBG(const CByteImage& imageIn, const CByteImage& imageBG, 
						  CByteImage& imageOut, int nThreshold)
{
	ASSERT(imageIn.GetChannel()==1); // 회색조 영상 확인

	int nWidth  = imageIn.GetWidth();
	int nHeight = imageIn.GetHeight();

	for (int r=0 ; r<nHeight ; r++)
	{
		BYTE* pIn	= imageIn.GetPtr(r);
		BYTE* pBG	= imageBG.GetPtr(r);
		BYTE* pOut	= imageOut.GetPtr(r);

		for (int c=0 ; c<nWidth ; c++)
		{
			if (abs(pIn[c]-pBG[c]) > nThreshold)
				pOut[c] = 255;
			else
				pOut[c] = 0;
		}
	}
}

void BinarizationBGCol(const CByteImage& imageIn, const CByteImage& imageBG, 
							 CByteImage& imageOut, int nThreshold)
{
	ASSERT(imageIn.GetChannel()==3); // 컬러 영상 확인

	nThreshold *= nThreshold; // 문턱값을 제곱

	int nWidth  = imageIn.GetWidth();
	int nHeight = imageIn.GetHeight();

	int dB, dG, dR, dd;
	for (int r=0 ; r<nHeight ; r++)
	{
		BYTE* pIn	= imageIn.GetPtr(r);
		BYTE* pBG	= imageBG.GetPtr(r);
		BYTE* pOut	= imageOut.GetPtr(r);

		int pos = 0;
		for (int c=0 ; c<nWidth ; c++)
		{
			dB = pIn[pos]-pBG[pos]; pos++;
			dG = pIn[pos]-pBG[pos]; pos++;
			dR = pIn[pos]-pBG[pos]; pos++;
			dd = dB*dB + dG*dG + dR*dR;
			if (dd > nThreshold) // 제곱끼리 비교
				pOut[c] = 255;
			else
				pOut[c] = 0;
		}
	}
}

위 메서드들은 문턱값을 매개변수로 해서 해당 문턱값을 바로 적용했는 데 바로 전 포스트에서 배운 자동 문턱값 조절 코드를 넣어서 구현을 해도 좋다. 다음은 그림은 위 메서드 실행 결과이다.




배경 분리를 이용한 위 그림을 보면 분할된 손에 조그만 검정색 표시가 아직 있다. 위 그림에서 배경 영상과 손 사이에 비슷한 색이 없는 것처럼 보여도 실제 영상의 잡음으로 두 영상에서 같은 위치의 픽셀이 문턱값 이하의 차이를 가질 수 있다. 그래서 앞에서 배운 가우스 필터를 이용해 잡음을 제거 해주고 배경 분리를 이용해 영상 분할을 한다면 다음과 같이 더 깔끔한 분할 결과가 나온다.



+ Recent posts