When will you grow up?

10.bilateralFilter를 이용한 이미지 처리. 본문

02. Study/Computer Vision(openframworks&opencv)

10.bilateralFilter를 이용한 이미지 처리.

미카이 2016. 9. 29. 16:46

bilateralFilter 란 ? 양방향 필터 라고 정의한다.

스무딩 이미지 처리와 노이즈제거를 위한 가장 Advanced된 필터라고 정의되어 있다. 
쉽게말해 윤곽선을 보존되면서 노이즈를 제거하지만 시간이 오래걸린다.


opencv 에서 제공되는 bilateralFilter함수의원형은 아래와 같습니다. 

출처 : 클릭
자세한 정보 :  클릭 

void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, intborderType=BORDER_DEFAULT )


(원본이미지,아웃풋이미지,각 픽셀의 근처의 직경,시그마컬러값 , 좌표공간에서 시그마 필터링)


src - 소스 8 비트 또는 부동 소수점, 1 채널 또는 3 채널 이미지.

dst - SRC와 동일한 크기와 유형의 대상 이미지입니다.

d - 필터링 중에 사용되는 각 픽셀 근처의 직경. 이 비 양성이면, sigmaSpace로부터 계산된다.

sigmaColor는 - 색 공간에서 시그마를 필터링합니다. 상기 파라미터의 값이 클수록 화소 근방 (sigmaSpace 참조) 내에서 더 멀리 색 세미 동일한 색상의 큰 영역의 결과를 함께 혼합 될 것이라는 것을 의미한다.

sigmaSpace는 - 좌표 공간에서 시그마를 필터링합니다. 매개 변수의 값이 클수록 더 멀리 픽셀만큼 자신의 색 (sigmaColor 참조) 충분히 가까이 서로 영향을 미치는 것을 의미합니다. > 0 거라고 때없이 sigmaSpace의 근방 크기를 지정한다. 그렇지 않으면, d를 sigmaSpace에 비례한다.



사용한 함수는 아래와 같습니다.

bilateralFilter(inputImg, blur_3, 0, 75, 75);






위 사진은 결과 값 인데 

순서대로 원본,50,75,150 경우 입니다 sigmaColor와 sigmaSpace 값이.

75였을경우에 가장 Cartoon이미지와 흡사한 느낌을 받을 수 있었다.


아래는 사진은 각 픽셀값에 대한 히스토그램 분포도 분석입니다.

원본이미지 히스토그램

bilateralFilter를 적용시킨 히스토그램




전체 소스는 아래와 같습니다.


#include "ofApp.h"


#define SCALE 0.2


//--------------------------------------------------------------
void ofApp::setup() {

	Mat inputImg,blur_2, blur_3, blur_4, blur_5, blur_6;

	inputImg = imread("223.jpg", CV_LOAD_IMAGE_COLOR);
	//resize(inputImg, inputImg, Size(), SCALE, SCALE, CV_INTER_AREA);
	
	bilateralFilter(inputImg, blur_3, 0, 75, 75);
	
	MatND histogramB, histogramG, histogramR;
	const int channel_numbersB[] = { 0 };  // Blue
	const int channel_numbersG[] = { 1 };  // Green
	const int channel_numbersR[] = { 2 };  // Red
	float channel_range[] = { 0.0, 255.0 };
	const float* channel_ranges = channel_range;
	int number_bins = 255;

	// R, G, B별로 각각 히스토그램을 계산한다.
	calcHist(&blur_3, 1, channel_numbersB, Mat(), histogramB, 1, &number_bins, &channel_ranges);
	calcHist(&blur_3, 1, channel_numbersG, Mat(), histogramG, 1, &number_bins, &channel_ranges);
	calcHist(&blur_3, 1, channel_numbersR, Mat(), histogramR, 1, &number_bins, &channel_ranges);

	// Plot the histogram
	int hist_w = 512; int hist_h = 400;
	int bin_w = cvRound((double)hist_w / number_bins);

	Mat histImageB(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
	normalize(histogramB, histogramB, 0, histImageB.rows, NORM_MINMAX, -1, Mat());

	Mat histImageG(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
	normalize(histogramG, histogramG, 0, histImageG.rows, NORM_MINMAX, -1, Mat());

	Mat histImageR(hist_h, hist_w, CV_8UC3, Scalar(0, 0, 0));
	normalize(histogramR, histogramR, 0, histImageR.rows, NORM_MINMAX, -1, Mat());

	for (int i = 1; i < number_bins; i++)
	{

		line(histImageB, Point(bin_w*(i - 1), hist_h - cvRound(histogramB.at(i - 1))),
			Point(bin_w*(i), hist_h - cvRound(histogramB.at(i))),
			Scalar(255, 0, 0), 2, 8, 0);
		line(histImageG, Point(bin_w*(i - 1), hist_h - cvRound(histogramG.at(i - 1))),
			Point(bin_w*(i), hist_h - cvRound(histogramG.at(i))),
			Scalar(0, 255, 0), 2, 8, 0);

		line(histImageR, Point(bin_w*(i - 1), hist_h - cvRound(histogramR.at(i - 1))),
			Point(bin_w*(i), hist_h - cvRound(histogramR.at(i))),
			Scalar(0, 0, 255), 2, 8, 0);

	}


	namedWindow("Original", CV_WINDOW_AUTOSIZE);
	namedWindow("HistogramB", CV_WINDOW_AUTOSIZE);
	namedWindow("HistogramG", CV_WINDOW_AUTOSIZE);
	namedWindow("HistogramR", CV_WINDOW_AUTOSIZE);

	moveWindow("Original", 100, 100);
	moveWindow("HistogramB", 110, 110);
	moveWindow("HistogramG", 120, 120);
	moveWindow("HistogramR", 130, 130);

	imshow("Original", inputImg);
	imshow("HistogramB", histImageB);
	imshow("HistogramG", histImageG);
	imshow("HistogramR", histImageR);
}

//--------------------------------------------------------------
void ofApp::update() {

}

//--------------------------------------------------------------
void ofApp::draw() {
	
}




//--------------------------------------------------------------
void ofApp::keyPressed(int key) {

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key) {

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y) {

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button) {

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button) {

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button) {

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y) {

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y) {

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h) {

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg) {

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo) {

}





Comments