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

每句话都有注释,简单易懂不是吗。由于这里提前引用了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;
}

总之最后的效果应该是这样的:

简单说明一下:

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(319,480,CV_8UC3,Scalar(255,0,0));
//这样写:
Mat image3(image.size(),CV_8UC3,Scalar(0,255,0));
//或者这样写:
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通道值。接着再存第二个像素,第三个像素……

恩,好像就说这么多已经足够了,其余的用法等进阶学习以后边用边学就行,有什么遗漏的话以后再重新编辑博文吧。得赶快结束了,我发现这篇文章已经有点太长了……

时间: 2024-08-25 10:45:10

OpenCV2+入门系列(二):图像的打开、创建与显示(命令行)的相关文章

Maven入门系列(二)--设置中央仓库的方法

原文地址:http://www.codeweblog.com/maven入门系列-二-设置中央仓库的方法/ Maven仓库放在我的文档里好吗?当然不好,重装一次电脑,意味着一切jar都要重新下载和发布. 下载的地址是中央仓库mvnrepository.com,当然,全球很多个仓库. 资源的坐标简称GVA 那么,现在如何修改maven的本地仓库路径呢? 关键在于maven文件夹的config下的settings.xml(E:\IDE\apache-maven-3.3.1\conf\settings

C# 互操作性入门系列(二):使用平台调用调用Win32 函数

好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------------------------------------------------------------------- C#互操作系列文章: C#互操作性入门系列(一):C#中互操作性介绍 C#互操作性入门系列(二):使用平台调用调用Win32 函数 C#互操作性入门系列(三):平台调用中的数据封

windows下mongodb基础玩法系列二CURD操作(创建、更新、读取和删除)

windows下mongodb基础玩法系列 windows下mongodb基础玩法系列一介绍与安装 windows下mongodb基础玩法系列二CURD操作(创建.更新.读取和删除) 简单说几句 在mongodb中3元素:db(数据库).collection(集合).document(文档) 其中collection类似于数据库中的表,document类似于行,这样一来我们就将内容对比起来记忆学习了. 数据格式 MongoDB documents是BSON格式(一种类json的一种二进制形式的存

C语言快速入门系列(二)

C语言快速入门系列(二) 本节引言: 在前面一节中我们对C语言进行了初步的了解,学会了使用IDE进行代码的编写,编译运行! 在这一节中我们会对C语言的基本语法进行进一步的学习! C语言是一门语言,可以和英语进行类比,英语句子 = 单词 + 语法 同样C语言的代码语句,也有着一套自己的规则! 废话不多说,直接正文! 本节学习路线图: 正文: 1.基本字符集 1.1 标识符 ①何为标识符:在C语言中,符号常量,变量,数组,函数等都需要一定的名称,我们把这种名称成为标识符 ②标识符的命名规则 答:只能

IBM规则引擎(ODM)入门系列二:Rule Execution Server(RES)服务安装

今天开始了ODM入门系列之二,在这个系列中我会讲讲规则执行服务的搭建安装,规则集的打包发布以及如何将部署之后的规则集发布为web服务,供其他服务或应用使用. 首先,我们先看一幅图: 这是我画的一张ODM各组件之间关系,其中WEB APP是我们自己的项目或应用,可以通过web服务的形式来调用RES上已经部署的RuleApp包来执行规则. 再来看一张图: (截屏自IBM官网) 这是IBM官网上的一张介绍ODM不同组件如何交互的一张图. 从这两张图都可以看出RES在ODM整个产品中都起着一个非常重要的

ActiveMQ入门系列二:入门代码实例(点对点模式)

在上一篇<ActiveMQ入门系列一:认识并安装ActiveMQ(Windows下)>中,大致介绍了ActiveMQ和一些概念,并下载.安装.启动他,还访问了他的控制台页面. 这篇,就用代码实例说下如何实现消息的生产和消费. 一.理论基础 同RabbitMQ一样,ActiveMQ中也是有两种模式: 点对点模式(Point to Point,简写为PTP) 发布/订阅模式(Publish & Subscribe,简写为Pub & Sub) 通过上一篇我们知道了制造消息的应用叫生产

Hive 系列(三)—— Hive CLI 和 Beeline 命令行的基本使用

一.Hive CLI 1.1 Help 使用 hive -H 或者 hive --help 命令可以查看所有命令的帮助,显示如下: usage: hive -d,--define <key=value> Variable subsitution to apply to hive commands. e.g. -d A=B or --define A=B --定义用户自定义变量 --database <databasename> Specify the database to use

前端技术之:如何创建一个NodeJs命令行交互项目

方法一:通过原生的NodeJs API,方法如下: #!/usr/bin/env node # test.js var argv = process.argv; console.log(argv) 通过以下命令执行: node test.js param1 --param2 -param3 结果输出如下: [ '/usr/local/Cellar/node/10.10.0/bin/node', 'test.js', 'param1', '--param2', '-param3' ] 可见,arg

iOS开发入门 ? C语言(字符串、字符串数组、命令行参数)

字符串 1. 概念 用双引号引起来的就是字符串 "a string" //C语言编译器会将两个并列的字符串自动拼接成一个字符串 "a string""another a string" // \是换行连接的标记(一行不够写) "a looooooooooong \ string" 常见ASCII编码: 'A' == 65    'a' == 97    '0' == 48    '\0' == 0 int a[10]; //表