OpenCV代码提取:morphologyEx函数的实现

2023-11-03

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:

// 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;
}

GitHubhttps://github.com/fengbingchun/OpenCV_Test

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV代码提取:morphologyEx函数的实现 的相关文章

  • cv2.imread:检查图像是否正在被读取

    我正在用 python 编写一个 OpenCV 程序 在某些时候我有类似的东西 import cv2 import numpy as np img cv2 imread myImage jpg do stuff with image her
  • 相机姿态估计(OpenCV PnP)

    我正在尝试使用网络摄像头从具有已知全球位置的四个基准点的图像中获取全局姿态估计 我检查了许多 stackexchange 问题和一些论文 但似乎无法得到正确的解决方案 我得到的位置数字是可重复的 但与相机移动绝不成线性比例 仅供参考 我正在
  • 屏幕截图中低分辨率文本的 OCR

    我正在编写一个 OCR 应用程序来从屏幕截图图像中读取字符 目前 我只关注数字 我的方法部分基于这篇博文 http blog damiles com 2008 11 basic ocr in opencv http blog damiles
  • 如何使图像呈现出陈旧、布满灰尘、颜色褪色的外观?

    我有旧画的图像 这些画很旧 布满灰尘 颜色褪色 如图所示here https i stack imgur com xuoEF jpg 如何赋予任何图像这种 旧 外观 我找不到任何过滤器或 openCV 函数来实现这种类型的外观 EDIT 我
  • opencv 视频上的颜色阈值

    I am thresholding for a color range in an opencv video The goal is to seperate the B mode black and white information on
  • OpenCV findContours 破坏源图像

    我编写了一个在单通道空白图像中绘制圆形 直线和矩形的代码 之后 我只需找出图像中的轮廓 就可以正确获取所有轮廓 但找到轮廓后 我的源图像变得扭曲 为什么会出现这种情况 任何人都可以帮我解决这个问题 我的代码如下所示 using namesp
  • 查找彼此接近的对象边界

    我正在研究一个计算机视觉问题 其中问题的第一步是找到物体彼此靠近的位置 例如 在下图中 我感兴趣的是找到灰色标记的区域 Input Output 我目前的方法是首先反转图像 然后通过侵蚀进行形态梯度跟随 然后删除一些不感兴趣的轮廓 脚本如下
  • 如何在Python中使用tcp套接字发送和接收网络摄像头流?

    我正在尝试重新创建这个项目 https github com hamuchiwa AutoRCCar 我拥有的是服务器 我的电脑 和客户端 我的树莓派 我所做的与原始项目不同的是我尝试使用一个简单的网络摄像头而不是树莓派摄像头将图像从我的
  • 如何删除树莓派的相机预览

    我在我的 raspberryPi 上安装了 SimpleCv 并安装了用于使用相机板的驱动程序 uv4l 驱动程序 现在我想使用它 当我在 simpleCV shell Camera 0 getImage save foo jpg 上键入时
  • 如何设置K-means openCV c++的初始中心

    我正在尝试使用 OpenCv 和 Kmeans 对图像进行分割 我刚刚实现的代码如下 include opencv2 objdetect objdetect hpp include opencv2 highgui highgui hpp i
  • OpenCV的拼接模块可以拼接平行运动相机拍摄的图像吗?

    我想知道是否缝合 http docs opencv org modules stitching doc stitching html http docs opencv org modules stitching doc stitching
  • 曲线/路径骨架二值图像处理

    我正在尝试开发一个可以处理图像骨架的路径 曲线的代码 我想要一个来自两点之间骨架的点向量 该代码在添加一些点后结束 我没有找到解决方案 include opencv2 highgui highgui hpp include opencv2
  • BASH 脚本编译多个 C++ 文件 - OpenCV

    请参见在C 和OpenCV中调用其他文件中的函数 https stackoverflow com questions 24442836 call functions in other files in c and opencv 对于最初的问
  • 使用 ffmpeg 或 OpenCV 处理原始图像

    看完之后维基百科页面 http en wikipedia org wiki Raw image format原始图像格式 是任何图像的数字负片 为了查看或打印 相机图像传感器的输出具有 进行处理 即转换为照片渲染 场景 然后以标准光栅图形格
  • OpenCV 2.3 与 VS 2008 - 鼠标事件

    强制性 我是新手 有一份涉及编程的工作 并且我一边工作一边自学 不用说 作为一名老师 我经常犯彻底的错误 我现在所处的位置 我创建了 Graph 类 它 令人惊讶的是 制作了图表 但现在我想通过单击鼠标来修改图形 但我似乎无法让鼠标处理程序
  • ffmpeg AVFrame 到 opencv Mat 转换

    我目前正在开发一个使用 ffmpeg 解码接收到的帧的项目 解码后 我想将 AVFrame 转换为 opencv Mat 帧 以便我可以在 imShow 函数上播放它 我拥有的是字节流 我将其读入缓冲区 解码为 AVFrame f fope
  • minAreaRect OpenCV 返回的裁剪矩形 [Python]

    minAreaRectOpenCV 中返回一个旋转的矩形 如何裁剪矩形内图像的这部分 boxPoints返回旋转矩形的角点的坐标 以便可以通过循环框内的点来访问像素 但是在 Python 中是否有更快的裁剪方法 EDIT See code在
  • OpenCV 2.4.3 中的阴影去除

    我正在使用 OpenCV 2 4 3 最新版本 使用内置的视频流检测前景GMG http docs opencv org modules gpu doc video html highlight gmg gpu 3a 3aGMG GPU算法
  • 如何确定与视频中物体的距离?

    我有一个从行驶中的车辆前面录制的视频文件 我将使用 OpenCV 进行对象检测和识别 但我停留在一方面 如何确定距已识别物体的距离 我可以知道我当前的速度和现实世界的 GPS 位置 但仅此而已 我无法对我正在跟踪的对象做出任何假设 我计划用
  • 从包含带边框的表格的图像中提取表格结构

    我正在尝试提取下表中的单元格位置 应用自适应阈值处理后 我能够获得细胞位置周围的轮廓 并且 HoughLines 获得垂直和水平结构元素 这是我的代码 img cv2 imread os path join img path file im

随机推荐

  • 推荐-社交推荐相关

    总结 近时间矩阵分解 社交信息的融合模型 2018 模型性能 不同社交推荐方法在不同数据集中不同用户社交强度下的性能对比 研究难点与热点 数据稀疏性 社交关系的有效挖掘 社交噪声 可解释性社交推荐 可扩展型社交推荐模型与多源信息的融合 社交
  • Linux 面试常见(55题)

    TOC删除线格式 一 文件管理 目录操作 创建目录 mkdir mkdir命令可以创建一个新的目录 例如 在当前目录下创建一个名为 test 的目录 mkdir test 2 删除目录 rmdir rmdir命令可以删除一个空目录 例如 要
  • 结构体输入输出(c语言)

    include
  • 实现Echarts词云和随机颜色(vue2)

    1 首先需要安装echarts和echarts wordcloud插件 2 echarts的版本和echarts wordcloud版本有对应要求才能实现 否则会报错 经过查询如果是用的是echarts4那么需要对应着echarts wor
  • python自动化课程笔记(十一)封装、继承、多态

    class Dog object good dog 说明文档 def init self new name color age 5 self name new name self color color self age age def s
  • Tomcat安装及部署

    Aphorism 安装 忽略下载过程 1 解压文件 把 tomcat 安装包解压到 D Program Files 下 2 启动 tomcat 在 tomcat 文件包的 bin 文件夹中 双击 startup bat 文件启动tomcat
  • 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。(C++实现)

    题目介绍 给定一个链表 删除链表的倒数第 n 个节点 并且返回链表的头结点 示例 给定一个链表 1 gt 2 gt 3 gt 4 gt 5 和 n 2 当删除了倒数第二个节点后 链表变为 1 gt 2 gt 3 gt 5 说明 给定的 n
  • Oil Deposits

    http poj org problem id 1562 Oil Deposits Description The GeoSurvComp geologic survey company is responsible for detecti
  • 10个超炫超有用的js库/插件

    原文地址 http blog csdn net shyy123 article details 7471782 1 CodeMirror CodeMirror 是一款 Online Source Editor 基于 Javascript 短
  • MyEclipse集成PMD代码检测插件自定义规则配置文件

    把我今天最新更新的MyEclipse2014集成PMD代码检测插件自定义规则配置文件JAVA版发布出来吧 方便自己以后回顾的同时 也看看能不能帮到有这方面需求的小伙伴们 文件名 cplatform pmd5 2 3 rules xml
  • Android.bp文件简介

    Android bp Android bp的出现就是为了替换Android mk文件 bp跟mk文件不同 它是纯粹的配置 没有分支 循环等流程控制 不能做算数逻辑运算 如果需要控制逻辑 那么只能通过Go语言编写 语法 根据设计 Androi
  • 为什么opencv用GPU实现比用CPU实现的慢?

    问题 打算通过OpenCV的GPU模块优化现有代码的运行效率 怀抱着美好愿望开始了代码的改写工作 改写的过程并不顺利 遇到了不少问题 例如 gpu模块提供的接口非常坑爹 相当一部分不支持浮点类型 像histogram integral这类常
  • SpringCloud实践(四) 通过Feign组件实现消费者

    在前面使用了RestTemplate和Ribbon来实现了服务消费者 Feign 是一个集成了Ribbon和Eureka的组件 通过声明的方式 就可以实现Http客户端 简化了http客户端 服务消费者 对于Feign 我们只要记得两个特点
  • Aspose工具实现word和ppt转pdf功能及遇到的一些问题

    Aspose工具包从word和ppt转到pdf的实现过程 直接放项目地址 说一下实现过程中遇到的坑 直接放项目地址 https github com lichangliu1098 File2Pdf 说一下实现过程中遇到的坑 jar包的引入
  • Zabbix部署详细步骤

    以下是在Ubuntu上安装Zabbix的详细步骤 1 更新系统 使用以下命令更新Ubuntu系统 sudo apt get update sudo apt get upgrade 2 安装依赖项 在安装Zabbix之前 需要先安装一些依赖项
  • 教你快速上手Flex弹性盒布局(容器属性)

    目录 简介 一 Flex布局语法 1 1 display flex 二 Flex属性 三 容器属性 3 1 flex direction 3 2 flex direction row 3 3 flex direction row rever
  • 【华为OD统一考试B卷

    在线OJ 已购买本专栏用户 请私信博主开通账号 在线刷题 运行出现 Runtime Error 0Aborted 请忽略 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为 2023A卷和2023B卷 你收
  • Tachyon内存文件系统

    Tachyon内存文件系统 Tachyon是以内存为中心的分布式文件系统 拥有高性能和容错能力 能够为集群框架 如Spark MapReduce 提供可靠的内存级速度的文件共享服务 从软件栈的层次来看 Tachyon是位于现有大数据计算框架
  • 使用GitHub的一些小知识合集

    文章目录 一 FastGithub 1 稳定可靠的github加速神器 FastGithub 2 github加速神器 FastGithub 二 README md添加图片 1 怎么给README md添加图片 两种方法 图文教程 2 在R
  • OpenCV代码提取:morphologyEx函数的实现

    Morphological Operations A set of operations that process images based on shapes Morphological operations apply a struct