어제보다 나은 내가 되자
필터링 본문
엠보싱 필터링
엠보싱이란 입체감을 주는, 올록볼록한 형태로 만든 객체의 윤곽을 뜻한다.
#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 0;
}
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();
return 0;
}
평균값 필터링
평균값 필터링은 입력 영상에서 특정 픽셀과 주변 픽셀들의 산술 평균을 결과 영상 픽셀 값으로 설정하는 필터이다.
픽셀 값의 급격한 변화가 줄어들기 때문에 날카로운 에지가 무뎌지고 잡음이 사라지는 효과가 있다.
평균값 필터를 너무 과도하게 사용하면 사물의 경계가 흐릿해진다.
마스크의 크기가 커질수록 더욱 부드러운 영상을 생성하지만, 연산량이 크게 증가한다.
#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 0;
}
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();
}
return 0;
}
행렬 원소의 합이 1보다 작으면 입력 영상보다 어두워지고 합이 1보다 크면 입력 영상보다 밝아진다.
따라서 평균 밝기를 그대로 유지하기 위해서는 행렬 원소의 합을 1로 해야한다.
행렬 원소의 합을 0으로 한다면 검은색으로 구성된 결과 영상이 생성된다. 주로 에지 검출 필터 마스크에서 사용하며 에지 성분이 강한 부분에서만 0이 아닌 값이 생성된다.
가우시안 필터링
평균값 필터보다 더 자연스러운 블러링 결과를 생성한다.
가우시안 분포란, 평균을 중심으로 좌우 대칭의 종 모양을 갖는 확률 분포를 말하며 정규 분포라고도 한다.
평균 근방에서 분포가 가장 많이 발생하고, 평균에서 멀어질수록 발생 빈도가 종 모양으로 감소하는 형태이다.
자연에서 발생하는 일은 대부분 가우시안 분포를 따른다.
또한 가우시안 분포는 평균과 표준 편차에 의해 모양이 결정된다.
표준 편차가 작으면 가우시안 분포 함수 그래프가 좁은 형태가 되고 표준 편차가 크면 넓은 형태이다.
이는 가우시안 필터에서도 적용되는데 가우시안 필터의 정 중앙이 가장 큰 값을 갖고 주변으로 갈 수록 값이 작아진다.
가중 평균을 구하는 것과 같다고 할 수 있다.
GaussianBlur() 함수를 사용하면 x축 방향, y축 방향에 따라 1차원 가우시안 필터 마스크를 각각 생성하여 필터링을 수행한다. 1차원 가우시안 필터 마스크를 생성하기 위해 OpenCV는 getGaussianKernel() 함수를 사용하여 사용자가 지정한 표준 편차를 따르는 1차원 가우시안 필터 마스크 행렬을 생성하여 반환한다.
샤프닝
사물의 윤곽을 뚜렷하고 선명하게 하는 영상을 샤프닝이라고 한다. 윤곽을 뚜렷하게 하기 위해서는 에지 주변에서 픽셀 값의 명암비가 커지도록 수정해야 한다.
샤프닝을 구현하기 위해서는 블러링된 영상을 사용한다. 원래 영상에서 블러링을 수행하고 원래 영상과 블러링된 영상의 차이를 구하면 날카로운 성분을 가진 함수를 구할 수 있고 이렇게 구한 성분을 원래 영상에 더해주면 날카로운 성분이 강조된다.
#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 0;
}
imshow("src", src);
for (int sigma = 1; sigma <= 5; sigma++) {
Mat blurred;
GaussianBlur(src, blurred, Size(), sigma);
double alpha = 1.0;
Mat dst = (1 + alpha) * src - alpha * blurred;
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();
}
return 0;
}
'영상처리' 카테고리의 다른 글
잡음(noise) (0) | 2020.05.19 |
---|---|
히스토그램 평활화 (0) | 2020.05.14 |
히스토그램 스트레칭 (0) | 2020.05.14 |
히스토그램 그리기 (0) | 2020.05.14 |
모든 픽셀을 방문하여 밝기 변화하기 (0) | 2020.05.13 |