Separable Convolution

선비Sunbei·2023년 3월 4일
0
post-thumbnail

2D Convolution to 1D Convolution

모든 2D filter를 1D 2개로 분리할 수 있는 것은 아니다. 2D kernel을 1D kernel두 개의 outer product로 표현할 수 있을 때만 가능하다.

outer product는 한국말로 외적인데 여기서 말하는 외적은 cross product를 얘기하는 것이 아니다.
outer product는 두 벡터를 행렬곱을 이용해서 행렬을 만드는 것이다.
ex> 열벡터 x 행벡터

행벡터 x 열벡터는 스칼라 값을 나타내는 inner product인 반면, outer product는 행렬을 만들어 낸다.

사용 이유 : 주변 값들을 불러오는 과정에서 연산량이 너무 많아지기 때문이다.

void Image::BoxBlur3()
{
	std::vector<Vec4> pixelsBuffer(this->pixels.size()); 

	for (int j = 0; j < this->height; j++)
		for (int i = 0; i < this->width; i++)
		{
			pixelsBuffer[i + j * width].v[0] = (GetPixel(i, j).v[0] + GetPixel(i + 1, j).v[0] + GetPixel(i - 1, j).v[0]) / 3;
			pixelsBuffer[i + j * width].v[1] = (GetPixel(i, j).v[1] + GetPixel(i + 1, j).v[1] + GetPixel(i - 1, j).v[1]) / 3;
			pixelsBuffer[i + j * width].v[2] = (GetPixel(i, j).v[2] + GetPixel(i + 1, j).v[2] + GetPixel(i - 1, j).v[2]) / 3;
		}

	std::swap(pixels, pixelsBuffer);

	for (int j = 0; j < this->height; j++)
		for (int i = 0; i < this->width; i++)
		{
			pixelsBuffer[i + j * width].v[0] = (GetPixel(i, j).v[0] + GetPixel(i, j + 1).v[0] + GetPixel(i, j - 1).v[0]) / 3;
			pixelsBuffer[i + j * width].v[1] = (GetPixel(i, j).v[1] + GetPixel(i, j + 1).v[1] + GetPixel(i, j - 1).v[1]) / 3;
			pixelsBuffer[i + j * width].v[2] = (GetPixel(i, j).v[2] + GetPixel(i, j + 1).v[2] + GetPixel(i, j - 1).v[2]) / 3;
		}

	std::swap(pixels, pixelsBuffer);
}

0개의 댓글