[OpenCV 11] 잡음 제거, 영상 프로파일

Sinaenjuni·2023년 7월 9일
0

OpenCV

목록 보기
11/25

잡음 제거

영상 데이터의 잡음은 픽셀 값에 원하지 않는 랜덤한 값이 추가되는 형태이다. 카메라에서 광학 신호를 전기적 신호로 변환하는 과정에서 센서에 잡음이 추가될 수 있다.


영상의 잡음은 크게 두 종류로 왼쪽 사진과 같이 흰색 혹은 검은색 점이 찍히는 잡음을 소금 그리고 후추 잡음이라고 한다. 오른쪽 영상과 같이 지글거리는 형태로 보이는 것이 가우시안 노이즈이다.

f(x,y)=s(x,y)+n(x,u)f(x,y)=s(x,y)+n(x,u)
/** @brief Fills the array with normally distributed random numbers.
The function cv::randn fills the matrix dst with normally distributed random numbers with the specified
mean vector and the standard deviation matrix. The generated random numbers are clipped to fit the
value range of the output array data type.
@param dst output array of random numbers; the array must be pre-allocated and have 1 to 4 channels.
@param mean mean value (expectation) of the generated random numbers.
@param stddev standard deviation of the generated random numbers; it can be either a vector (in
which case a diagonal standard deviation matrix is assumed) or a square matrix.
@sa RNG, randu
난수를 생성하는 함수로 반환 결과는 주어진 변수의 데이터 타입과 동일하게 적용된다.
*/
void randn(InputOutputArray dst, InputArray mean, InputArray stddev);
void ex_noise(){
    Mat src = imread("../data/lenna.bmp", IMREAD_GRAYSCALE), noise(src.size(), CV_32S), dst;
    randn(noise, 0, 10);

    add(src, noise, dst, noArray(), CV_8U);

    imshow("src", src);
    imshow("dst", dst);
    waitKey();
    destroyAllWindows();
}


프로파일(Profile)

영상에서 특정 경로(라인 또는 곡선) 상에 있는 픽셀의 밝기 값을 그래프 형태로 나타낸 것이다.

Mat src, dst, profile;
int row = 0;

void on_trackbar(int, void*)
{
	src.copyTo(dst);
	profile.setTo(255);

	uchar* pSrc = (uchar*)src.ptr<uchar>(row);
	uchar* pDst = (uchar*)dst.ptr<uchar>(row);

	for (int i = 1; i < src.cols; i++) {
		line(profile, Point(i - 1, 255 - pSrc[i - 1]), Point(i, 255 - pSrc[i]), 0);
		pDst[i] = saturate_cast<uchar>(pSrc[i] + 50);
	}

	imshow("dst", dst);
	imshow("profile", profile);
}


void ex_profile(){
	src = imread("../data/lenna.bmp", IMREAD_GRAYSCALE);

	if (src.empty()) {
		cerr << "Image load failed!" << endl;
		return ;
	}

//	GaussianBlur(src, src, Size(), 2);
	
	namedWindow("dst");
	namedWindow("profile");

	profile.create(256, src.cols, CV_8UC1);

	createTrackbar("Profile", "dst", &row, src.rows - 1, on_trackbar);
	on_trackbar(0, 0);

	waitKey();
}


양방향 필터(Bilateral filter)

엣지 보전 잡음 제거 필터의 한 종류이다. 평균 값 필터 또는 가우시안 필터는 엣지 영역을 평탄화하기 때문에 물체의 경계가 사라지는 문제가 있다. 기준 픽셀과 이웃 픽셀들 과의 거리, 그리고 픽셀 값의 차이를 함께 고려해서 블러링 정도를 조절한다.




필터 중앙의 픽셀을 기준으로 비슷한 수준의 픽셀에는 일반적인 가우시안 필터를 적용하고, 그렇지 않고 중앙 픽셀과 많은 차이를 보이는 픽셀에는 0으로 채워진 필터를 디자인해서 필터링에 사용한다.

src: Source 8-bit or floating-point, 1-channel or 3-channel image.
dst: Destination image of the same size and type as src .
d: 커널 사이즈와 마찬가지로 필터링에 사용될 거리(-1: sigma에 의해 자동을 결정)
sigmaColor: 색 공간에서 필터의 표준 편차
sigmaSpace: 좌표 공간에서 필터의 표준 편차 (거리에 따른 가우시안 필터를 적용한다. 만약 10을 입력하면 -30~30 범위 밖에 있는 픽셀에는 0에 가까운 값을 곱하게 된다.)
borderType: border mode used to extrapolate pixels outside of the image, see #BorderTypes

void bilateralFilter( InputArray src, OutputArray dst, int d,
					double sigmaColor, double sigmaSpace,
					int borderType = BORDER_DEFAULT );
void ex_bilateral(){
	Mat src = imread("../data/lenna.bmp", IMREAD_GRAYSCALE);

	if (src.empty()) {
		cerr << "Image load failed!" << endl;
		return ;
	}

	TickMeter tm;
	tm.start();

	Mat dst1;
	GaussianBlur(src, dst1, Size(), 5);

	tm.stop(); 
	cout << "Gaussian: " << tm.getTimeMilli() << endl;

	tm.reset();
	tm.start();

	Mat dst2;
	bilateralFilter(src, dst2, -1, 10, 5);

	tm.stop();
	cout << "Bilateral: " << tm.getTimeMilli() << endl;

	imshow("src", src);
	imshow("dst1", dst1);
	imshow("dst2", dst2);
	waitKey();
}



0개의 댓글