因为需要,之前写了一个利用mask 得到不规则ROI 区域的程序。

现在需要修改,发现自己都看不懂是怎么做的了。。

所以把它整理下来。


首先利用 鼠标可以得到 你想要的不规则区域的 顶点信息。具体这里不再描述。

setMouseCallback("setROIParking_Image", on_MouseHandle, (void*)&SrcImage);

得到不规则区域的顶点之后之后,接下来生成mask.

具体程序如下

    void Image::GetROImage()
{
Mat srcImage = imread(srcImageName);
for (int j = 0; j < ROInumber; j++)
{
Point root_points[1][4];
root_points[0][0] = DrawPoints[j*4];
root_points[0][1] = DrawPoints[j*4 + 1];
root_points[0][2] = DrawPoints[j*4 + 2];
root_points[0][3] = DrawPoints[j*4 + 3]; const Point* ppt[1] = { root_points[0] };
int npt[] = { 4 };
// polylines(srcImage, ppt, npt, 1, 1, Scalar(0, 0, 0), 1, 8, 0); vector <Mat>mv;
cv::Mat mask_ann, dst,dst1,dst2;
srcImage.copyTo(mask_ann);
mask_ann.setTo(cv::Scalar::all(0));
fillPoly(mask_ann, ppt, npt, 1, Scalar(255, 255, 255));
split(mask_ann, mv);
srcImage.copyTo(dst, mv[0]);
vector<Point> rectPoints = {}; //得到rectangle 的角点
rectPoints.push_back(DrawPoints[j * 4]);
rectPoints.push_back(DrawPoints[j * 4 +1]);
rectPoints.push_back(DrawPoints[j * 4 +2]);
rectPoints.push_back(DrawPoints[j * 4 +3]);
Rect rec = boundingRect(Mat(rectPoints));
dst1 = dst(rec); //boundingRect(Mat(rectPoints)) //得到rectROImage
if (dst1.cols >= 160)
{
resize(dst1, dst2, Size(160, 120),0,0,3); //得到rectROImage_resize //降采样
}
else
{
resize(dst1, dst2, Size(160, 120),0,0,1);//放大
}
//默认为线性插值 INTER_NEAREST = 0(最近邻插值),
//INTER_LINEAR = 1(线性插值,默认值),
//INTER_CUBIC = 2(三次样条插值),INTER_AREA = 3(区域插值);INTER_LANCZOS4 = 4(Lanczos插值),
//INTER_MAX = 7, WARP_FILL_OUTLIERS = 8,
//降采样:3, 放大:2(效率不高,不推荐);1(效率高,推荐)
imwrite(ROImageNames[j], dst);
imwrite(rectROImageNames[j], dst1);
imwrite(rectROImageNames_resize[j], dst2);
imwrite(rectROImageNames_resize_[j], dst2);
}
}

我这里写的可能有些冗余,主要自己有点的也不是太懂,就根据自己的需要一点点添加得到自己想要的效果。

其中,DrawPoints里存储了不规则区域的顶点(我这里设定了是不规则四边形)。首先是 生成mask(我这里是mask_ann),

             srcImage.copyTo(mask_ann);
mask_ann.setTo(cv::Scalar::all(0));

这一部分是生成和原图一样大小的mask 图像,然后将整个图像用黑色填充。

         const Point* ppt[1] = { root_points[0] };
int npt[] = { 4 };
fillPoly(mask_ann, ppt, npt, 1, Scalar(255, 255, 255));

这一部分是在mask 图像中将不规则区域的部分用白色填充,参考:http://blog.csdn.net/billbliss/article/details/43968291 可以看一下效果

    vector <Mat>mv;
split(mask_ann, mv);
srcImage.copyTo(dst, mv[0]);

我添加的这一部分代码,是跟通道分离有关,具体 也不是特别清楚。但是在我没有添加这一句时,最后得到的图像 有问题(会得到一个不规则ROI区域,但是不是自己想要的那一部分)。split 函数是将mask_ann的三个通道分别赋值给 mv . 因为这里的 mask_ann 是三通道的,而且三通道应该是一样的,我们后面利用mask得到想要的不规则区域时只用到的他的一个通道。mv[0] 即它的一个通道。

后面的

        srcImage.copyTo(dst, mv[0]);

即得到想要的不规则区域。即除了不规则区域,其他区域全部为黑色。

    Rect rec =  boundingRect(Mat(rectPoints));
dst1 = dst(rec); //boundingRect(Mat(rectPoints)) //得到rectROImage

是我从上面得到的部分中进一步的裁剪,把多余的黑色去掉,提取出了以 ROI 区域为边界的的图片(规则四边形,周围区域用黑色填充,因为如果ROI区域太小,得到的图片中大部分都是黑色,所以进一步裁剪)。

因为我想得到最终 尺寸一样的图像,所以利用resize进行了 升降采样。

C++ 中利用 Opencv 得到不规则的ROI 区域(已知不规则区域)的更多相关文章

  1. MFC中利用Opencv与C++抓取摄像头进行人脸识别(Mat)

    原文:http://blog.csdn.net/mr_curry/article/details/51098311 第一次写博客哈哈,有些小激动,还请各位大神多多包涵~ 最近的项目需要用到人脸识别,作 ...

  2. OpenCV - Android Studio 2.2 中利用CAMKE进行OpenCV的NDK开发

    我在http://www.cnblogs.com/fx-blog/p/8206737.html一文中提到了如何在Android Studio中Java层导入OpenCV(包含opencv_contri ...

  3. 在OpenCV中利用鼠标绘制矩形和截取图像的矩形区域

    这是两个相关的程序,前者是后者的基础.实际上前一个程序也是在前面博文的基础上做的修改,请参考<在OpenCV中利用鼠标绘制直线> .下面贴出代码. 程序之一,在OpenCV中利用鼠标绘制矩 ...

  4. 利用OpenCV检测图像中的长方形画布或纸张并提取图像内容

    基于知乎上的一个答案.问题如下: 也就是在一张照片里,已知有个长方形的物体,但是经过了透视投影,已经不再是规则的长方形,那么如何提取这个图形里的内容呢?这是个很常见的场景,比如在博物馆里看到一幅很喜欢 ...

  5. 在MacOS和iOS系统中使用OpenCV

    在MacOS和iOS系统中使用OpenCV 前言 OpenCV 是一个开源的跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法. 最近试着在 MacOS 和 iOS 上使用 OpenCV ...

  6. 如何利用OpenCV自带的级联分类器训练程序训练分类器

    介绍 使用级联分类器工作包括两个阶段:训练和检测. 检测部分在OpenCVobjdetect 模块的文档中有介绍,在那个文档中给出了一些级联分类器的基本介绍.当前的指南描述了如何训练分类器:准备训练数 ...

  7. 如何在Android中使用OpenCV

    如何在Android中使用OpenCV 2011-09-21 10:22:35 标签:Android 移动开发 JNI OpenCV NDK 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始 ...

  8. [转]在MacOS和iOS系统中使用OpenCV

    OpenCV 是一个开源的跨平台计算机视觉库,实现了图像处理和计算机视觉方面的很多通用算法. 最近试着在MacOS和iOS上使用OpenCV,发现网上关于在MacOS和iOS上搭建OpenCV的资料很 ...

  9. opencv探索之路(十二):感兴趣区域ROI和logo添加技术

    在图像处理领域,有一个非常重要的名词ROI. 什么是ROI? 它的英文全称是Region Of Interest,对应的中文解释就是感兴趣区域. 感兴趣区域,就是我们从图像中选择一个图像区域,这个区域 ...

随机推荐

  1. 5Linux流程控制语句-if、for、while、case语句、计划任务

    流程控制语句.计划任务服务程序,今天记录的有点乱,在预习的时候就记了挺多了,书都花了,上几张图. for 循环      →指定一定的范围 while 循环 →指定一定的条件   for循环语句允许脚 ...

  2. EL表达式与JSTL标签map遍历varStatus属性下标使用

    在JSP页面开发中,JSTL标签库迭代标签<c:forEach>为我们迭代遍历数组集合提供了一种选择. 遍历过程中varStatus属性为我们遍历集合提升了很大操作空间. 贴一下具体使用 ...

  3. neo4j性能调优(转)

    最近在公司实习做的就是优化neo4j图形数据库查询效率的事,公司提供的是一个在Linux上搭建且拥有几亿个节点的数据库.开始一段时间主要是熟悉该数据库的一些基本操作,直到上周才正式开始步入了优化数据库 ...

  4. Linux 用户与组

    在 Linux 操作系统下,如何添加一个新用户到一个特定的组中?如何同时将用户添加到多个组中?又如何将一个已存在的用户移动到某个组或者给他增加一个组?对于不常用 Linux 的人来讲,记忆 Linux ...

  5. 数据仓库系列 - 缓慢渐变维度 (Slowly Changing Dimension) 常见的三种类型及原型设计

    在从 OLTP 业务数据库向 DW 数据仓库抽取数据的过程中,特别是第一次导入之后的每一次增量抽取往往会遇到这样的问题:业务数据库中的一些数据发生了更改,到底要不要将这些变化也反映到数据仓库中?在数据 ...

  6. pandas的简单使用

    pandas可以对数据进行整理分析 因为要对excel中的源数据进行分组和处理,所以想到用pandas来处理.试用过确实比自己去读写快捷很多 (实际pandas底层也是用xlrd,xlwt两个第三方包 ...

  7. activemq stomp类

    此库用来增强ide,能对stomp类进行自动提示 <?php class Stomp { /** * 构造器 * Stomp constructor. * @param string $brok ...

  8. 20175126《Java程序设计》第九周学习总结

    # 20175126 2016-2017-2 <Java程序设计>第九周学习总结 ## 教材学习内容总结 - 本周学习方式主要为手动敲代码并理解内容学习. - 学习内容为教材第十一章,本章 ...

  9. BootStrap布局组件

    BootStrap字体图标(Glyphicons) BootStrap下拉菜单:下拉菜单是可以切换的,是以列表格式显示链接的上下文菜单. 类 描述 .dropdown 指定下拉菜单 .dropdown ...

  10. 关于HTML5中的sessionStorage的会话级缓存使用

    sessionStorage作为HTML5的Web Storage的两种存储方式之一.    用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数 ...