首页 文章 精选 留言 我的

精选列表

搜索[图数据库],共10000篇文章
优秀的个人博客,低调大师

opencv提取保存轮廓图

pragma once include "open2_public.h" class ld_yjt_sub_image{public: //获取src_mat的轮廓个数,介于nMinSzie和nMaxSize之间的才会放入到evc_contours中 bool getContours(const Mat& src_mat, vector<vector<Point>>& evc_contours, const int& nMinSzie = 500, const int& nMaxSize = 100000); //生成影像名称 string getNewImage(); //提取出子影像文件 bool extract_sub_image(const string& src_image, vector<string>& vec_sub_image); private: //错误信息 CString m_strErrMsg; public: ld_yjt_sub_image(); virtual ~ld_yjt_sub_image(); }; include "stdafx.h" include "ld_yjt_sub_image.h" int g_lImageCount = 0; ld_yjt_sub_image::ld_yjt_sub_image(){} ld_yjt_sub_image::~ld_yjt_sub_image(){} //获取src_mat的轮廓个数,介于nMinSzie和nMaxSize之间的才会放入到evc_contours中bool ld_yjt_sub_image::getContours(const Mat& src_mat, vector>& evc_contours, const int& nMinSzie, const int& nMaxSize) { if (src_mat.empty()) { m_strErrMsg = "原始矩阵为空,无法获取轮廓个数"; return false; } if (src_mat.channels() != 3) { m_strErrMsg.Format("原始矩阵通道个数不为3个"); return false; } Mat mat_clone = src_mat.clone(); //灰度图像 cvtColor(mat_clone, mat_clone, COLOR_BGR2GRAY); //对图像进行二值化 threshold(mat_clone, mat_clone, 80, 255, THRESH_BINARY); vector<vector<Point>> evc_temp_contours; //提取轮廓元素 findContours(mat_clone, evc_temp_contours, CV_RETR_TREE, CHAIN_APPROX_NONE); for (int i = 0; i < evc_temp_contours.size(); i++) { if (evc_temp_contours[i].size() < nMinSzie || evc_temp_contours[i].size() > nMaxSize) //轮廓尺寸过小或者过大 continue; //添加进入容器 evc_contours.push_back(evc_temp_contours[i]); } return true; } //生成影像名称string ld_yjt_sub_image::getNewImage(){ string str_new_image = "new_image"; str_new_image.append(to_string(g_lImageCount++)); str_new_image.append(".jpg"); return str_new_image; } //提取出子影像文件bool ld_yjt_sub_image::extract_sub_image(const string& src_image, vector& vec_sub_image){ Mat src_mat = imread(src_image); if (src_mat.empty()) { m_strErrMsg.Format("打开影像文件[%s]失败", src_image.c_str()); return false; } vector<vector<Point>> evc_contours; if (!getContours(src_mat, evc_contours)) return false; for (int i = 0; i < evc_contours.size(); i++) { //获取区域坐标 Rect rt = boundingRect(evc_contours[i]); //获取倾斜角度 RotatedRect rotate = minAreaRect(evc_contours[i]); //如果角度超过5度,就需要做旋转 float angle = rotate.angle; if (abs(angle) > 5) { cout << "倾斜角度大于5度" << endl; //获取矩形的四个坐标点 Point2f rectpoint[4]; rotate.points(rectpoint); //计算两条边的长度 int line1 = sqrt((rectpoint[1].y - rectpoint[0].y)*(rectpoint[1].y - rectpoint[0].y) + (rectpoint[1].x - rectpoint[0].x)*(rectpoint[1].x - rectpoint[0].x)); int line2 = sqrt((rectpoint[3].y - rectpoint[0].y)*(rectpoint[3].y - rectpoint[0].y) + (rectpoint[3].x - rectpoint[0].x)*(rectpoint[3].x - rectpoint[0].x)); //为了让正方形横着放,所以旋转角度是不一样的 if (line1 > line2) // angle = 90 + angle; //直接克隆一个矩阵 Mat warp_mat = src_mat(rt).clone(); //计算绕图像中点顺时针旋转50度缩放因子为0.8的旋转矩阵 Point center = Point(warp_mat.cols / 2, warp_mat.rows / 2); double scale = 1; //通过上面的旋转细节信息求得旋转矩阵 Mat rot_mat = getRotationMatrix2D(center, angle, scale); //旋转已扭曲图像 warpAffine(warp_mat, warp_mat, rot_mat, warp_mat.size()); //imshow("warp_mat", warp_mat); //再次提取轮廓 vector<vector<Point>> evc_warp_contours; if (!getContours(warp_mat, evc_warp_contours)) return false; for (int j = 0; j<evc_warp_contours.size(); j++) { //获取区域坐标 Rect warp_rt = boundingRect(evc_warp_contours[j]); string ImageName = getNewImage(); imwrite(ImageName, warp_mat(warp_rt)); vec_sub_image.push_back(ImageName); } waitKey(0); } else { cout << "倾斜角度小于5度" << endl; /// 设置目标图像的大小和类型与源图像一致 Mat warp_dst = Mat::zeros(src_mat.rows, src_mat.cols, src_mat.type()); warp_dst.setTo(cv::Scalar(100, 0, 0)); src_mat(rt).copyTo(warp_dst); string str_new_image = getNewImage(); imwrite(str_new_image, warp_dst); vec_sub_image.push_back(str_new_image); } } }

优秀的个人博客,低调大师

Hadoop的MapReduce执行流程图

Hadoop的MapReduce shuffle过程,非常重要。只有熟悉整个过程才能对业务了如指掌。 MapReduce执行流程 输入和拆分: 不属于map和reduce的主要过程,但属于整个计算框架消耗时间的一部分,该部分会为正式的map准备数据。 分片(split)操作: split只是将源文件的内容分片形成一系列的 InputSplit,每个 InputSpilt 中存储着对 应分片的数据信息(例如,文件块信息、起始位置、数据长度、所在节点列表…),并不是将源文件分割成多个小文件,每个InputSplit 都由一个 mapper 进行后续处理。 每个分片大小参数是很重要的,splitSize 是组成分片规则很重要的一个参数,该参数由三个值来确定: minSize:splitSize 的最小值,由 mapred-site.xml 配置文件中 mapred.min.split.size 参数确定。 maxSize:splitSize 的最大值,由 mapred-site.xml 配置文件中mapreduce.jobtracker.split.metainfo.maxsize 参数确定。 blockSize:HDFS 中文件存储的快大小,由 hdfs-site.xml 配置文件中 dfs.block.size 参数确定。 splitSize的确定规则:splitSize=max{minSize,min{maxSize,blockSize}} 数据格式化(Format)操作: 将划分好的 InputSplit 格式化成键值对形式的数据。其中 key 为偏移量,value 是每一行的内容。 值得注意的是,在map任务执行过程中,会不停的执行数据格式化操作,每生成一个键值对就会将其传入 map,进行处理。所以map和数据格式化操作并不存在前后时间差,而是同时进行的。 2)Map 映射: 是 Hadoop 并行性质发挥的地方。根据用户指定的map过程,MapReduce 尝试在数据所在机器上执行该 map 程序。在 HDFS中,文件数据是被复制多份的,所以计算将会选择拥有此数据的最空闲的节点。 在这一部分,map内部具体实现过程,可以由用户自定义。 3)Shuffle 派发: Shuffle 过程是指Mapper 产生的直接输出结果,经过一系列的处理,成为最终的 Reducer 直接输入数据为止的整个过程。这是mapreduce的核心过程。该过程可以分为两个阶段: Mapper 端的Shuffle:由 Mapper 产生的结果并不会直接写入到磁盘中,而是先存储在内存中,当内存中的数据量达到设定的阀值时,一次性写入到本地磁盘中。并同时进行 sort(排序)、combine(合并)、partition(分片)等操作。其中,sort 是把 Mapper 产 生的结果按照 key 值进行排序;combine 是把key值相同的记录进行合并;partition 是把 数据均衡的分配给 Reducer。 Reducer 端的 Shuffle:由于Mapper和Reducer往往不在同一个节点上运行,所以 Reducer 需要从多个节点上下载Mapper的结果数据,并对这些数据进行处理,然后才能被 Reducer处理。 4)Reduce 缩减: Reducer 接收形式的数据流,形成形式的输出,具体的过程可以由用户自定义,最终结果直接写入hdfs。每个reduce进程会对应一个输出文件,名称以part-开头。 欢迎补充。 本文转自 ChinaUnicom110 51CTO博客,原文链接:http://blog.51cto.com/xingyue2011/1969662

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册