6. 필터링

OpenJR·2022년 4월 11일
0
post-custom-banner

영상의 필터링

2D 필터링

void filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel,
	Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT);

src: 입력 영상

dst: 출력 영상

ddepth: 원하는 결과 영상의 깊이를 지정. -1이면 src와 같은 깊이를 사용.

  • Input depth (src.depth()) -> Output depth (ddepth)
  • CV_8U -> -1/CV_16S/CV_32F/CV_64F
  • CV_16U/CV_16S -> -1/CV_32F/CV_64F
  • CV_32F -> -1/CV_32F/CV_64F
  • CV_64F -> -1/CV_64F

kernel: 필터 마스크 행렬. 1채널 실수형.

anchor: 고정점 위치. (-1, -1)이면 필터 중앙을 고정점으로 사용.

delta: (optional) 추가적으로 더할 값

borderType: 가장자리 픽셀 처리 방법

엠보싱 필터

kernel=[110101011]kernel = \begin{bmatrix}-1&-1&0\\-1&0&1\\0&1&1\end{bmatrix}
Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);

float data[] = { -1, -1, 0, -1, 0, 1, 0, 1, 1 };
Mat emboss(3, 3, CV_32FC1, data);
Mat dst;
filter2D(src, dst, -1, emboss, Point(-1, -1), 128);

블러링: 영상 부드럽게 하기

평균값 필터

void blur(InputArray src, OutputArray dst, Size ksize,
	Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT);

Mat dst;
int ksize = 3;
blur(src, dst, Size(ksize, ksize));

src: 입력 영상

dst: 출력 영상

ksize: 평균값 필터 크기

anchor: 고정점

borderType: 가장자리 픽셀 확장 방식

가우시안 필터링

void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX,
                  double sigmaY = 0, int borderType = BORDER_DEFAULT);

Mat dst;
double sigma = 1;
GaussianBlur(src, dst, Size(), sigma);

src: 입력 영상. 각 채널 별로 처리됨. (CV_8U, CV_16U, CV_16S, CV_32F or CV-64F)

dst: 출력 영상. src와 같은 크기, 같은 타입.

ksize: 가우시안 커널 크기. Size()를 지정하면 sigma 값에 의해 자동 결정됨.

sigmaX: x방향 sigma

sigmaY: y방향 sigma. 0이면 sigmaX와 같게 설정.

borderType: 가장자리 픽셀 처리 방식

샤프닝: 영상 날카롭게 하기

h(x,y)=f(x,y)+(f(x,y)fˉ(x,y))=2f(x,y)fˉ(x,y)\begin{aligned}h(x,y) = &f(x, y) + (f(x,y) - \bar{f}(x,y))\\ =&2f(x, y) - \bar{f}(x,y)\end{aligned}

평균값 필터 사용

Mat src = imread("camera.bmp", IMREAD_GRAYSCALE);
Mat blr;
blur(src, blr, Size(3, 3));
Mat dst = 2 * src - blr;

가우시안 필터 사용

Mat src = imread ("camera.bmp", IMREAD_GRAYSCALE);
Mat blr;
GaussianBlur(src, blr, Size(), 1.0);
Mat dst = 2 * src -blr;

샤프니스 조절을 위한 가중치:α\alpha

h(x,y)=f(x,y)+αg(x,y)h(x, y)= f(x, y)+\alpha g(x,y)
h(x,y)=f(x,y)+α(f(x,y)ƒˉ(x,y))=(1+α)f(x,y)αƒˉ(x,y)\begin{aligned}h(x, y) = &f(x, y)+\alpha(f(x, y)- \bar{ƒ}(x, y))\\ =&-(1+ \alpha)f(x, y) - \alpha\bar{ƒ}(x, y)\end{aligned}
h(x,y)=(1+α)f(x,y)αGσ(f(x,y))h(x,y) = (1+\alpha)f(x, y)- \alpha G_\sigma(f(x,y))

잡음 제거 필터링

프로파일

void on_trackbar(int, void*)
{
	src.copyTo(dst);
	profile.setTo(255);

	uchar* pSrc = (uchar*)src.ptr<uchar>(row);
	uchar* pDst = (uchar*)dst.ptr<uchar>(row);

	for (int i = 1; i < src.cols; i++) {
		line(profile, Point(i - 1, 255 - pSrc[i - 1]), Point(i, 255 - pSrc[i]), 0);
		pDst[i] = saturate_cast<uchar>(pSrc[i] + 50);
	}

	imshow("dst", dst);
	imshow("profile", profile);
}

createTrackbar("Profile", "dst", &row, src.rows - 1, on_trackbar);

가우시안 노이즈 추가하기

void randn(InputoutputArray dst, InputArray mean, InputArray stddev);

Mat src = imread ("lenna.bmp", IMREAD_GRAYSCALE);
Mat noise(src.size(), CV_32S);
randn(noise, 0, 10);
Mat dst;
add(src, noise, dst, noArray(), CV_8U);

dst: 정상 분포 난수 행렬. dst은 미리 생성되어 있어야 하며, 1~4 채널을 가질 수 있음.

mean: 평균

stddev: 표준편차

참고사항:

  • 생성된 난수는 dst의 타입에 맞게 자동 변환됨

  • 만약 dst가 uchar 자료형을 사용하면 0보다 작은 난수는 모두 0으로 설정됨

양방향 필터

BF(I)p=1WpqSGσs(pq)Gσr(IpIq)IqBF(I)_{p} = \frac{1}{W_p}\sum_{q\in S}G_{\sigma_s}(||\bold{p}-\bold{q}||)G_{\sigma_r}(|I_p-I_q|)I_q

p,q,\bold{p}, \bold{q},: p점과 q점의 픽셀 좌표

Ip,IqI_p, I_q: p점과 q점의 픽셀 값

WpW_p: 커널 합이 1이 되도록 만드는 정규화 상수

void bilateralFilter(InputArray src, OutputArray dst, int d,
                     double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT);

Mat dst;
bilateralFilter(src, dst, -1, 10, 5);

src: 입력 영상. 8비트 또는 실수형, 1채널 또는 3채널.

dst: 출력 영상. src와 같은 크기, 같은 타입.

d: 필터링에 사용될 이웃 픽셀의 거리(지름). 음수(-1)를 입력할 경우 sigmaSpace 값에 의해 자동 결정됨.

sigmaColor: 색 공간에서 필터의 표준 편차 (픽셀 값의 차이)

sigmaSpace: 좌표 공간에서 필터의 표준 편차 (sigma)

borderType: 가장자리 픽셀 처리 방식

profile
Jacob
post-custom-banner

0개의 댓글