OpenCV2+入门系列(二):图像的打开、创建与显示(命令行)
前置知识:数字图像的简略知识
这里只是最基础的知识,上课如果稍微听了课的同学可以直接略过不不看。
彩色图像:
对于一副数字图像,对于一副RGB色彩空间的彩色数字图像,它一共有宽X高个像素格子,每个格子的色彩由蓝色、绿色、红色三个原色合成,很简单吧,三原色的合成大家小学就学过喽。计算机中B、G、R三个值可以从0至255选择,不同的值的组合就可以合成出不同的色彩,一般来说总共可以组成255*255*255种色彩。
灰度图像:
而若是图像中所有像素都是由黑到白(0到255)的亮度表示,那么这幅图像将是一副只有灰色的图像(想象一下黑白照片)。
二值图像:
在灰度图像中,把所有亮度大于某个值(二值化阈值)的像素点的亮度设置为255,其余的设置为0,那么就得到了二值图像,它将是只有黑色与白色两种颜色的图像,类似于黑白木刻画。
1.图像的打开
假设大家在C++编程上已经有所建树,而且也大致了解了类、对象、命名空间,那么为了使用OpenCV的相关函数,首先要添加相应的头文件。我们将core.hpp,highgui.hpp添加,并且引用cv这个命名空间。
1.1 打开现有图片
OpenCV 2+版本中图像的存储类型为Mat型,载入图像的函数为imread,显示图像的函数为imshow,很简单吧,只需要几个函数你就可以写出一个图片浏览器(笑~)。
因为太简单了,所以直接放代码:
- #include "stdafx.h"
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- using namespace cv;
- int main() {
- Mat image = cv::imread("img.jpg");//读取img.jpg到image中,此处可以写相对路径也可以写绝对路径
- namedWindow("图片1");//定义一个名为“图片1”的窗口
- imshow("图片1", image);//在窗口“图片1”中显示image
- waitKey();//等待按键
- return ;
- }
每句话都有注释,简单易懂不是吗。由于这里提前引用了cv这个namespace,所以不必每句话前加一个"cv:",否则你将看到这样的代码:
- #include "stdafx.h"
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- int main() {
- cv::Mat image = cv::imread("img.jpg");//读取img.jpg到image中,此处可以写相对路径也可以写绝对路径
- cv::namedWindow("图片1");//定义一个名为“图片1”的窗口
- cv::imshow("图片1", image);//在窗口“图片1”中显示image
- cv::waitKey();//等待按键
- return ;
- }
总之最后的效果应该是这样的:
简单说明一下:
1 Mat类型是OpenCV2中用于保存图像或者矩阵信息的数据结构。初始化时可以用上面的方法,直接imread一张图片,也可以指定初始尺寸和初始色彩,这个我们之后再说。
2 通过imread函数,我们可以从指定的路径加载一张图片到内存中(存为Mat型变量)。它的函数原型为:
可以知道它有一个默认参数flags = 1,它表示程序打开的图像默认为三通道的(即BGR三通道),为彩色图像,如果在调用函数时设置flags = 0,那么就会把图像加载成灰度图像(单通道)。当它设置为-1,2,4时都还有另外的意义,不过更详细的函数说明你就要出门左转去看OpenCV的官方手册了,毕竟我这文章也不是文档翻译对吧。
当然有时候你无法确定自己指定的图片是否能够被顺利打开(图片不存在、图片损坏等),因此在使用打开的图像时,最好判断一下图像是否正确读取了,就像这样。
- Mat image = imread("img.jpg",CV_LOAD_IMAGE_COLOR);//读取img.jpg到image中,此处可以写相对路径也可以写绝对路径
- if(!image.data)
- {
- //do something图片没有被读取成功
- }
3 在使用imshow函数显示图像之前,记得一定要先用namedWindow定义一个窗口,窗口参数可以设置大小、位置、缩放等,具体也请去看官方文档。
1.2在内存中创建图像
OK,当然除了从文件读取图像外,我们还可以直接在计算机内存中创建一副图像。我们是这样做的,如图,在定义一个Mat变量时有24种重载可以用来指定变量的初始值。
- //你可以这样写:
- Mat image2(,,CV_8UC3,Scalar(,,));
- //这样写:
- Mat image3(image.size(),CV_8UC3,Scalar(,,));
- //或者这样写:
- Mat image4(image);
第一种写法表示创建一副宽480,高319的8位3通道彩色图像,颜色为255的蓝色。代码中CV_8UC3是一个宏定义,表示的就是8位3通道彩色图像,类似的宏定义还有CV_8U,它表示的是八位灰度图像。Scalar(255,0,0)表示的是创建图像的颜色,三个数字分别表示BGR通道。
第二种写法表示的是创建一个image一样大的绿色图像。
第三章写法则表示直接复制了一个image图像到image4的内存空间。
二、Mat对象的存储格式(简略)
本节很重要,只有了解了Mat变量才能很好的操作图像!
本节很重要,只有了解了Mat变量才能很好的操作图像!
因为很重要,所以说两遍,可是如果要详细说Mat的话,估计一整篇文章都不够,所以这里只能简略的讲讲。
Mat类是用于保存图像的数据结构,它的默认尺寸为0,载入图像数据的方法在上文中已经说了,忘记的同学赶快回去复习。Mat对象在离开作用域以后会其分配的内存会自动被释放,终于不用像以前那样cvRelease图像了。以下是Mat类的简略结构:
- Mat
- {
- public:
- / / … …很多的方法...
- ...
- /*!包括几位字段:
- -神奇的签名
- -连续性标志
- -深度(Note:应该是位深)
- -通道数
- */
- int flags;(Note :目前还不知道flags做什么用的)
- //!数组的维数,> = 2
- int dims ;
- //!行和列的数量或 (-1,-1) 此时数组已超过 2 维
- int rows,cols;
- //!指向数据的指针
- uchar *data ;
- //!指针的引用计数器 ;
- / / 阵列指向用户分配的数据时,当指针为 NULL
- int * refcount ;
- / / 其他成员
- ...
- };
Mat.step定义了数据布局,它代表了图像一行的像素占据的数据长度。而Mat. Data则指向了数组数据的开头,还有一个Mat.elemSize()将返回数组元素的长度。因此第N行第M列的数据可以这样来取,公式并不难理解。
Data = Mat.data + (N - 1)×Mat.step + (M - 1)×Mat.elemSize();
Mat. channels()则表示图像的通道数目,若为灰度图像,那么数据的存放没什么好说的,第一行一个个像素一次排下去,然后是第二行、第三行。如果是三通道,则先存第一个像素的B通道值、然后是G通道值、最后是R通道值。接着再存第二个像素,第三个像素……
恩,好像就说这么多已经足够了,其余的用法等进阶学习以后边用边学就行,有什么遗漏的话以后再重新编辑博文吧。得赶快结束了,我发现这篇文章已经有点太长了……
OpenCV2+入门系列(二):图像的打开、创建与显示(命令行)的更多相关文章
- Maven入门系列(二)--设置中央仓库的方法
原文地址:http://www.codeweblog.com/maven入门系列-二-设置中央仓库的方法/ Maven仓库放在我的文档里好吗?当然不好,重装一次电脑,意味着一切jar都要重新下载和发布 ...
- C# 互操作性入门系列(二):使用平台调用调用Win32 函数
好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...
- [转]C# 互操作性入门系列(二):使用平台调用调用Win32 函数
传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...
- [Unity3D插件]2dtoolkit系列二 动画精灵的创建以及背景图的无限滚动
经过昨天2dtoolkit系列教程一的推出,感觉对新手还有有一定的启发作用,引导学习使用unity 2dToolKit插件的使用过程,今天继续系列二——动画精灵的创建,以及背景图的无限循环滚动,在群里 ...
- mybatis入门系列二之输入与输出参数
mybatis入门系列二之详解输入与输出参数 基础知识 mybatis规定mapp.xml中每一个SQL语句形式上只能有一个@parameterType和一个@resultType 1. 返回 ...
- windows下mongodb基础玩法系列二CURD操作(创建、更新、读取和删除)
windows下mongodb基础玩法系列 windows下mongodb基础玩法系列一介绍与安装 windows下mongodb基础玩法系列二CURD操作(创建.更新.读取和删除) windows下 ...
- C语言高速入门系列(二)
C语言高速入门系列(二) -----转载请注明出处coder-pig 本节引言: 在前面一节中我们对C语言进行了初步的了解,学会了使用IDE进行代码的编写,编译执行! 在这一节中我们会对C语言的基本的 ...
- 如何创建一个基于命令行工具的跨平台的 NuGet 工具包
命令行可是跨进程通信的一种非常方便的手段呢,只需启动一个进程传入一些参数即可完成一些很复杂的任务.NuGet 为我们提供了一种自动导入 .props 和 .targets 的方法,同时还是一个 .NE ...
- 在 Mac OS X 上创建的 .NET 命令行程序访问数据库 (使用Entity Framework 7 )
var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...
随机推荐
- CDN技术详解
CDN,全称为Content DeliveryNetwork,中文意为"内容分发网络"".通过将网络内容发布到最靠近用户的『边缘节点』,使不同地区的用户在访问相同页面.图 ...
- U家面试prepare: Serialize and Deserialize Tree With Uncertain Children Nodes
Like Leetcode 297, Serialize and Deserialize Binary Tree, the only difference, this is not a binary ...
- 虚拟机下CentOS 6.5配置IP地址的三种方法
实验软件环境:虚拟机Vmware Workstation10.0 .CentOS 6.5 32位 1.自动获取IP地址 虚拟机使用桥接模式,相当于连接到物理机的网络里,物理机网络有DHCP服务器自动分 ...
- position
1.父集设置了relative,子集的absolute要设置top和left的值,不然父集的padding值会影响到子集的位置: #first{ width: 200px; height: 100px ...
- mysql 日期加减操作
1. MySQL 为日期增加一个时间间隔:date_add() set @dt = now(); select date_add(@dt, interval 1 day); -- add ...
- Oracle数据库学习笔记
创建表的同时插入数据:create table zhang3 as select * from zhang1;create table zhang3(id,name) as select * from ...
- Android 中如何计算 App 的启动时间?
(转载) 已知的两种方法貌似可以获取,但是感觉结果不准确:一种是,adb shell am start -w packagename/activity,这个可以得到两个值,ThisTime和Total ...
- IIS7 全新管理工具AppCmd.exe的命令使用实例分享
IIS 7 提供了一个新的命令行工具 Appcmd.exe,可以使用该工具来配置和查询 Web 服务器上的对象,并以文本或 XML 格式返回输出. 下面是一些可以使用 Appcmd.exe 完成的任务 ...
- Xcode插件描述
Xcode插件 Xcode是iOS的集成开发环境,虽然苹果一直在不断改进Xcode,但程序员总是有各种新奇的想法和需求,当Xcode无法满足他们时,于是他们就会通过插件的方式来为Xcode增加新的功能 ...
- JAG Summer 2012 Day 4 C Connect
状压dp,由于枚举两维状态会GG,所以只枚举当前位置前m个的状态,就是这个样子大概= =: 呆马: #include <iostream> #include <cstdio> ...