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

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

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

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

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

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

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

# coding: utf-8

import cv2

import numpy as np

def main():

    # 读取lena图

    img = cv2.imread('lena.jpg')

    # 打印img的维度

    print 'img.shape:',img.shape

    # 打印img的一个像素值

    print 'img[0,0]:',img[0,0]

    # 打印img的一个像素的一个通道值

    print 'img[0,0,0]:',img[0,0,0]

if __name__ == '__main__':

    main()

在OpenCV的Python库中,图像是用numpy库的array结构表示的,你可以理解为矩阵。img这个numpy.array的第一个维度沿着行方向,第二个维度沿着列方向,第三个维度沿着通道。numpy.array与Matlab中的矩阵很相似,也支持多个数据同时访问,如img[0, :]可以表示图像的第一行所有像素、img[…, 0]可以表示图像的第一个通道所有像素。