:)
영상처리_필터링 본문
평균값 필터(Mean filter)
- 영상의 특정 좌표 값을 주변 픽셀 값들의 산술 평균으로 설정
- 그레이스케일 값 변화가 줄어들어 날카로운 에지가 무뎌지고, 영상의 잡음이 사라짐.
void blur(InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT);
blur(src, dst, Size(5,5));
- ksize : 평균값 필터 크기
- anchor : 고정점
- borderType : 가장자리 픽셀 확장 방식
- 튀는 값이 있다면 튀는 값에 의해 영향을 많이받게된다.
- 가까이있는것은 웨이트를 많이주고 멀리있는건 적게주자(가우시안weight)
GaussianBlur(src, dst, Size(), 1) // 블러처리를 많이하고싶으면 1의 값을 수정.
언샤프 마스크(Unsharp mask) 필터링
- 날카롭지 않은 영상, 즉 부드러운 영상을 이용하여 날카로운 영상을 생성
// 평균값 필터 사용
Mat blr;
blur(src, blr, size(3,3));
Mat dst = 2 * src - blr;
// 가우시안 블러 사용
Mat src;
GaussianBlur(src, blr, Size(), 1.0);
Mat dst = 2 * src - blr;
미디언(median) 필터
- 주변 픽셀들의 값들을 정렬하여 그 중앙값으로 픽셀 값을 대체
- median 필터는 영상이 뭉게지는게 보임
- 개선된 미디언 필터 : 전체 모든 픽셀에 대해 median 필터X -> 현재 픽셀값이 0 or 255 일때만 적용
#include "opencv2/opencv.hpp"
#include <algorithm>
#include <iostream>
using namespace cv;
using namespace std;
Mat addNoise(const Mat& src, int percent)
{
srand(1);
int amount = src.rows * src.cols * percent / 100;
Mat noise = src.clone();
for (int i = 0; i < amount; i++) {
int x = rand() % src.cols;
int y = rand() % src.rows;
noise.at<uchar>(y, x) = (i % 2) * 255;
}
return noise;
}
void myMedian(const Mat& src, Mat& dst)
{
CV_Assert(!src.empty());
CV_Assert(src.type() == CV_8UC1);
// TODO: src 영상을 dst로 깊은 복사를 수행하세요.
src.copyTo(dst);
uchar p[9];
for (int y = 1; y < src.rows - 1; y++) {
for (int x = 1; x < src.cols - 1; x++) {
// TODO: src 영상의 픽셀 값이 0 또는 255인 경우에만 적용
if ( src.at<uchar>(y,x) == 0 || src.at<uchar>(y,x) == 255 ) {
p[0] = src.at<uchar>(y - 1, x - 1);
p[1] = src.at<uchar>(y - 1, x);
p[2] = src.at<uchar>(y - 1, x + 1);
p[3] = src.at<uchar>(y, x - 1);
p[4] = src.at<uchar>(y, x);
p[5] = src.at<uchar>(y, x + 1);
p[6] = src.at<uchar>(y + 1, x - 1);
p[7] = src.at<uchar>(y + 1, x);
p[8] = src.at<uchar>(y + 1, x + 1);
sort(p, p + 9);
// TODO: 정렬된 src 픽셀 값 중에서 중앙값을 dst 픽셀 값으로 설정
dst.at<uchar>(y, x) = p[4];
}
}
}
}
int main(void)
{
Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);
if (src.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
Mat noise = addNoise(src, 10); // 10% noise
Mat dst1, dst2;
medianBlur(noise, dst1, 3);
myMedian(noise, dst2);
imshow("src", src);
imshow("noise", noise);
imshow("dst1", dst1);
imshow("dst2", dst2);
waitKey();
return 0;
}
'컴퓨터비전' 카테고리의 다른 글
크기변환과 보간법 (0) | 2022.03.22 |
---|---|
이동 변환과 전단 변환 (0) | 2022.03.22 |
OpenCV 함수 (0) | 2022.03.20 |
이벤트 처리하기 (0) | 2022.03.19 |
OpenCV 그리기 함수 (0) | 2022.03.18 |
Comments