open-cv 영상처리

opencv c++ sobel filter

hojung 2022. 3. 23.
728x90
반응형

1. sobel filter 

sobel filter란 주파수의 방향성에 따라 필터링을 해주는 필터이다. 예를 들어 

이러한 이미지의 경우 수직으로는 변화량이 거의 없지만 수평으로는 흰색 검은색이 반복하며 변화량이 큰 것을 알 수 있다. 이러한 이미지를 sobel filter에 넣고 적용하면 수평 방향으로 이미지가 나오게 된다. 

 

c++ 로 sobel filter를 구현하는 코드는 다음과 같다. 

Mat mySobelFilter(Mat srcImg)
{
	int kernelX[3][3] = { -1, -1,2,
						-1,2,-1,
						2 ,-1,-1 }; // 45도 마스크
	int kernelY[3][3] = { 2,-1,-1,
						 -1,2,-1,
						 -1,-1,2 }; //135도 마스크

	//마스크 합이 0이 되므로 1로 정규화하는 과정은 필요 없음

	Mat dstImg(srcImg.size(), CV_8UC1);
	uchar* srcData = srcImg.data;
	uchar* dstData = dstImg.data;
	int width = srcImg.cols;
	int height = srcImg.rows;

	for (int y = 0; y < height; y++)
	{
		for (int x = 0; x < width; x++)
		{
			dstData[y * width + x] = (abs(myKernelCon3x3(srcData, kernelX, x, y, width, height)) + abs(myKernelCon3x3(srcData, kernelY, x, y, width, height))) / 2;
			//두 에지 결과의 절대값 합 형태로 최종 결과 도출

		}
	}
	return dstImg;
}

위의 sobel filter를 씌우는 마스크들을 살펴보면 

45도를 나타내는 sobel mask는 

-1 -1 2

-1 2 -1

2 -1 -1

로 나타나있다. 이는 오른쪽 상단 방향으로 2(큰 값)이 포진해있고 나머지 방향으로의 방향성은 상대적으로 죽이겠다는 것이다. 

또한 135도를 나타내는 sobel mask는 45도와 수직으로 대칭이므로

2 -1 -1

-1  2 -1

-1 -1  2

로 나타나있다. 이는 왼쪽 위 방향으로 2가 대각선으로 펼쳐져 있는 모습이다. 

이 마스크들을 또한 convolution이라는 과정을 통해 계산을 해야한다. 

convolution이란 시스템의 출력을 구하는 식으로

수식으로는 다음과 같다. 

합성곱이라고도 불린다. 기하학적으로는 원본 신호와 입력되는 신호를 뒤집은 후 이동시키면서 겹치는 면적의 크기를 의미한다. 

따라서 저런 적분 수식을 코드로 구현하면 다음과 같아진다. 

int myKernelCon3x3(uchar* arr, int kernel[][3], int x, int y, int width, int height) //convolution
{
	int sum = 0;
	int sumKernel = 0;

	for (int j = -1; j <= 1; j++)
	{
		for (int i = -1; i <= 1; i++)
		{
			if ((y + j) >= 0 && (y + j) < height && (x + i) >= 0 && (x + i) < width)
			{
				sum += arr[(y + j) * width + (x + i)] * kernel[i + 1][j + 1];
				sumKernel += kernel[i + 1][j + 1];// 적분의 형태 높이와 밑변을 곱한 사각형들을 모두 더해주는 식 
			}
		}
	}
	if (sumKernel != 0) { return sum / sumKernel; } //합이 1로 정규화되도록 해 영상의 밝기 변화 방지
	else { return sum; }
}

따라서 sobel mask를 구하고 원본 이미지에 sobel mask를 처음서부터 convolution하면서 이동시키면 우리가 적용시킨 sobel mask에 해당하는 45도 135도에 해당하는 주파수 성분들만 강조되어서 나올 것이다. 


2. 결과

원본 이미지는 앞서 가우시안 필터링을 포스팅한 포스트에서 쓴 이미지와 같은 이미지를 사용하였다. 

sobel filter를 적용한 모습이다. 대각선에 해당하는 부분들이 잘 출력된 것을 확인할 수 있다. 

728x90
반응형

'open-cv 영상처리' 카테고리의 다른 글

opencv C++ BandPass Filter  (2) 2022.03.24
opencv c++ 가우시안 필터  (0) 2022.03.23
opencv 사진 합성  (0) 2021.06.18
opencv spread salt  (0) 2021.06.18

댓글