Mopological operation
모폴로지 연산은 Structuring element를 이용하여 반복적으로 영역을 확장시켜 떨어진 부분 또는 구멍을 채우거나, 잡음을 축소하여 제거하는 등의 연산으로 침식(erode), 팽창(dilate), 열기(opening), 닫기(closing) 등이 있다.
출처 : C++ API OpenCV 프로그래밍(책)
Erode (침식)
void cv::erode (
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
src : 입력영상
dst : 출력영상
kernel : morphology 로 사용할 kernel (MORPH_RECT, MORPH_CROSS, MORPH_ELLIPSE)
_anchor : Kernel element의 위치설정 (-1,-1일 경우 Kernel의 중심)
iterations : Erode 를 반복수행할 횟수
소스
Size size(5,5);
int iterations = 3;
Point anchor(-1,-1);
Mat rectKernel = getStructuringElement(MORPH_RECT, size);
erode(srcImage,erodeImage,rectKernel,anchor,iterations);
실행결과
설명
<<작성중 >>
Dilate(팽창)
void cv::dilate (
InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
<erode와 동일>
MorphologyEx
void cv::morphologyEx (
InputArray src,
OutputArray dst,
int op,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue()
)
src : 입력영상
dst : 출력영상
op : Morphology operation 의 type (MORPH_ERODE, MORPH_DILATE, MORPH_OPEN, MORPH_CLOSE, MORPH_GRADIENT, MORPH_TOPHAT, MORPH_BLACKHAT, MORPH_HITMISS)
kernel : Morphology 연산에 사용할 Kernel
anchor : Kernel element의 위치설정 (-1,-1일 경우 Kernel의 중심)
iteration : Number of times erosion and dilation are applied.
소스
Size size(5,5);
Mat rectKernel = getStructuringElement(MORPH_RECT, size);
int iterations = 5;
Point anchor(-1,-1);
morphologyEx(srcImage,openImage,MORPH_OPEN,rectKernel,anchor,iterations);
실행결과
설명
erode 와 dilate와 다르게 morphologyEx 는 op값(morphology operation type)에 따라 erode 와 dilate를 조합해서 사용하게 된다.
예를들면 MORPH_OPEN은 수축(erode) 수행 후 결과를 가지고 팽창(dilate)를 수행하게 된다.
각 morphology operation에 따른 조합은 아래의 자료를 참고해주세요
사용한 전체 소스 (Morphology 부분)
JNIEXPORT jstring JNICALL
Java_com_tistory_technote_opencvandroid_MainActivity_convertNativeLibtoMorpology(JNIEnv *env, jobject, jlong addrInput, jlong addrResult) {
Mat &img_input = *(Mat *) addrInput;
Mat &img_result = *(Mat *) addrResult;
cvtColor(img_input, img_result, CV_RGBA2GRAY);
jstring result;
std::stringstream buffer;
Mat srcImage = img_result;
Size size(5,5);
Mat rectKernel = getStructuringElement(MORPH_RECT, size);
buffer << "rectkernel =Mat rectKernel = getStructuringElement(MORPH_RECT, size); " << endl;
buffer << rectKernel << endl;
int iterations = 3;
Point anchor(-1,-1);
Mat erodeImage;
erode(srcImage,erodeImage,rectKernel,anchor,iterations);
img_result = erodeImage.clone();
Mat dilateImage;
dilate(srcImage,dilateImage,rectKernel,anchor,iterations);
//img_result = dilateImage.clone();
Mat ellipseKernel = getStructuringElement(MORPH_ELLIPSE,size);
buffer << "ellipseKernel = Mat ellipseKernel = getStructuringElement(MORPH_ELLIPSE,size);" << endl;
buffer << ellipseKernel << endl;
Mat erodeImage2;
erode(srcImage,erodeImage2,ellipseKernel,anchor,iterations);
//img_result = erodeImage2.clone();
Mat dilateImage2;
dilate(srcImage,dilateImage2,ellipseKernel,anchor,iterations);
//img_result = dilateImage2.clone();
Mat corssKernel = getStructuringElement(MORPH_CROSS,size);
buffer << "corsskernel =Mat corssKernel = getStructuringElement(MORPH_CROSS,size);" << endl;
buffer <<corssKernel << endl;
Mat erodeImage3;
erode(srcImage,erodeImage3,corssKernel,anchor,iterations);
//img_result = erodeImage3.clone();
Mat dilateImage3;
dilate(srcImage,dilateImage3,corssKernel,anchor,iterations);
//img_result = dilateImage3.clone();
const char *cstr = buffer.str().c_str();
result = env->NewStringUTF(cstr);
return result;
}
morphologyEx 부분
JNIEXPORT jstring JNICALL
Java_com_tistory_technote_opencvandroid_MainActivity_convertNativeLibtoMorpologyEx(JNIEnv *env, jobject, jlong addrInput, jlong addrResult) {
Mat &img_input = *(Mat *) addrInput;
Mat &img_result = *(Mat *) addrResult;
cvtColor(img_input, img_result, CV_RGBA2GRAY);
jstring result;
std::stringstream buffer;
Mat srcImage = img_result;
Size size(5,5);
Mat rectKernel = getStructuringElement(MORPH_RECT, size);
buffer << "rectkernel =Mat rectKernel = getStructuringElement(MORPH_RECT, size); " << endl;
buffer << rectKernel << endl;
int iterations = 5;
Point anchor(-1,-1);
Mat openImage;
morphologyEx(srcImage,openImage,MORPH_OPEN,rectKernel,anchor,iterations);
img_result = openImage.clone();
Mat closeImage;
morphologyEx(srcImage,closeImage,MORPH_CLOSE,rectKernel,anchor,iterations);
//img_result = closeImage.clone();
Mat gradientImage;
morphologyEx(srcImage,gradientImage,MORPH_GRADIENT,rectKernel,anchor,iterations);
//img_result = gradientImage.clone();
Mat tophatImage;
morphologyEx(srcImage,tophatImage,MORPH_TOPHAT,rectKernel,anchor,iterations);
//img_result = tophatImage.clone();
Mat blackhatImage;
morphologyEx(srcImage,blackhatImage,MORPH_TOPHAT,rectKernel,anchor,iterations);
//img_result = blackhatImage.clone();
const char *cstr = buffer.str().c_str();
result = env->NewStringUTF(cstr);
return result;
}
관련문의
- 이메일: [email protected]
- Blog : technote.tistory.com
- Github : https://gitlab.com/Technote/opencv320-android-study