
1. 영상의 필터링
영상의 필터링
주파수 공간에서의 필터링

공간적 필터링


최외곽 픽셀 처리
최외곽 바깥에 가상의 픽셀이 있다고 가정

OpenCV 필터링에서 지원하는 가장자리 픽셀 확장 방법


기본적인 2D 필터링 함수

엠보싱 필터

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(void)
{
Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
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);
imshow("src", src);
imshow("dst", dst);
waitKey();
}

2. 블러링
평균 값 필터
각각의 좌표에서 주변 픽셀 값들의 산술 평균을 계산하고 이를 출력 영상의 픽셀 값으로 설정
영상에 평균 값 필터를 적용하면 인접한 픽셀 간의 급격한 그레이스케일 값 변화가 줄어들어 날카로운 에지가 무뎌지고 영상에 있는 잡음이 감소하는 효과

마스크 크기가 커질수록 평균 값 필터 결과가 더욱 부드러워짐 -> 더 많은 연산량이 필요

평균 값 필터를 이용한 블러링 함수

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
imshow("src", src);
Mat dst;
for (int ksize = 3; ksize <= 7; ksize += 2) {
blur(src, dst, Size(ksize, ksize));
String desc = format("Mean: %dx%d", ksize, ksize);
putText(dst, desc, Point(10, 30), FONT_HERSHEY_SIMPLEX, 1.0,
Scalar(255), 1, LINE_AA);
imshow("dst", dst);
waitKey();
}
}



정규 분포와 가우시안 함수



가우시안 필터링

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(void)
{
Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
imshow("src", src);
Mat dst;
for (int sigma = 1; sigma <= 5; sigma++) {
TickMeter tm;
tm.start();
GaussianBlur(src, dst, Size(0, 0), (double)sigma);
tm.stop();
cout << "sigma: " << sigma << ", time: " << tm.getTimeMilli() << " ms." << endl;
String desc = format("Sigma = %d", sigma);
putText(dst, desc, Point(10, 30), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255), 1, LINE_AA);
imshow("dst", dst);
waitKey();
}
}
실행 결과



sigma 값이 커질수록 연산 시간이 늘어남
3. 샤프닝
언샤프 마스크 필터링

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
void sharpen_mean();
void sharpen_gaussian();
int main(void)
{
sharpen_mean();
sharpen_gaussian();
}
void sharpen_mean()
{
Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return;
}
float sharpen[] = {
-1 / 9.f, -1 / 9.f, -1 / 9.f,
-1 / 9.f, 17 / 9.f, -1 / 9.f,
-1 / 9.f, -1 / 9.f, -1 / 9.f
};
Mat kernel(3, 3, CV_32F, sharpen);
Mat dst;
filter2D(src, dst, -1, kernel);
imshow("src", src);
imshow("dst", dst);
waitKey();
destroyAllWindows();
}
void sharpen_gaussian()
{
Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return;
}
imshow("src", src);
Mat srcf;
src.convertTo(srcf, CV_32FC1);
for (int sigma = 1; sigma <= 5; sigma++) {
Mat blr;
GaussianBlur(srcf, blr, Size(), sigma);
float alpha = 1.0f;
Mat dst = (1.f + alpha) * srcf - alpha * blr;
dst.convertTo(dst, CV_8UC1);
String desc = format("sigma: %d", sigma);
putText(dst, desc, Point(10, 30), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255), 1, LINE_AA);
imshow("dst", dst);
waitKey();
}
destroyAllWindows();
}
실행 영상

sigma 값이 클수록 샤프닝이 과하게 출력된다.
4. 영상의 잡음


양방향 필터
에지 보전 잡음 제거 필터의 하나
평균 값 필터 또는 가우시안 필터는 에지 부근에서도 픽셀 값을 평탄하게 만드는 단점이 있음
기준 픽셀과 이웃 픽셀과의 거리 그리고 픽셀 값의 차이를 함께 고려하여 블러링 정도를 조절

에지가 아닌 부분에서만 블러링

OpenCV 양방향 필터링 함수

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(void)
{
Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
TickMeter tm;
tm.start();
Mat dst1;
GaussianBlur(src, dst1, Size(), 5);
tm.stop();
cout << "Gaussian: " << tm.getTimeMilli() << endl;
tm.reset();
tm.start();
Mat dst2;
bilateralFilter(src, dst2, -1, 10, 5);
tm.stop();
cout << "Bilateral: " << tm.getTimeMilli() << endl;
imshow("src", src);
imshow("dst1", dst1);
imshow("dst2", dst2);
waitKey();
}
