diff --git a/modules/imgproc/doc/filtering.rst b/modules/imgproc/doc/filtering.rst index 24bd9d04cb..0a78c365ff 100755 --- a/modules/imgproc/doc/filtering.rst +++ b/modules/imgproc/doc/filtering.rst @@ -1231,6 +1231,8 @@ Performs advanced morphological transformations. * **MORPH_BLACKHAT** - "black hat" + * **MORPH_HITMISS** - "hit and miss" + :param iterations: Number of times erosion and dilation are applied. :param borderType: Pixel extrapolation method. See :ocv:func:`borderInterpolate` for details. @@ -1269,6 +1271,8 @@ Morphological gradient: \texttt{dst} = \mathrm{blackhat} ( \texttt{src} , \texttt{element} )= \mathrm{close} ( \texttt{src} , \texttt{element} )- \texttt{src} +"Hit and Miss": Only supported for CV_8UC1 binary images. Tutorial can be found in this page: http://opencv-code.com/tutorials/hit-or-miss-transform-in-opencv/ + Any of the operations can be done in-place. In case of multi-channel images, each channel is processed independently. .. seealso:: diff --git a/modules/imgproc/include/opencv2/imgproc/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc/imgproc.hpp index f46cc643c8..aa6a5f6ca3 100644 --- a/modules/imgproc/include/opencv2/imgproc/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc/imgproc.hpp @@ -352,7 +352,7 @@ CV_EXPORTS_W Mat getGaborKernel( Size ksize, double sigma, double theta, double enum { MORPH_ERODE=CV_MOP_ERODE, MORPH_DILATE=CV_MOP_DILATE, MORPH_OPEN=CV_MOP_OPEN, MORPH_CLOSE=CV_MOP_CLOSE, MORPH_GRADIENT=CV_MOP_GRADIENT, MORPH_TOPHAT=CV_MOP_TOPHAT, - MORPH_BLACKHAT=CV_MOP_BLACKHAT }; + MORPH_BLACKHAT=CV_MOP_BLACKHAT, MORPH_HITMISS }; //! returns horizontal 1D morphological filter CV_EXPORTS Ptr getMorphologyRowFilter(int op, int type, int ksize, int anchor=-1); diff --git a/modules/imgproc/src/morph.cpp b/modules/imgproc/src/morph.cpp index fa1f8acbf3..1cf4a625dd 100644 --- a/modules/imgproc/src/morph.cpp +++ b/modules/imgproc/src/morph.cpp @@ -1374,6 +1374,8 @@ void cv::morphologyEx( InputArray _src, OutputArray _dst, int op, _dst.create(src.size(), src.type()); Mat dst = _dst.getMat(); + Mat k1, k2, e1, e2; //only for hit and miss op + switch( op ) { case MORPH_ERODE: @@ -1409,6 +1411,24 @@ void cv::morphologyEx( InputArray _src, OutputArray _dst, int op, erode( temp, temp, kernel, anchor, iterations, borderType, borderValue ); dst = temp - src; break; + case MORPH_HITMISS: + CV_Assert(src.type() == CV_8UC1); + k1 = (kernel.getMat() == 1); + k2 = (kernel.getMat() == -1); + if (countNonZero(k1) <= 0) + e1 = src; + else + erode(src, e1, k1, anchor, iterations, borderType, borderValue); + if (countNonZero(k2) <= 0) + e2 = src; + else + { + Mat src_complement; + bitwise_not(src, src_complement); + erode(src_complement, e2, k2, anchor, iterations, borderType, borderValue); + } + dst = e1 & e2; + break; default: CV_Error( CV_StsBadArg, "unknown morphological operation" ); }