OpenCV代码提取:morphologyEx函数的实现
2016-09-03 16:26
381 查看
Morphological Operations: A set of operations that process images based on shapes.Morphological operations apply a structuring element to an input image and generate an output image.
The most basic morphological operations are two: Erosion and Dilation. They have a wide array of uses, i.e.:
(1)、Removing noise.
(2)、Isolation of individual elements and joining disparate elements in an image.
(3)、Finding of intensity bumps or holes in an image.
数学形态学可以理解为一种滤波行为,因此也称为形态学滤波。滤波中用到的滤波器(kernal),在形态学中称为结构元素。结构元素往往是由一个特殊的形状构成,如线条、矩形、圆等。
开运算(open):先腐蚀后膨胀的过程。开运算可以用来消除小黑点,在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。
闭运算(close):先膨胀后腐蚀的过程。闭运算可以用来排除小黑洞。
形态学梯度(morph-grad):可以突出团块(blob)的边缘,保留物体的边缘轮廓。
顶帽(top-hat):将突出比原轮廓亮的部分。
黑帽(black-hat):将突出比原轮廓暗的部分。
目前fbc_cv库中支持uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一致。
实现代码morphologyEx.hpp:
GitHub:https://github.com/fengbingchun/OpenCV_Test
The most basic morphological operations are two: Erosion and Dilation. They have a wide array of uses, i.e.:
(1)、Removing noise.
(2)、Isolation of individual elements and joining disparate elements in an image.
(3)、Finding of intensity bumps or holes in an image.
数学形态学可以理解为一种滤波行为,因此也称为形态学滤波。滤波中用到的滤波器(kernal),在形态学中称为结构元素。结构元素往往是由一个特殊的形状构成,如线条、矩形、圆等。
开运算(open):先腐蚀后膨胀的过程。开运算可以用来消除小黑点,在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。
闭运算(close):先膨胀后腐蚀的过程。闭运算可以用来排除小黑洞。
形态学梯度(morph-grad):可以突出团块(blob)的边缘,保留物体的边缘轮廓。
顶帽(top-hat):将突出比原轮廓亮的部分。
黑帽(black-hat):将突出比原轮廓暗的部分。
目前fbc_cv库中支持uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一致。
实现代码morphologyEx.hpp:
// fbc_cv is free software and uses the same licence as OpenCV // Email: fengbingchun@163.com #ifndef FBC_CV_MORPHOLOGYEX_HPP_ #define FBC_CV_MORPHOLOGYEX_HPP_ /* reference: include/opencv2/imgproc.hpp modules/imgproc/src/morph.cpp */ #include <typeinfo> #include "erode.hpp" #include "dilate.hpp" namespace fbc { // perform advanced morphological transformations using an erosion and dilation as basic operations // In case of multi - channel images, each channel is processed independently. // morphologyEx can be applied several ( iterations ) times. // op ==> enum MorphTypes // support type: uchar/float, multi-channels template<typename _Tp, int chs> int morphologyEx(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst, int op, const 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); } Mat_<uchar, 1> kernel_ = kernel; if (kernel_.empty()) { kernel_ = Mat_<uchar, 1>(3, 3); getStructuringElement(kernel_, MORPH_RECT, Size(3, 3), Point(1, 1)); } switch (op) { case MORPH_ERODE: { erode(src, dst, kernel_, anchor, iterations, borderType, borderValue); break; } case MORPH_DILATE: { dilate(src, dst, kernel_, anchor, iterations, borderType, borderValue); break; } case MORPH_OPEN: { erode(src, dst, kernel_, anchor, iterations, borderType, borderValue); dilate(dst, dst, kernel_, anchor, iterations, borderType, borderValue); break; } case CV_MOP_CLOSE: { dilate(src, dst, kernel_, anchor, iterations, borderType, borderValue); erode(dst, dst, kernel_, anchor, iterations, borderType, borderValue); break; } case CV_MOP_GRADIENT: { Mat_<_Tp, chs> temp(src.rows, src.cols); erode(src, temp, kernel_, anchor, iterations, borderType, borderValue); dilate(src, dst, kernel_, anchor, iterations, borderType, borderValue); dst -= temp; break; } case CV_MOP_TOPHAT: { Mat_<_Tp, chs> temp(src.rows, src.cols); if (src.data != dst.data) temp = dst; erode(src, temp, kernel_, anchor, iterations, borderType, borderValue); dilate(temp, temp, kernel_, anchor, iterations, borderType, borderValue); dst = src - temp; break; } case CV_MOP_BLACKHAT: { Mat_<_Tp, chs> temp(src.rows, src.cols); if (src.data != dst.data) temp = dst; dilate(src, temp, kernel_, anchor, iterations, borderType, borderValue); erode(temp, temp, kernel_, anchor, iterations, borderType, borderValue); dst = temp - src; break; } case MORPH_HITMISS: { FBC_Assert(typeid(uchar).name() == typeid(_Tp).name() && chs == 1); Mat_<uchar, 1> k1 = (kernel_ == Mat_<uchar, 1>(kernel_.rows, kernel_.cols, Scalar::all(1))); Mat_<uchar, 1> k2 = (kernel_ == Mat_<int, 1>(kernel_.rows, kernel_.cols, Scalar::all(-1))); Mat_<_Tp, chs> e1, e2; if (countNonZero(k1) <= 0) e1 = src; else erode(src, e1, k1, anchor, iterations, borderType, borderValue); if (countNonZero(k2) <= 0) { e2 = src; } else { Mat_<_Tp, chs> src_complement; bitwise_not(src, src_complement); erode(src_complement, e2, k2, anchor, iterations, borderType, borderValue); } bitwise_and(e1, e2, dst); break; } default: FBC_Assert("unknown morphological operation"); } return 0; } } // namespace fbc #endif // FBC_CV_MORPHOLOGYEX_HPP_测试代码test_morphologyEx.cpp:
#include "test_erode.hpp" #include <assert.h> #include <morphologyEx.hpp> #include <opencv2/opencv.hpp> int test_morphologyEx_uchar() { cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1); if (!matSrc.data) { std::cout << "read image fail" << std::endl; return -1; } int width = matSrc.cols; int height = matSrc.rows; for (int elem = 0; elem < 3; elem++) { for (int size = 0; size < 5; size++) { for (int iterations = 1; iterations < 3; iterations++) { for (int operation = 0; operation < 7; operation++) { int type; if (elem == 0){ type = fbc::MORPH_RECT; } else if (elem == 1){ type = fbc::MORPH_CROSS; } else if (elem == 2) { type = fbc::MORPH_ELLIPSE; } fbc::Mat_<uchar, 1> element(2 * size + 1, 2 * size + 1); fbc::getStructuringElement(element, type, fbc::Size(2 * size + 1, 2 * size + 1), fbc::Point(size, size)); int type_; if (elem == 0){ type_ = cv::MORPH_RECT; } else if (elem == 1){ type_ = cv::MORPH_CROSS; } else if (elem == 2) { type_ = cv::MORPH_ELLIPSE; } cv::Mat element_ = cv::getStructuringElement(type_, cv::Size(2 * size + 1, 2 * size + 1), cv::Point(size, size)); assert(element.rows == element_.rows && element.cols == element.cols && element.step == element_.step); for (int y = 0; y < element.rows; y++) { const fbc::uchar* p1 = element.ptr(y); const uchar* p2 = element_.ptr(y); for (int x = 0; x < element.step; x++) { assert(p1[x] == p2[x]); } } fbc::Mat3BGR mat1(height, width, matSrc.data); fbc::Mat3BGR mat2(height, width); fbc::morphologyEx(mat1, mat2, operation, element, fbc::Point(-1, -1), iterations, 0, fbc::Scalar::all(128)); cv::Mat mat1_(height, width, CV_8UC3, matSrc.data); cv::Mat mat2_; cv::morphologyEx(mat1_, mat2_, operation, element_, cv::Point(-1, -1), iterations, 0, cv::Scalar::all(128)); assert(mat2.rows == mat2_.rows && mat2.cols == mat2_.cols && mat2.step == mat2_.step); for (int y = 0; y < mat2.rows; y++) { const fbc::uchar* p1 = mat2.ptr(y); const uchar* p2 = mat2_.ptr(y); for (int x = 0; x < mat2.step; x++) { assert(p1[x] == p2[x]); } } } } } } return 0; } int test_morphologyEx_float() { cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1); if (!matSrc.data) { std::cout << "read image fail" << std::endl; return -1; } cv::cvtColor(matSrc, matSrc, CV_BGR2GRAY); matSrc.convertTo(matSrc, CV_32FC1); int width = matSrc.cols; int height = matSrc.rows; for (int elem = 0; elem < 3; elem++) { for (int size = 0; size < 5; size++) { for (int iterations = 1; iterations < 3; iterations++) { for (int operation = 0; operation < 7; operation++) { int type; if (elem == 0){ type = fbc::MORPH_RECT; } else if (elem == 1){ type = fbc::MORPH_CROSS; } else if (elem == 2) { type = fbc::MORPH_ELLIPSE; } fbc::Mat_<uchar, 1> element(2 * size + 1, 2 * size + 1); fbc::getStructuringElement(element, type, fbc::Size(2 * size + 1, 2 * size + 1), fbc::Point(size, size)); int type_; if (elem == 0){ type_ = cv::MORPH_RECT; } else if (elem == 1){ type_ = cv::MORPH_CROSS; } else if (elem == 2) { type_ = cv::MORPH_ELLIPSE; } cv::Mat element_ = cv::getStructuringElement(type_, cv::Size(2 * size + 1, 2 * size + 1), cv::Point(size, size)); assert(element.rows == element_.rows && element.cols == element.cols && element.step == element_.step); for (int y = 0; y < element.rows; y++) { const fbc::uchar* p1 = element.ptr(y); const uchar* p2 = element_.ptr(y); for (int x = 0; x < element.step; x++) { assert(p1[x] == p2[x]); } } fbc::Mat_<float, 1> mat1(height, width, matSrc.data); fbc::Mat_<float, 1> mat2(height, width); fbc::morphologyEx(mat1, mat2, operation, element, fbc::Point(-1, -1), iterations, 0, fbc::Scalar::all(128)); cv::Mat mat1_(height, width, CV_32FC1, matSrc.data); cv::Mat mat2_; cv::morphologyEx(mat1_, mat2_, operation, element_, cv::Point(-1, -1), iterations, 0, cv::Scalar::all(128)); assert(mat2.rows == mat2_.rows && mat2.cols == mat2_.cols && mat2.step == mat2_.step); for (int y = 0; y < mat2.rows; y++) { const fbc::uchar* p1 = mat2.ptr(y); const uchar* p2 = mat2_.ptr(y); for (int x = 0; x < mat2.step; x++) { assert(p1[x] == p2[x]); } } } } } } return 0; } int test_morphologyEx_hitmiss() { cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1); if (!matSrc.data) { std::cout << "read image fail" << std::endl; return -1; } cv::cvtColor(matSrc, matSrc, CV_BGR2GRAY); int width = matSrc.cols; int height = matSrc.rows; for (int elem = 0; elem < 3; elem++) { for (int size = 0; size < 5; size++) { for (int iterations = 1; iterations < 3; iterations++) { int operation = 7; int type; if (elem == 0){ type = fbc::MORPH_RECT; } else if (elem == 1){ type = fbc::MORPH_CROSS; } else if (elem == 2) { type = fbc::MORPH_ELLIPSE; } fbc::Mat_<uchar, 1> element(2 * size + 1, 2 * size + 1); fbc::getStructuringElement(element, type, fbc::Size(2 * size + 1, 2 * size + 1), fbc::Point(size, size)); int type_; if (elem == 0){ type_ = cv::MORPH_RECT; } else if (elem == 1){ type_ = cv::MORPH_CROSS; } else if (elem == 2) { type_ = cv::MORPH_ELLIPSE; } cv::Mat element_ = cv::getStructuringElement(type_, cv::Size(2 * size + 1, 2 * size + 1), cv::Point(size, size)); assert(element.rows == element_.rows && element.cols == element.cols && element.step == element_.step); for (int y = 0; y < element.rows; y++) { const fbc::uchar* p1 = element.ptr(y); const uchar* p2 = element_.ptr(y); for (int x = 0; x < element.step; x++) { assert(p1[x] == p2[x]); } } fbc::Mat_<uchar, 1> mat1(height, width, matSrc.data); fbc::Mat_<uchar, 1> mat2(height, width); fbc::morphologyEx(mat1, mat2, operation, element, fbc::Point(-1, -1), iterations, 0, fbc::Scalar::all(128)); cv::Mat mat1_(height, width, CV_8UC1, matSrc.data); cv::Mat mat2_; cv::morphologyEx(mat1_, mat2_, operation, element_, cv::Point(-1, -1), iterations, 0, cv::Scalar::all(128)); assert(mat2.rows == mat2_.rows && mat2.cols == mat2_.cols && mat2.step == mat2_.step); for (int y = 0; y < mat2.rows; y++) { const fbc::uchar* p1 = mat2.ptr(y); const uchar* p2 = mat2_.ptr(y); for (int x = 0; x < mat2.step; x++) { assert(p1[x] == p2[x]); } } } } } return 0; }
GitHub:https://github.com/fengbingchun/OpenCV_Test
相关文章推荐
- OpenCV代码提取:morphologyEx函数的实现
- OpenCV代码提取:resize函数的实现
- OpenCV代码提取:flip函数的实现
- OpenCV代码提取:erode函数的实现
- OpenCV代码提取:remap函数的实现
- OpenCV代码提取:transpose函数的实现
- OpenCV代码提取:flip函数的实现
- OpenCV代码提取:transpose函数的实现
- 【图像特征提取12】OpenCv的SIFT图像局部特征提取描述算法C++代码的实现
- OpenCV代码提取:merge/split函数的实现
- OpenCV代码提取:cvtColor函数的实现
- OpenCV代码提取:merge/split函数的实现
- OpenCV代码提取:cvtColor函数的实现
- OpenCV代码提取:dilate函数的实现
- OpenCV特征提取与图像检索实现(附代码)
- HOG特征提取代码(opencv处理基本数据,c语言实现基本算法)
- HOG特征提取代码(opencv处理基本数据,c语言实现基本算法)
- OpenCV代码提取:dilate函数的实现
- OpenCV代码提取:dft函数的实现
- OpenCV代码提取:dft函数的实现