实现代码dilate.cpp:
- // fbc_cv是免费软件,并且使用与OpenCV相同的许可证
- #ifndef FBC_CV_DILATE_HPP_
- #define FBC_CV_DILATE_HPP_
- /* reference: include/opencv2/imgproc.hpp
- modules/imgproc/src/morph.cpp
- */
- #include <typeinfo>
- #include "core/mat.hpp"
- #include "imgproc.hpp"
- #include "filterengine.hpp"
- #include "core/core.hpp"
- #include "morph.hpp"
- namespace fbc {
- // 通过使用特定的结构元素来扩展图像
- // \f[\texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f]
- // 在多通道图像的情况下,每个通道被独立处理.
- // 支持类型:uchar / float,多通道
- template<typename _Tp, int chs>
- int dilate(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst, Mat_<uchar, 1>& kernel,
- Point anchor = Point(-1, -1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = Scalar::all(DBL_MAX))
- {
- FBC_Assert(typeid(uchar).name() == typeid(_Tp).name() || typeid(float).name() == typeid(_Tp).name()); // uchar || float
- if (dst.empty()) {
- dst = Mat_<_Tp, chs>(src.rows, src.cols);
- } else {
- FBC_Assert(src.rows == dst.rows && src.cols == dst.cols);
- }
- Size ksize = !kernel.empty() ? kernel.size() : Size(3, 3);
- anchor = normalizeAnchor(anchor, ksize);
- if (iterations == 0 || kernel.rows * kernel.cols == 1) {
- src.copyTo(dst);
- return 0;
- }
- if (kernel.empty()) {
- kernel = Mat_<uchar, 1>(1 + iterations * 2, 1 + iterations * 2);
- getStructuringElement(kernel, MORPH_RECT, Size(1 + iterations * 2, 1 + iterations * 2));
- anchor = Point(iterations, iterations);
- iterations = 1;
- } else if (iterations > 1 && countNonZero(kernel) == kernel.rows * kernel.cols) {
- anchor = Point(anchor.x*iterations, anchor.y*iterations);
- kernel = Mat_<uchar, 1>(ksize.height + (iterations - 1)*(ksize.height - 1), ksize.width + (iterations - 1)*(ksize.width - 1));
- getStructuringElement(kernel, MORPH_RECT,
- Size(ksize.width + (iterations - 1)*(ksize.width - 1), ksize.height + (iterations - 1)*(ksize.height - 1)), anchor);
- iterations = 1;
- }
- anchor = normalizeAnchor(anchor, kernel.size());
- Ptr<BaseRowFilter> rowFilter;
- Ptr<BaseColumnFilter> columnFilter;
- Ptr<BaseFilter> filter2D;
- if (countNonZero(kernel) == kernel.rows*kernel.cols) {
- // 矩形结构元素
- rowFilter = getMorphologyRowFilter<_Tp, chs>(1, kernel.cols, anchor.x);
- columnFilter = getMorphologyColumnFilter<_Tp, chs>(1, kernel.rows, anchor.y);
- } else {
- filter2D = getMorphologyFilter<_Tp, chs>(1, kernel, anchor);
- }
- Scalar borderValue_ = borderValue;
- if (borderType == BORDER_CONSTANT && borderValue_ == Scalar::all(DBL_MAX)) {
- if (sizeof(_Tp) == 1) // CV_8U
- borderValue_ = Scalar::all(0.);
- else // CV_32F
- borderValue_ = Scalar::all(-FLT_MAX);
- }
- Ptr<FilterEngine<_Tp, _Tp, _Tp, chs, chs, chs>> f = makePtr<FilterEngine<_Tp, _Tp, _Tp, chs, chs, chs>>(filter2D, rowFilter, columnFilter, borderType, borderType, borderValue_);
- f->apply(src, dst);
- for (int i = 1; i < iterations; i++)
- f->apply(dst, dst);
- return 0;
- }
- } // 命名空间fbc
- #endif // FBC_CV_DILATE_HPP_