.. ocv:pyfunction:: cv2.blur(src, ksize[, dst[, anchor[, borderType]]]) -> dst
- :param src: Source image.
+ :param src: Source image. The image can have any number of channels, which are processed independently. The depth should be ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F`` or ``CV_64F``.
:param dst: Destination image of the same size and type as ``src`` .
\alpha = \fork{\frac{1}{\texttt{ksize.width*ksize.height}}}{when \texttt{normalize=true}}{1}{otherwise}
-Unnormalized box filter is useful for computing various integral characteristics over each pixel neighborhood, such as covariance matrices of image derivatives (used in dense optical flow algorithms,
-and so on). If you need to compute pixel sums over variable-size windows, use
-:ocv:func:`integral` .
+Unnormalized box filter is useful for computing various integral characteristics over each pixel neighborhood, such as covariance matrices of image derivatives (used in dense optical flow algorithms, and so on). If you need to compute pixel sums over variable-size windows, use :ocv:func:`integral` .
.. seealso::
.. ocv:function:: Ptr<FilterEngine> createMorphologyFilter(int op, int type, InputArray element, Point anchor=Point(-1,-1), int rowBorderType=BORDER_CONSTANT, int columnBorderType=-1, const Scalar& borderValue=morphologyDefaultBorderValue())
-.. ocv:function:: Ptr<BaseFilter> getMorphologyFilter(int op, int type, InputArray element, Point anchor=Point(-1,-1))
+.. ocv:function:: Ptr<BaseFilter> getMorphologyFilter(int op, int type, InputArray element, Point anchor=Point(-1,-1))
-.. ocv:function:: Ptr<BaseRowFilter> getMorphologyRowFilter(int op, int type, int esize, int anchor=-1)
+.. ocv:function:: Ptr<BaseRowFilter> getMorphologyRowFilter(int op, int type, int esize, int anchor=-1)
-.. ocv:function:: Ptr<BaseColumnFilter> getMorphologyColumnFilter(int op, int type, int esize, int anchor=-1)
+.. ocv:function:: Ptr<BaseColumnFilter> getMorphologyColumnFilter(int op, int type, int esize, int anchor=-1)
.. ocv:function:: Scalar morphologyDefaultBorderValue()
:param op: Morphology operation ID, ``MORPH_ERODE`` or ``MORPH_DILATE`` .
-
- :param type: Input/output image type. The image must have 1-4 channels and valid image depths are ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F``.
+
+ :param type: Input/output image type. The number of channels can be arbitrary. The depth should be one of ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F` or ``CV_64F``.
:param element: 2D 8-bit structuring element for a morphological operation. Non-zero elements indicate the pixels that belong to the element.
.. ocv:cfunction:: void cvDilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 )
.. ocv:pyoldfunction:: cv.Dilate(src, dst, element=None, iterations=1)-> None
- :param src: Source image. The image must have 1-4 channels and valid image depths are ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F``.
+ :param src: Source image. The number of channels can be arbitrary. The depth should be one of ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F` or ``CV_64F``.
:param dst: Destination image of the same size and type as ``src`` .
.. ocv:cfunction:: void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1)
.. ocv:pyoldfunction:: cv.Erode(src, dst, element=None, iterations=1)-> None
- :param src: Source image. The image must have 1-4 channels and valid image depths are ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F``.
+ :param src: Source image. The number of channels can be arbitrary. The depth should be one of ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F` or ``CV_64F``.
- :param dst: Destination image of the same size and type as ``src`` .
+ :param dst: Destination image of the same size and type as ``src``.
:param element: Structuring element used for erosion. If ``element=Mat()`` , a ``3 x 3`` rectangular structuring element is used.
:param dst: Destination image of the same size and the same number of channels as ``src`` .
- :param ddepth: Desired depth of the destination image. If it is negative, it will be the same as ``src.depth()`` .
+ :param ddepth: Desired depth of the destination image. If it is negative, it will be the same as ``src.depth()`` . The following combination of ``src.depth()`` and ``ddepth`` are supported:
+ * ``src.depth()`` = ``CV_8U``, ``ddepth`` = -1/``CV_16S``/``CV_32F``/``CV_64F``
+ * ``src.depth()`` = ``CV_16U``/``CV_16S``, ``ddepth`` = -1/``CV_32F``/``CV_64F``
+ * ``src.depth()`` = ``CV_32F``, ``ddepth`` = -1/``CV_32F``/``CV_64F``
+ * ``src.depth()`` = ``CV_64F``, ``ddepth`` = -1/``CV_64F``
+
+ when ``ddepth=-1``, the destination image will have the same depth as the source.
:param kernel: Convolution kernel (or rather a correlation kernel), a single-channel floating point matrix. If you want to apply different kernels to different channels, split the image into separate color planes using :ocv:func:`split` and process them individually.
.. ocv:pyfunction:: cv2.GaussianBlur(src, ksize, sigma1[, dst[, sigma2[, borderType]]]) -> dst
- :param src: Source image.
+ :param src: Source image. The image can have any number of channels, which are processed independently. The depth should be ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F`` or ``CV_64F``.
:param dst: Destination image of the same size and type as ``src`` .
.. ocv:cfunction:: void cvMorphologyEx( const CvArr* src, CvArr* dst, CvArr* temp, IplConvKernel* element, int operation, int iterations=1 )
.. ocv:pyoldfunction:: cv.MorphologyEx(src, dst, temp, element, operation, iterations=1)-> None
- :param src: Source image. The image must have 1-4 channels and valid image depths are ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F``.
+ :param src: Source image. The number of channels can be arbitrary. The depth should be one of ``CV_8U``, ``CV_16U``, ``CV_16S``, ``CV_32F` or ``CV_64F``.
:param dst: Destination image of the same size and type as ``src`` .
:param dst: Destination image of the same size and the same number of channels as ``src`` .
- :param ddepth: Destination image depth.
+ :param ddepth: Destination image depth. The following combination of ``src.depth()`` and ``ddepth`` are supported:
+ * ``src.depth()`` = ``CV_8U``, ``ddepth`` = -1/``CV_16S``/``CV_32F``/``CV_64F``
+ * ``src.depth()`` = ``CV_16U``/``CV_16S``, ``ddepth`` = -1/``CV_32F``/``CV_64F``
+ * ``src.depth()`` = ``CV_32F``, ``ddepth`` = -1/``CV_32F``/``CV_64F``
+ * ``src.depth()`` = ``CV_64F``, ``ddepth`` = -1/``CV_64F``
+
+ when ``ddepth=-1``, the destination image will have the same depth as the source.
:param rowKernel: Coefficients for filtering each row.
if( rowBorderType == BORDER_CONSTANT || columnBorderType == BORDER_CONSTANT )
{
constBorderValue.resize(srcElemSize*borderLength);
- scalarToRawData(_borderValue, &constBorderValue[0], srcType,
+ int srcType1 = CV_MAKETYPE(CV_MAT_DEPTH(srcType), MIN(CV_MAT_CN(srcType), 4));
+ scalarToRawData(_borderValue, &constBorderValue[0], srcType1,
borderLength*CV_MAT_CN(srcType));
}
template<> inline uchar MinOp<uchar>::operator ()(uchar a, uchar b) const { return CV_MIN_8U(a, b); }
template<> inline uchar MaxOp<uchar>::operator ()(uchar a, uchar b) const { return CV_MAX_8U(a, b); }
+struct MorphRowNoVec
+{
+ MorphRowNoVec(int, int) {}
+ int operator()(const uchar*, uchar*, int, int) const { return 0; }
+};
+
+struct MorphColumnNoVec
+{
+ MorphColumnNoVec(int, int) {}
+ int operator()(const uchar**, uchar*, int, int, int) const { return 0; }
+};
+
+struct MorphNoVec
+{
+ int operator()(uchar**, int, uchar*, int) const { return 0; }
+};
+
#if CV_SSE2
template<class VecUpdate> struct MorphRowIVec
#else
-struct MorphRowNoVec
-{
- MorphRowNoVec(int, int) {}
- int operator()(const uchar*, uchar*, int, int) const { return 0; }
-};
-
-struct MorphColumnNoVec
-{
- MorphColumnNoVec(int, int) {}
- int operator()(const uchar**, uchar*, int, int, int) const { return 0; }
-};
-
-struct MorphNoVec
-{
- int operator()(uchar**, int, uchar*, int) const { return 0; }
-};
-
#ifdef HAVE_TEGRA_OPTIMIZATION
using tegra::ErodeRowVec8u;
using tegra::DilateRowVec8u;
#endif
+typedef MorphRowNoVec ErodeRowVec64f;
+typedef MorphRowNoVec DilateRowVec64f;
+typedef MorphColumnNoVec ErodeColumnVec64f;
+typedef MorphColumnNoVec DilateColumnVec64f;
+typedef MorphNoVec ErodeVec64f;
+typedef MorphNoVec DilateVec64f;
+
template<class Op, class VecOp> struct MorphRowFilter : public BaseRowFilter
{
if( depth == CV_32F )
return Ptr<BaseRowFilter>(new MorphRowFilter<MinOp<float>,
ErodeRowVec32f>(ksize, anchor));
+ if( depth == CV_64F )
+ return Ptr<BaseRowFilter>(new MorphRowFilter<MinOp<double>,
+ ErodeRowVec64f>(ksize, anchor));
}
else
{
if( depth == CV_32F )
return Ptr<BaseRowFilter>(new MorphRowFilter<MaxOp<float>,
DilateRowVec32f>(ksize, anchor));
+ if( depth == CV_64F )
+ return Ptr<BaseRowFilter>(new MorphRowFilter<MaxOp<double>,
+ DilateRowVec64f>(ksize, anchor));
}
CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type));
if( depth == CV_32F )
return Ptr<BaseColumnFilter>(new MorphColumnFilter<MinOp<float>,
ErodeColumnVec32f>(ksize, anchor));
+ if( depth == CV_64F )
+ return Ptr<BaseColumnFilter>(new MorphColumnFilter<MinOp<double>,
+ ErodeColumnVec64f>(ksize, anchor));
}
else
{
if( depth == CV_32F )
return Ptr<BaseColumnFilter>(new MorphColumnFilter<MaxOp<float>,
DilateColumnVec32f>(ksize, anchor));
+ if( depth == CV_64F )
+ return Ptr<BaseColumnFilter>(new MorphColumnFilter<MaxOp<double>,
+ DilateColumnVec64f>(ksize, anchor));
}
CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type));
return Ptr<BaseFilter>(new MorphFilter<MinOp<short>, ErodeVec16s>(kernel, anchor));
if( depth == CV_32F )
return Ptr<BaseFilter>(new MorphFilter<MinOp<float>, ErodeVec32f>(kernel, anchor));
+ if( depth == CV_64F )
+ return Ptr<BaseFilter>(new MorphFilter<MinOp<double>, ErodeVec64f>(kernel, anchor));
}
else
{
return Ptr<BaseFilter>(new MorphFilter<MaxOp<short>, DilateVec16s>(kernel, anchor));
if( depth == CV_32F )
return Ptr<BaseFilter>(new MorphFilter<MaxOp<float>, DilateVec32f>(kernel, anchor));
+ if( depth == CV_64F )
+ return Ptr<BaseFilter>(new MorphFilter<MaxOp<double>, DilateVec64f>(kernel, anchor));
}
CV_Error_( CV_StsNotImplemented, ("Unsupported data type (=%d)", type));
borderValue == morphologyDefaultBorderValue() )
{
int depth = CV_MAT_DEPTH(type);
- CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32F );
+ CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_16S ||
+ depth == CV_32F || depth == CV_64F );
if( op == MORPH_ERODE )
borderValue = Scalar::all( depth == CV_8U ? (double)UCHAR_MAX :
- depth == CV_16U ? (double)USHRT_MAX : (double)FLT_MAX );
+ depth == CV_16U ? (double)USHRT_MAX :
+ depth == CV_16S ? (double)SHRT_MAX :
+ depth == CV_32F ? (double)FLT_MAX : DBL_MAX);
else
borderValue = Scalar::all( depth == CV_8U || depth == CV_16U ?
- 0. : (double)-FLT_MAX );
+ 0. :
+ depth == CV_16S ? (double)SHRT_MIN :
+ depth == CV_32F ? (double)-FLT_MAX : -DBL_MAX);
}
return Ptr<FilterEngine>(new FilterEngine(filter2D, rowFilter, columnFilter,
int cdepth = CV_MAT_DEPTH(ctype), ccn = CV_MAT_CN(ctype);
CV_Assert( img.dims <= 2 && templ.dims <= 2 && corr.dims <= 2 );
- CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32F || depth == CV_64F );
if( depth != tdepth && tdepth != std::max(CV_32F, depth) )
{
corr.create(corrsize, ctype);
- int maxDepth = depth > CV_8U ? CV_64F : std::max(std::max(CV_32F, tdepth), cdepth);
+ int maxDepth = depth > CV_8S ? CV_64F : std::max(std::max(CV_32F, tdepth), cdepth);
Size blocksize, dftsize;
blocksize.width = cvRound(templ.cols*blockScale);
}
}
-/*void
-cv::crossCorr( const Mat& img, const Mat& templ, Mat& corr,
- Point anchor, double delta, int borderType )
-{
- CvMat _img = img, _templ = templ, _corr = corr;
- icvCrossCorr( &_img, &_templ, &_corr, anchor, delta, borderType );
-}*/
-
}
/*****************************************************************************************/
TEST(Imgproc_EigenValsVecs, accuracy) { CV_EigenValVecTest test; test.safe_run(); }
TEST(Imgproc_PreCornerDetect, accuracy) { CV_PreCornerDetectTest test; test.safe_run(); }
TEST(Imgproc_Integral, accuracy) { CV_IntegralTest test; test.safe_run(); }
+
+//////////////////////////////////////////////////////////////////////////////////
+
+class CV_FilterSupportedFormatsTest : public cvtest::BaseTest
+{
+public:
+ CV_FilterSupportedFormatsTest() {}
+ ~CV_FilterSupportedFormatsTest() {}
+protected:
+ void run(int)
+ {
+ const int depths[][2] =
+ {
+ {CV_8U, CV_8U},
+ {CV_8U, CV_16U},
+ {CV_8U, CV_16S},
+ {CV_8U, CV_32F},
+ {CV_8U, CV_64F},
+ {CV_16U, CV_16U},
+ {CV_16U, CV_32F},
+ {CV_16U, CV_64F},
+ {CV_16S, CV_16S},
+ {CV_16S, CV_32F},
+ {CV_16S, CV_64F},
+ {CV_32F, CV_32F},
+ {CV_64F, CV_64F},
+ {-1, -1}
+ };
+
+ int i = 0;
+ volatile int fidx = -1;
+ try
+ {
+ // use some "odd" size to do yet another smoke
+ // testing of the non-SIMD loop tails
+ Size sz(163, 117);
+ Mat small_kernel(5, 5, CV_32F), big_kernel(21, 21, CV_32F);
+ Mat kernelX(11, 1, CV_32F), kernelY(7, 1, CV_32F);
+ Mat symkernelX(11, 1, CV_32F), symkernelY(7, 1, CV_32F);
+ randu(small_kernel, -10, 10);
+ randu(big_kernel, -1, 1);
+ randu(kernelX, -1, 1);
+ randu(kernelY, -1, 1);
+ flip(kernelX, symkernelX, 0);
+ symkernelX += kernelX;
+ flip(kernelY, symkernelY, 0);
+ symkernelY += kernelY;
+
+ Mat elem_ellipse = getStructuringElement(MORPH_ELLIPSE, Size(7, 7));
+ Mat elem_rect = getStructuringElement(MORPH_RECT, Size(7, 7));
+
+ for( i = 0; depths[i][0] >= 0; i++ )
+ {
+ int sdepth = depths[i][0];
+ int ddepth = depths[i][1];
+ Mat src(sz, CV_MAKETYPE(sdepth, 5)), dst;
+ randu(src, 0, 100);
+ // non-separable filtering with a small kernel
+ fidx = 0;
+ filter2D(src, dst, ddepth, small_kernel);
+ fidx++;
+ filter2D(src, dst, ddepth, big_kernel);
+ fidx++;
+ sepFilter2D(src, dst, ddepth, kernelX, kernelY);
+ fidx++;
+ sepFilter2D(src, dst, ddepth, symkernelX, symkernelY);
+ fidx++;
+ Sobel(src, dst, ddepth, 2, 0, 5);
+ fidx++;
+ Scharr(src, dst, ddepth, 0, 1);
+ if( sdepth != ddepth )
+ continue;
+ fidx++;
+ GaussianBlur(src, dst, Size(5, 5), 1.2, 1.2);
+ fidx++;
+ blur(src, dst, Size(11, 11));
+ fidx++;
+ morphologyEx(src, dst, MORPH_GRADIENT, elem_ellipse);
+ fidx++;
+ morphologyEx(src, dst, MORPH_GRADIENT, elem_rect);
+ }
+ }
+ catch(...)
+ {
+ ts->printf(cvtest::TS::LOG, "Combination of depths %d => %d in %s is not supported (yet it should be)",
+ depths[i][0], depths[i][1],
+ fidx == 0 ? "filter2D (small kernel)" :
+ fidx == 1 ? "filter2D (large kernel)" :
+ fidx == 2 ? "sepFilter2D" :
+ fidx == 3 ? "sepFilter2D (symmetrical/asymmetrical kernel)" :
+ fidx == 4 ? "Sobel" :
+ fidx == 5 ? "Scharr" :
+ fidx == 6 ? "GaussianBlur" :
+ fidx == 7 ? "blur" :
+ fidx == 8 || fidx == 9 ? "morphologyEx" :
+ "unknown???");
+
+ ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
+ }
+ }
+};
+
+TEST(Imgproc_Filtering, supportedFormats) { CV_FilterSupportedFormatsTest test; test.safe_run(); }
+