热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OpenCv2.4.9(一)Mat基础结构如何遍历图片

前言因为对图像方面感兴趣,所以有空学学OpenCV的使用,并且希望以此为引子,带领自己入门图像领域。先post上几个参考网站,
前言

 

  因为对图像方面感兴趣,所以有空学学OpenCV的使用,并且希望以此为引子,带领自己入门图像领域。

  先post上几个参考网站,上面有完整源码:

  • http://docs.opencv.org/2.4.9/ (英文文档,主要参看)
  • http://www.opencv.org.cn/opencvdoc/2.3.2/html/index.html (低版本的中文参考)
  • https://github.com/opencv/opencv/tree/master/doc/tutorials (github源码,有些需要参考会英文文档)

  因为这么多资源,所以就不贴完整代码,这重点讲解某部分,方便自己以后回来查询。

 

Mat - 基本的图像容器

Mat

  在以前,opencv使用的是C结构,IplImage。但是使用这个结构有一个缺点就是你需要注意内存的申请和销毁。幸运的是,在C++我们可以使用一种更智能的结构,Mat。Mat会自动申请内存和销毁。

  Mat由基本的两部分组成:矩阵头(包含图片信息,例如矩阵大小,存储方法等)和一个指向包含像素点信息的指针。矩阵头部大小是常数,但是矩阵的大小却各不相同。

1 Mat A, C;  // 只建立头部
2 A = imread(fname, CV_LOAD_IMAGE_COLOR);
3
4 Mat B(A); // 调用copy构造函数
5 C = A; // 调用assign函数

 

  上面的所有对象都指向同一个矩阵,只是头部不一样而已。如果使用其中一个对象改变图像内容,所有指向这个矩阵的对象都会受影响。copy和assign只是复制头部的一些信息。

  我们可以调用其它方法实现深复制:

1 Mat F = A.clone();
2 Mat G;
3 A.copyTo(G);

 

 

显式创建Mat

  我们可以使用 imwrite() 函数来把一个矩阵写入到图片文件。但是为了调试方便&#xff0c;我们还可以使用<<输出&#xff08;仅适用于二维矩阵&#xff09;。

  下面是创建Mat对象的各种方法&#xff1a;

  • Mat()构造器

    1 Mat M(2, 2, CV_8UC3, Scalar(0, 0, 255)); // CV_[多少位][有符号or无符号][类型前缀]C[通道数]
    2 cout <endl;
    3 // [0, 0, 255, 0, 0, 255;
    4 // 0, 0, 255, 0, 0, 255

  • 使用C\C&#43;&#43;数组构造

    1 int sz[3] &#61; {2, 2&#xff0c;2};
    2 Mat L(3, sz, CV_8UC(1), Scalar::all(0)); // 3维的[2, 2, 2]的图像

  • 为已存在IplImage指针构建头部

    1 IplImage* img &#61; cvLoadImage(fname);
    2 Mat mtx(img);

  • Create() 函数

    1 M.create(4, 4, CV_8UC(2)); // 这种方法不能赋初值&#xff0c;只在中心分配内存时使用
    2 cout<

  • Matlab风格的初始化

    1 Mat E &#61; Mat::eye(4, 4, CV_64F);
    2 Mat O &#61; Mat::ones(2, 2, CV_32F);
    3 Mat Z &#61; Mat::zeros(3, 3, CV_8UC1);

  • 逗号分隔的初始化小矩阵

    1 Mat C &#61; (Mat_<double>(3,3) <<0, -1, 0, -1, 5, -1, 0, -1, 0);

  • 使用clone或copyTo。

    1 Mat RowClone &#61; C.row(1).clone(); // randu(RowClone, Scalar::all(0), Scalar::all(255))可以在low和high之间随机

    

怎样遍历图片

 

  首先&#xff0c;我们可以使用一段代码计算程序执行的时间&#xff1a;

1 double t &#61; (double)getTickCount();
2 // do something
3 t &#61; ((double)getTickCount() - t) / getTickFrequency();

 

  

图像的存储

  在RGB系统中&#xff0c;图像是这样存储的&#xff1a;&#xff08;注意是BGR的形式&#xff0c;可以使用 isContinunous() 函数查看是否连续存放&#xff09;

&#xff08;下面以颜色空间缩减为例子说明&#xff09;

C风格的读法

先用指针p指向一行&#xff0c;然后再p[j]形式读取

1 int channels &#61; I.channels();
2 int nRows &#61; I.rows;
3 int nCols &#61; I.cols * channels;
4
5 if (I.isContinuous()) {
6 nCols &#61; nCols * nRows;
7 nRows &#61; 1;
8 }
9
10 int i, j;
11 uchar* p;
12 for (i&#61;0; ii) {
13 for (j&#61;0; jj) {
14 p &#61; I.ptr(i);
15 p[j] &#61; table[p[j]]; //查表替换
16 }
17 }

 

迭代&#xff08;安全&#xff09;方法

迭代器从begin到end&#xff0c;使用(*it)[0]形式读取

const int channels &#61; I.channels();
switch(channels)
{
case 1: {MatIterator_ it, end;for (it &#61; I.begin(), end&#61;I.end(); it !&#61; end; &#43;&#43;it)*it &#61; table[*it];break;}
case 3: {MatIterator_ it, end;for (it &#61; I.begin(), end&#61;I.end(); it !&#61; end; &#43;&#43;it)(*it)[0] &#61; table[(*it)[0]];(*it)[1] &#61; table[(*it)[1]];(*it)[2] &#61; table[(*it)[2]];}
}

 

 通过相关返回值的On-the-fly地址计算

先把矩阵转换成Mat_&#xff0c;再用_I(i, j)[0]形式读取

const int channels &#61; I.channels();
switch(channels)
{
case 1:{for (int i&#61;0; ii)for (int j&#61;0; jj)I.at(i, j) &#61; table[I.at(i, j)];break;}
case 3:{Mat_ _I &#61; I;for (int i&#61;0; ii)for (int j&#61;0; jj) {_I(i, j)[0] &#61; table[_I(i, j)[0]];_I(i, j)[1] &#61; table[_I(i, j)[1]];_I(i, j)[2] &#61; table[_I(i, j)[2]];}I &#61; _I;break;}
}

 

快速实现表替换

Mat lookUpTable(1, 256, CV_8U);
uchar
* p &#61; lookUpTable.data;
for (int i&#61;0; i <256; &#43;&#43;i)p[i] &#61; table[i];
LUT(I, lookUpTable, I);


转:https://www.cnblogs.com/mangoyuan/p/6442631.html



推荐阅读
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文详细解析了 Yii2 框架中视图和布局的各种函数,并综述了它们在实际开发中的应用场景。通过深入探讨每个函数的功能和用法,为开发者提供了全面的参考,帮助他们在项目中更高效地利用这些工具。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 本文详细介绍了一种利用 ESP8266 01S 模块构建 Web 服务器的成功实践方案。通过具体的代码示例和详细的步骤说明,帮助读者快速掌握该模块的使用方法。在疫情期间,作者重新审视并研究了这一未被充分利用的模块,最终成功实现了 Web 服务器的功能。本文不仅提供了完整的代码实现,还涵盖了调试过程中遇到的常见问题及其解决方法,为初学者提供了宝贵的参考。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • 深入解析:Synchronized 关键字在 Java 中对 int 和 Integer 对象的作用与影响
    深入探讨了 `Synchronized` 关键字在 Java 中对 `int` 和 `Integer` 对象的影响。尽管初看此题似乎简单,但其实质在于理解对象的概念。根据《Java编程思想》第二章的观点,一切皆为对象。本文详细分析了 `Synchronized` 关键字在不同数据类型上的作用机制,特别是对基本数据类型 `int` 和包装类 `Integer` 的区别处理,帮助读者深入理解 Java 中的同步机制及其在多线程环境中的应用。 ... [详细]
  • 在HTML布局中,即使将 `top: 0%` 和 `left: 0%` 设置为元素的定位属性,浏览器中仍然会出现空白填充。这个问题通常与默认的浏览器样式、盒模型或父元素的定位方式有关。为了消除这些空白,可以考虑重置浏览器的默认样式,确保父元素的定位方式正确,并检查是否有其他CSS规则影响了元素的位置。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 在ElasticStack日志监控系统中,Logstash编码插件自5.0版本起进行了重大改进。插件被独立拆分为gem包,每个插件可以单独进行更新和维护,无需依赖Logstash的整体升级。这不仅提高了系统的灵活性和可维护性,还简化了插件的管理和部署过程。本文将详细介绍这些编码插件的功能、配置方法,并通过实际生产环境中的应用案例,展示其在日志处理和监控中的高效性和可靠性。 ... [详细]
  • 在优化Nginx与PHP的高效配置过程中,许多教程提供的配置方法存在诸多问题或不良实践。本文将深入探讨这些常见错误,并详细介绍如何正确配置Nginx和PHP,以实现更高的性能和稳定性。我们将从Nginx配置文件的基本指令入手,逐步解析每个关键参数的最优设置,帮助读者理解其背后的原理和实际应用效果。 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • 本文探讨了使用JavaScript在不同页面间传递参数的技术方法。具体而言,从a.html页面跳转至b.html时,如何携带参数并使b.html替代当前页面显示,而非新开窗口。文中详细介绍了实现这一功能的代码及注释,帮助开发者更好地理解和应用该技术。 ... [详细]
author-avatar
刘妤劭明馨
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有