관심쟁이 영호

[#18] OpenCV (With. cpp) ㅣ 캐니 에지, 최대/최소/평균/미디언/가우시안 필터링 본문

학교공부/OpenCV

[#18] OpenCV (With. cpp) ㅣ 캐니 에지, 최대/최소/평균/미디언/가우시안 필터링

관심쟁이 영호 2020. 11. 25. 01:30
반응형

안녕하세요!

관심쟁이 영호입니다.

 

오늘 공부해볼 과목은

OpenCV입니다!

 


오늘은 캐니 에지검출, 최대/최소/평균/미디언/가우시안 필터링에 대해서 공부해볼게요!

캐니 에지란?

이전에 봤던 에지 검출방법은 대부분 잡음을 에지로 인식하고 검출하는 경우가 많아요!

그래서 캐니 에지라는 것이 나왔는데요.

캐니 에지는 잡음을 없애면서 에지를 검출하는 방법입니다.

순서를 봅시다!

 

1. 블러링을 통한 노이즈 제거

2. 화소 기울기의 강도와 방향 검출

3. 비최대치 억제

4. 이력 임계값으로 에지 결정

 

이해가 잘 안되시죠?

저두 마찬가지에요..ㅋㅋㅋ

이해도 안되고 이해하기도 싫네요..

어쨋든 이러한 에지를 검출을 하기 위해서는

저 순서대로 하면 된다는 말씀!

 

예시코드가 너무 길어서.. 이번만 패스할게요.. ㅎㅎ

 

최댓/최소/평균 필터링?

 

최대필터링은 영상에서 마스크 계수중 최댓값을 통과시켜 출력화소를 크게! 전반적으로 밝아짐.

최소필터링은 영상에서 마스크 계수중 최솟값을 통과시켜 출력화소를 작게! 전반적으로 어두워짐.

평균필터링은 영상에서 마스크 계수중 평균값을 통과시켜 출력화소를 평균적으로! 전반적으로 블러링효과!

 

해당 필터링들은 어디에 쓰이냐면요! 밝은, 어두운 잡음을 경우에 따라서 특징을 확대하기위한 기법입니다.

 

그럼 세개 모두 코드로 살펴볼게요!

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;
void minMaxFilter(Mat img, Mat& dst, int size, int flag = 1) {
	dst = Mat(img.size(), CV_8U, Scalar(0));
	Size msize(size, size);
	Point h_m = msize / 2;

	for (int i = h_m.y; i < img.rows - h_m.y; i++)
	{
		for (int j = h_m.x; j < img.cols - h_m.x; j++)
		{
			Point start = Point(j, i) - h_m;
			Rect roi(start, msize);
			Mat mask = img(roi);

			double minVal, maxVal;
			minMaxLoc(mask, &minVal, &maxVal);
			dst.at<uchar>(i, j) = (flag) ? maxVal : minVal;
		}



	}
}

void averageFilter(Mat img, Mat& dst, int size) {
	dst = Mat(img.size(), CV_8U, Scalar(0));

	for (int i = 0; i < img.rows; i++)
	{
		for (int j = 0; j < img.cols; j++)
		{
			Point pt1 = Point(j - size / 2, i - size / 2);
			Point pt2 = pt1 + (Point)Size(size, size);

			if (pt1.x < 0) pt1.x = 0;
			if (pt1.y < 0) pt1.y = 0;
			if (pt2.x > img.cols) pt2.x = img.cols;
			if (pt2.y > img.rows) pt2.y = img.rows;

			Rect mask_rect(pt1, pt2);
			Mat mask = img(mask_rect);
			dst.at<uchar>(i, j) = (uchar)mean(mask)[0];
		}

	}
}
int main()
{
	Mat image = imread("../image/sample.jpg", IMREAD_GRAYSCALE);
	
	CV_Assert(image.data);

	Mat min_img, max_img;
	minMaxFilter(image, min_img, 5, 0);
	minMaxFilter(image, max_img, 5, 1);

	Mat avg_img, blur_img, box_img;
	averageFilter(image, avg_img, 5);
	blur(image, blur_img, Size(5, 5));
	boxFilter(image, box_img, -1, Size(5, 5));

	imshow("avg_Filter_img", avg_img);
	imshow("image", image);

	imshow("minFilter_img", min_img);
	imshow("maxFilter_img", max_img);
	

	

	

	

	
	waitKey(0);

		return 0;
}

 

코드를 보면!

한개의 화소가 있으면 그 화소를 둘러싸고 있는 주변의 8개와 비교를 합니다! 그 중에서 최대, 최소, 그값들의 평균을 출력화소로 정하는 거에요!!

 

결과에요!!

 

최댓값은 전반적으로 밝아지고, 최솟값은 전반적으로 어두워지고, 평균값은 전반적으로 블러링 효과!

 

미디언, 가우시안 필터링

 

미디언 필터링= 이전에 보았던 최대-최소-평균값과 비슷하게 주어진 행렬에서 중간값을 출력화소로 정하는 것입니다!

가우시안 필터링 = 스무딩 처리에서 가장 대표적으로 사용되는 기법이에요!

 

그럼 가우시안 필터링을 코드로 살펴볼게요!

 

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat image = imread("../image/sample.jpg", IMREAD_GRAYSCALE);
	
	CV_Assert(image.data);
	
	Size size(5, 21);
	double sigmaX = 0.3 * ((size.width - 1) * 0.5 - 1) + 0.8;
	double sigmaY = 0.3 * ((size.height - 1) * 0.5 - 1) + 0.8;

	Mat gauss_img1, gauss_img2, gauss_img3;

	GaussianBlur(image, gauss_img2, size, sigmaX, sigmaY);	 //openCV에서 제공하는 함수로 가우시안 스무딩!
	

	imshow("image", image);

	imshow("minFilter_img", gauss_img2);
	

	waitKey(0);

		return 0;
}

sigmaX, sigmaY는 가우시안 세부공식을 미리 계산한 것입니다!

 

오늘은 여기까지 공부를 해보겠습니다!

 

300x250
Comments