【OpenCV-Python入门书】第二篇 图像与矩阵

很多非科班出身(或是科班但大学没认真学习)的程序员,听到类似“哈希表”、“树/图”、“矩阵”之类的数据结构/数学专业词汇都会觉得头大。
计算机图像处理,矩阵是基础,未来无论多高级的功能都要用到。接下来我会尽量避开数学的东西,用形象的方式来讲。(其实我读书时比大家好不到哪儿去——既非科班出身,又没有认真学习-_-#)。

照例啰嗦完,下面开始。

 

0. 理解矩阵

看一张图:

3x3矩阵

这是一个3x3矩阵(3行3列,行在前列在后),行列索引均从0开始。

1. 代码创建矩阵

cv2 接口开始,OpenCV Python使用 numpy 作为其官方矩阵处理库。运行以下代码以创建上图的矩阵:

import numpy as np
mat = np.array([
    [   0, 100,   0 ],
    [ 100, 255, 100 ],
    [   0, 100,   0 ]])
print(mat)

没错,二维矩阵其实就是个二维数组。

 

2. 矩阵与图像

矩阵和图像有什么关系?我们尝试将矩阵当做图片显示出来(为了便于观看,矩阵被放大100倍):

import cv2
import numpy as np

mat = np.array([
    [   0, 100,   0 ],
    [ 100, 255, 100 ],
    [   0, 100,   0 ]], dtype = np.uint8)
resized = np.kron(mat, np.ones((100, 100)))  # 【调试用,勿深究】将矩阵放大100倍便于观看
resized = resized.astype(np.uint8)  # 【调试用,勿深究】由于np.kron会改变dtype类型为float64,这里我们转回uint8

cv2.imshow('3x3 Matrix', resized)
cv2.waitKey()

(中间两行是为了放大图像写的调试代码,你可以删掉试试看效果)
运行结果如下:

矩阵效果

可以看到,刚刚矩阵中的数值,其实是最简单的颜色——灰度值,0为黑色,255为白色,中间线性变化(所以100是灰色)。请仔细对比矩阵图和结果图观察每个像素值和显示色彩。

所以,OpenCV中矩阵即图片。

 

2. 彩色图像

上面我们说了灰度图的创建,接下来考虑一下彩色图。
OpenCV官方最常用的是BGR图像(注意和RGB图像色彩顺序是反的)。灰度图每个像素用1个0~255的值表示,BGR彩色图则每个像素包含B(Blue 蓝色)、G(Green 绿色)、R(Red 红色)3个值,也是用0~255表示。看图理解:

3通道二维矩阵

依然是9个像素,部分像素解析:

  • [0,0](0行0列)像素BGR均为0,所以依然是黑色
  • [0,1](0行1列)像素第一个值B为100,GR均为0,所以是蓝色
  • [1,0](1行0列)像素BG均为0,R为100,所以是红色
  • [1,1](1行1列)像素BGR均为255,所以是白色

修改之后的代码如下:

import cv2
import numpy as np

mat = np.array([
    [ [ 0,   0,   0 ], [ 100,   0,   0 ], [ 0,   0,   0 ] ],
    [ [ 0,   0, 100 ], [ 255, 255, 255 ], [ 0,   0, 100 ] ],
    [ [ 0,   0,   0 ], [ 100,   0,   0 ], [ 0,   0,   0 ] ]], dtype = np.uint8)
resized = np.kron(mat, np.ones((100, 100, 1)))  # 【调试用,勿深究】将矩阵放大100倍便于观看
resized = resized.astype(np.uint8)  # 【调试用,勿深究】由于np.kron会改变dtype类型为float64,这里我们转回uint8

cv2.imshow('3x3 Matrix', resized)
cv2.waitKey()

可以看到我们在原来灰度图二维数组基础之上,将每个元素由原来的int改为了一个包含BGR 3个数值的数组(注意放大时的矩阵也扩大了一个维度)。效果如下:

彩色图

同样请大家仔细对比矩阵图和结果图的每个像素,并请大家动手改一改代码中的矩阵内容,将两侧的红色改为绿色。

好了,大家平时看到的色彩丰富的照片,也都是用这种方式组成的,只是矩阵更大一些,例如下面是一个3264 x 2448的3通道RGB矩阵(如果舍得花时间,也是可以一个像素一个像素手工填出来的!-_-):

铜锣湾
(摄于2017年1月香港铜锣湾凌晨1点)

 

3. 通道的概念

通道的概念很重要,下面的内容偏理论一点,但请尽量理解:

1)通道就是每个像素拥有的色彩维度

  • 对于灰度图,只有一个色彩维度,所以是单通道(灰度图也被称为单通道二维矩阵)
  • 对于BGR彩色图,有BGR三个色彩维度,所以是3通道
  • 像RGBA彩色图,则有四个色彩维度(A是Alpha透明度),所以是4通道
  • 类似的还有YUV、HSL等色彩模型(未来会详细介绍),也是3通道
  • 如果我们将BGR中,所有B通道值取出来组成一个二维矩阵,就形成了单通道二维矩阵,即灰度图,这个灰度图描述了当前图像蓝色分布
  • 如果我们要将一张照片中的红色调低,则可以将BGR图像拆分成3个通道灰度图,然后将R通道灰度图的亮度调低(例如每个值都缩小为原有的0.5),再将3个通道合并回BGR图像

2)几乎所有的OpenCV图像都可以被表示为3维矩阵(数组)

  • 从代码来看,1维矩阵就是普通数组,2维矩阵就是2维数组,3维矩阵就是3维数组
  • OpenCV图像3维矩阵中的3维按顺序是:1维-行,2维-列,3维-通道
  • 如果3维矩阵不好理解,可以理解成2维矩阵,矩阵中每个元素都包含1、3或4个数值(暂时不存在2通道颜色空间)

如果之前对矩阵等不太熟悉,可能会有点难理解,没关系,多写多思考,慢慢就好了。

以上是一些图像矩阵基础知识,以及矩阵的创建,为了让大家理解OpenCV原理,特意没有像其他教程一样从加载图片中来分析,希望大家能够学到东西。下一篇继续讲矩阵操作。

  • 15
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值