Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

:)

영상처리_필터링 본문

컴퓨터비전

영상처리_필터링

mihee 2022. 3. 21. 18:13

평균값 필터(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;
}

noise(10% salt and pepper), dst1(median filter), dst2(improved median filter)

 

 

'컴퓨터비전' 카테고리의 다른 글

크기변환과 보간법  (0) 2022.03.22
이동 변환과 전단 변환  (0) 2022.03.22
OpenCV 함수  (0) 2022.03.20
이벤트 처리하기  (0) 2022.03.19
OpenCV 그리기 함수  (0) 2022.03.18
Comments