평균값 필터 직접구현(블러링)
#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 << "Img load failed!" << endl;
return -1;
}
/*
float data[] = // 입력 데이터에 따라 필터 종류도 달라지는 거 같다. 엠보싱과 한번 비교해보자.
{
1 / 9.f ,1 / 9.f ,1 / 9.f,
1 / 9.f ,1 / 9.f ,1 / 9.f,
1 / 9.f ,1 / 9.f ,1 / 9.f,
}; // 이와 같이 원소가 모두 동일 시 Mat::ones 사용해 굳이 data[] 만들 필요없다.
Mat kernel(3, 3, CV_32FC1, data);
cout << kernel << endl;
*/
Mat kernel = Mat::ones(3, 3, CV_32FC1)/ 9.f;
cout << kernel << endl;
Mat dst;
filter2D(src, dst, -1, kernel);
imshow("src", src);
imshow("dst", dst);
waitKey();
}
평균값필터는 blur라는 함수를 제공해 간편히 평균값필터를 사용할 수 있다
cv::filter2D (InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT)
**when ddepth = -1, the output image will have the same depth as the source. 결과 영상 깊이가 src 깊이와 동일.
**Poin(-1,-1):고정점 좌표. Point(-1, -1)을 지정하면 커널 중심을 고정점으로 사용
#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 << "Img load failed!" << endl;
return -1;
}
Mat kernel = Mat::ones(3, 3, CV_32FC1)/ 9.f;
cout << kernel << endl;
Mat dst;
imshow("src", src);
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();
}
}
산술평균 사용시 원하는 부분(현재 위치의 픽셀값)이 아닌 전체 부분에 동일한 가중치로 필터를 적용하게 된다.
결과 영상에서 같은 위치에 있는 입력영상의 픽셀값 비중은 1/n 이며 나머지 픽셀들의 비중이 (n-1)/n 이 되어 원본 영상의
같은 위치 픽셀값보다 주변에 위치한 픽셀값들에의해 영향을 많이 받게 된다.
이에, 현위치와 가까이 있는 픽셀들에게 가중치를 크게 주고 멀리 떨어진 픽셀들에겐 가중치를 적게 주는 형태로 필터링해
야한다.
해결법: 가우시안 블러링.
#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;
}
Mat dst;
GaussianBlur(src, dst, Size(), 2.0); // sigma값 1.0 입력 시 내부적으로 7x7 필터사이즈 크기로 블러링 됨
Mat dst2;
blur(src, dst2, Size(7, 7)); //그러나 위보단, 직접 7,7 로 입력하여 블러링한게 좀 더 블러링이 된다. 필터사이즈가 커짐에따라 결과영상 품질은 좋지 않다.
//7x7 평균값필터 적용 시 GaussianBlur의 sigma값을 증가시켜서 좀 더 자연스러운 블러링을 할 수 있다. 간단한 블러링의 경우 평균값 필터 사용할 수 있다.
imshow("src", src);
imshow("dst", dst);
imshow("dst2", dst2);
waitKey();
}
시그마 사이즈가 커지면 내부에서 연산량이 증가하여 시간 또한 증가하게 될 것이다.
'프로그래머스 > OPENCV' 카테고리의 다른 글
1주차 과제) 히스토그램 개선해서 명암비가 좋은 결과 이미지 만들기 (0) | 2022.12.03 |
---|---|
잡음제거 필터 (GaussianBlur vs BilateralFilter) (0) | 2022.12.02 |
영상의 필터링 - 엠보싱필터링 (0) | 2022.12.02 |
opencv 동영상 (1) (0) | 2022.12.02 |
영상의 산술 및 논리연산 (0) | 2022.12.02 |