zoukankan      html  css  js  c++  java
  • 第3章 图像基础

     

    3图像基础

      在开始构建图像分类器之前,首先要理解图像是什么。首先要理解图像的基石——像素。

    1          像素——图像的基石

      像素是图像最原始的构建块。每副图像由像素集合构成。通常,像素考虑为给定一副图片下,在给定位置的“颜色”或亮度的“强度”。如图1所示:

     

    图1 1000像素宽,750像素高的图像

    图1的图像为1000*750分辨率,意味着1000像素宽且750像素高。我们可以用矩阵来概念化图像,在这个例子中,矩阵1000列(宽)和750行(高),即该图像总共1000*750=750000像素。

    大多数像素以两种方式描述:

    (1)       灰阶/单通道

    (2)       彩色/多通道

    灰阶图像,每个像素是在0-255的标量值,其中0对应于“黑色”,255对应于“白色”。值是0-255之间的灰色阴影,越接近0则越黑,越接近于255则越亮。如图2所示:

     

    图2 从0到255的图像梯度像素表示

           在RGB颜色空降中的像素值不再是标量,而是以三个值构成的列表来表示:一个是Red分量、Green分量和Blue分量。因此要定义一副以RGB颜色模型的图像,我们只需要定义每个像素的RGB分量大小即可。

           在一副RGB图像中的所有像素对应的Red分量构成一个通道,另外Green、Blue分量则分别构成另外2个通道,即RGB分别对应1个通道。每个通道的值对应[0,255]总共256个“阴影”。给定仅在[0-255]之间的像素值,我们通常使用8bit无符号整数来表示强度。

          

           一旦我们构建第一个神经网络,我们通常通过执行均值减法(mean subtraction)或缩放(scale)来预处理图像,这将需要我们将图像转换为浮点数据类型。请记住这一点,因为库从磁盘(例如opencv)加载图像所使用的数据类型在直接将学习算法应用于图像之前,通常需要进行转换。

           考虑Red、Green、Blue三个值,我们可以将它们构成RGB的三元组形式(red, green, blue)。这个元组表示RGB颜色空间中的一个特定颜色。可以看出,RGB颜色空间的颜色为加法颜色空间:每个颜色加的越多,像素月亮且越接近白色。颜色空间如图3所示:

     

    图3 左:RGB加性颜色空间    右:RGB立方体

           例如,我们可以表示白色:(255,255,255),黑色(0,0,0)。RGB颜色空间也可表示为图3右侧的立方体方式,由于RGB三通道总共256*256*256种可能的颜色,依赖于RGB各自的取值。

           RGB颜色空间的主要缺陷是:

           (1)它的加特性,使得不使用“颜色选择器”工具情况下,对于定义颜色有点不直观。

           (2)它不能模拟人类对颜色的感知。

           除了这些,几乎遇到的所有图片都使用RGB方式。

    1.1  由通道构建一副图像

    由于一个RGB图像是由R/G/B三个分量构成,我们可以将RGB图像概念化为由宽W和高H组成的三个独立分量构成。我们可以将这三个参数用W*H*D的三维数组表示,其中D为深度或图像的通道。如图4所示:

     

    图4 表示一个RGB图像,每个通道都是独立的矩阵,组合。

    (1)       RGB颜色空间中,每个像素值是R、G、B的三个整数构成;

    (2)       而在NumPy的多维数组中,编程表示则是用宽、高、深度表示。

    2          图像坐标系统

    前面提到,图像是由像素的网格来表示的。那么,在图像坐标系统中,(0,0)点对应于图像的左上的角点,随着向右向下移动,x与y的值随之增大。

     

    图5 字符“I”在8*8的图像表示,x向右,y向下。Python中以0开始索引

             例如,以0开始索引,那么像素4宽、5高的图像,最大索引坐标为(3,4)。

    2.1  由NumPy数组表示图像

    图像处理库如opencv和scikit-image,将RGB图像表示为以shape(形状)(height,width,channel)表示的多维NumPy数组。注意:这里高度在前,宽度在后,与像素图像表示的宽在前、高再厚相反。因为矩阵中的行对应于图像的高度。

             如示例程序load_display.py:

             import cv2

             image = cv2.imread(“lena.jpg”)

             print(image.shape)  //显示shape形状

             cv2.imshow(“IMAGE”, image)

             cv2.waitKey(0)   //等待点击操作,关闭窗口

    保存后,我们执行:python load_display.py将显示lena.jpg的图片,且打印出该图片的shape:(512,512,3),即高512、宽512、3通道。

     

             如果要获取单独像素点的RGB值,则:

             (b,g,r) = image[20, 100]  //注意20为高、100为宽,且返回的值为BGR形式。

    2.2  BGR和RGB顺序

    注意:opencv中存储RGB的通道值是反序的。即我们通常考虑的是Red、Green、Blue,而opencv中则是Blue、Green、Red。原因竟然是历史上,opencv的早期开发者选择了BGR的顺序,由于当时著名的相机制造商等等都以BGR的顺序。这里我们仅仅记住即可。

    3          缩放和长宽比率

    Scale或者resize,是以图像宽度和高度来增加或缩小图像大小的过程。改变图像大小,最主要的是保持图像aspect ratio(长宽比率),该值是图像高与宽的比值。而忽略长宽比率可能使图片看起来压缩和扭曲。如下图所示:

     

    图 6 左:原始图像 右、上:无长宽比率的图像缩放

             为了防止这种缩放问题,我们仅仅在改变图像大小时,通过按比例缩放宽与高。从美学观点来看,我们常常确保这种长宽比率,但是这种原则却不太适合深度学习。大多数神经网络和CNNs应用图像分类任务是假定一个固定大小的输入,意味着传递给网络的所有图像的维度必须大小相等。CNNs网络通常的宽高大小为32*32、64*64、224*224、227*227、256*256和299*299。

            

             假定我们设计网络输入为224*224,但是数据集大小包括312*234、320*240等等,我们如何处理这些图像呢?我们是仅仅忽略长宽比率而处理扭曲的图像(图7下部左侧)?还是采取另一种策略缩放图像,即沿着最短维度缩放图像并且采取中心不变(center crop?)(图7下部右侧)。

     

    图7 上:原图 下左:忽略ratio 下右:首先沿着最短维度缩放然后取center crop

     

             由图7下左可知,忽略长宽比率,将导致图片看起来扭曲且“crunched”。而下右,保持了长宽比率,但是牺牲了图像的一部分内容,因此,如果我们不小心将要识别的物体的一部分或全部割下(crop),这将对我们的图像分类系统造成特别的损害。

             那么,最好的方法就是具体问题具体分析。对于一些数据集,忽略比率将更有优势;而另一些数据集可能沿着最短维度缩放然后center crop更好。

             对于这些方法及应用将在后续中讲解,这里我们仅仅是要理解图像的基础部分以及它们是如何表示的。

  • 相关阅读:
    线程中一些常用方法的分析
    Java中获取路径的方法_自我分析
    Mybatis 一对一,一对多,多对一,多对多的理解
    页面刷新两次为什么取不到值
    排序--插入
    排序--冒泡
    页面刷新两次为什么取不到值
    容器模式
    java操作oracle的blob,clob数据
    Redis基本操作命令
  • 原文地址:https://www.cnblogs.com/paladinzxl/p/9491596.html
Copyright © 2011-2022 走看看