图像的构成、创建、读取、访问

lena.jpg

前言

我是人工智障,一名程序猿。做过嵌入式、爬虫,目前在自学计算机视觉 。注册 「命运探知之魔眼」(名字取自影视作品「命运石之门」)这个公号已有些日子,真正有心将它运营起来是看到朋友狗哥运营它的公号

「一个优秀的废人」

之后。注册这个号的初衷是分享我的 计算机视觉 学习笔记,希望更多的人加入我的行业,杜撰一下希特勒的话:「我们每写一行代码,都在改变着世界的版图」。

图像是什么

人类看到图像的原理(引用维基百科):

物体发来的光线经过眼的折光系统,一般会在视网膜上形成像,被感光细胞感到。

感光细胞受刺激后将其刺激的形态传递到大脑,大脑的不同部分平行工作产生图像的概念。

数字图像的形成原理与人类解析到图像的原理相似,数字图像是连续的光信号经过传感器的采样在空间域上的表达。一张图像是由一个包含若干个像素点的矩形框组成的,试着把一张图在“画图”软件中放大会有更直观的感受,下面是lena图放大后的效果。

lena放大图

可以看到图像是由很多个小格子组成的,每个小格子都只有一种颜色,这是构成图像的最小单元——像素(pixel)。不同的像素值代表了不同的颜色,像素值的值域一般在0到255(包括)之间,也就是256个整数,因此可以用完整个unsigned char类型的值域,所以像素值一般都是用unsigned char类型表示。

图像的颜色

但0-255并不能映射到像上图所示的彩色,而只是对应黑色到白色之间的灰度值(grayscale),如下图:

灰度值

人类看到彩色也是需要3种视锥细胞,分别感受红绿蓝不同的颜色,缺失某种细胞则会造成不同的色盲。要表示彩色像素,先回忆初中物理学的三原色,红绿蓝(RGB),饱和的红绿蓝三种颜色叠加起来就是白色,假如其中一种颜色不那么“饱和”则可以表示其他的颜色,调节三种颜色的比例则可以表示我们常看到的24位色。灰度值的颜色空间在几何上可以用一根直线表示,而RGB彩色空间在几何上则对应了一个立方体,如下图:

RGB

因此,要表示彩色值,我们需要3个维度,也就是3个图像通道,每个像素值用3个数字表示,如(255,255,255)表示白色,(255,0,0)表示红色,(255,255,0)表示黄色。

图像的坐标系

像素在图像上的排布使用左手坐标系,原点在左上角,如下图:

图像坐标系

代码

在OpenCV的python库中读取和访问图像的示例代码如下:

运行结果:

运行结果PS:对于上面的代码,如果从第一行开始就看不懂,建议先补习 Python 基础,参考这个公号「一个优秀的废人」。

如果还是有点感觉的,请继续往下看。

首先

是导入 OpenCV 库,我们要学的所有函数都在这个库里面。

numpy 是一个科学计算库,如果你是电子相关专业的学生,应该有学过 Matlab ,numpy 的功能就跟 Matlab 类似,能够表达矩阵和矩阵相关的操作,图像的数据结构就是 numpy.array 。

main 函数里面的第一行,我们从磁盘上读取了一幅图 lena.jpg 。

cv2.imread 参数:

cv2.imread (图像路径,格式标志),

其中第一个参数是必须的,是相对于工作路径的图片的地址;

第二个参数有三种可以取的值,分别是:

cv2.IMREAD_COLOR

cv2.IMREAD_GRAYSCALE

cv2.IMREAD_UNCHANGED

默认不填就是 cv2.IMREAD_COLOR ,也就是把图片当作彩图读入。

cv2.IMREAD_GRAYSCALE 也就是把图片读入后转换成灰度图,这个值也等于0,使用的时候可以直接写 cv2.imread(img_path, 0)。

cv2.IMREAD_UNCHANGED 是原封不动的读取,图片该是怎样就怎样读。

cv2.imread 返回值:

cv2.imread 的返回值是一个 numpy.array 结构,相当于一个矩阵,矩阵的维度信息、具体每一个数据都能获取到。

注意:如果图像读取失败,例如传入的路径不对或者图片损坏,返回值是 None ,如果需要健壮的处理请务必加上这个判断。

numpy.array:

img.shape 就是获取维度,对应的是 Python 的元组( tuple )在这里,因为是彩色图,所以 tuple 有 3 个元素,如果是灰度图,则只有两个元素,您可以自行测试。在实际使用中如果得到了一幅不知道是彩图还是灰度图的 img ,就可以用 if len(img.shape) == 3 这样的方法去判断。

看上面的运行结果,输出的 img.shape 是 (512L, 512L, 3L),这个 L 表示长整型,可以把它忽略。我们就说这是一幅 512x512x3 大小的图,其中第一个 512 表示图像的高度,第二个 512 表示图像的宽度, 第三个 3 就是前面说的表示它是彩色图,也就是通常所说的通道数

3 个通道是因为上面讲图像的颜色的时候,我们说了彩色图的一个像素值要用 3 个数字表示,所以再看回运行结果的第二行,打印 img[0,0] 的时候就输出了一个 3 元素的list —— [128 138 255],其中第一个通道是对应的蓝色通道,第二个通道是绿色,第三个是红色,也就是通常所说的BGR排列。

numpy.array 与 Matlab 中的矩阵很相似,也支持多个数据同时访问,如 img[0, :] 可以表示图像的第一行所有像素、img[…, 0] 可以表示图像的第一个通道所有像素。

图像的显示

如果要显示上面的图像,就要使用 cv2.imshow 函数,在上面贴的代码中没有写,可以自行测试。

cv2.imshow:

接收两个参数:(窗口名,图像)

如 cv2.imshow('LENA',img) 就会显示一个名称是 LENA 的窗口,内容是 lena 图。

如果急着进行这一步就运行的话可能会看到有个一闪而过的窗口,然后程序就结束了,因为窗口必须要有阻塞才会显示,阻塞的方法我们可以让程序等待,这就用到了 cv2.waitKey 函数。

cv2.waitKey:

接收 1 个参数: 等待时间(单位是毫秒(ms),1000 ms = 1 s)。

返回值是用户按下的键值,我通常的用法是:

这里我传入的参数是 0,表示一直等待,直到我按下 Q 键让它退出。

显示出来的效果是这样的:

显示效果

后语

我不是大神,不是什么牛人,于 计算机视觉 领域来说,我是菜鸡,但谁刚开始接触一个领域的时候不是菜鸡呢。 写这个号的目的是为了记录我自学 计算机视觉 的笔记。

如果本文对你哪怕有一丁点帮助请右下角点赞,否则忽略就好。平时工作也是在做计算机视觉,希望大家多多指教。

我一直认为学习不能有所见即所得的想法,一看就会,一做就错。千万不要偷懒,所谓大神都是一个一个坑踩过来的。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180724G1LK9V00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券