When will you grow up?

11.medianblur 만들기 본문

02. Study/Computer Vision(openframworks&opencv)

11.medianblur 만들기

미카이 2016. 10. 16. 16:07

medianblur란 ?

Noise filtering이라고도 칭하며, 중앙값 블러링을 나타낸다.


openCV에서도 medianBlur함수를 제공해줍니다.

medianBlur(inputArray,outputArray,ksize);//원본,medianblur될이미지,커널사이즈

로 사용될수 있습니다.


이번에는 openCV함수와 제가만든 median함수를 비교해보는 코딩을 해보겠습니다.





핵심 함수입니다.


이미지의 픽셀값을 얻어와 

stl vector형으로 값을 다 넣어주며 각 중앙 값을 되돌려주는 함수입니다.


Vec3b median(Mat_<Vec3b> &I)

{

Vec3b medVec3b;


for (int k = 0; k < 3; k++)

{

vector<int> q;

for (int r = 0; r < I.rows; r++)

{

for (int c = 0; c < I.cols; c++)

{

q.push_back(I(r, c)[k]);

}

}

std::sort(q.begin(), q.end());

int med = q[q.size() / 2];

medVec3b[k] = med;


}

return medVec3b;

}

----------------------------------------------------------------------------------------


//setup함수부분

//커널 사이즈를 x,y축으로 지정해주며

//각 구간별로 이미지를 짤라 medVec3b값을 추출하여

//복사된 이미지에 넣어줌으로써 medianblur를 마무리하게됨니다.

int KsizeX = 9;

int KsizeY = 9;

int Xr = KsizeX/2 ;

int Yr = KsizeY/2 ;


for (int r = Yr; r < src.rows - Yr; r++)

{

for (int c = Xr; c < src.cols - Xr; c++)

{

cv::Rect window(c - Xr, r - Yr, KsizeX ,KsizeY);

Mat_<Vec3b> subImage(src, window);

dst(r,c) = median(subImage);

}

}




아래는 

실행결과입니다.



                      원본이미지                 KsizeX =1   , KsizeX =9            


원본이미지                 KsizeX =9   , KsizeX =1    

원본이미지                           KsizeX =9   , KsizeX =9               opencv medianblur                                                                                                kernel size 9




아래는 전체소스코드입니다.




#include "ofApp.h"
using namespace cv;
using namespace std;

ofImage photo; // 불러올 이미지를 위한 ofImage를 형으로하는 photo 

cv::Mat_ src; //원본이미지
cv::Mat_ dst; //output이미지
cv::Mat_ opencvdst;//opencvblur를 이용한 output이미지
Vec3b median(Mat_ &I);//함수원형 선언
//--------------------------------------------------------------

//--------------------------------------------------------------



void ofApp::setup() {
	

	photo.load("1.JPG"); // 이미지를 읽어온다.
	src = cv::Mat(photo.getHeight(), photo.getWidth(), CV_8UC3, photo.getPixels().getData()); // 불러온 이미지의 데이터를 srcImg에 대입한다.

	dst = src.clone(); // srcImg 복제
	opencvdst = src.clone();
							
	cv::imshow("원본이미지", src); // srcImg를 출력한다.

	int KsizeX = 9;
	int KsizeY = 9;
	int Xr = KsizeX/2 ;
	int Yr = KsizeY/2 ;

	for (int r = Yr; r < src.rows - Yr; r++)
	{
		for (int c = Xr; c < src.cols - Xr; c++)
		{
			cv::Rect window(c - Xr, r - Yr, KsizeX ,KsizeY);
			Mat_ subImage(src, window);
			dst(r,c) = median(subImage);
		}
	}

	medianBlur(src, opencvdst, 9);

	cv::imshow("Mymedian", dst);
	cv::imshow("openCVmedian", opencvdst);
}


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

}

//--------------------------------------------------------------
void ofApp::draw() {
	
}
Vec3b median(Mat_ &I)
{
	Vec3b medVec3b;

	for (int k = 0; k < 3; k++)
	{
		vector q;
		for (int r = 0; r < I.rows; r++)
		{
			for (int c = 0; c < I.cols; c++)
			{
				q.push_back(I(r, c)[k]);
			}
		}
		std::sort(q.begin(), q.end());
		int med = q[q.size() / 2];
		medVec3b[k] = med;

	}
	return medVec3b;
}


Comments