[Day2] 电脑视觉下的人脸

万般皆是脸
Francois & Jean Robert – 《FACES》

:在接下来的内容里,我会着重在"图片"下的人脸辨识 (包含摄影机图片串流处理),3D影像或其他非图片类型的本人还未着墨,因此不会在这个系列内容中说明。

注2:本篇文章着重在接下来系列文的基础知识,如果这些对你来说太简单了,可以斟酌跳过 :)

本文开始

以下面年轻时的卓别林照片来说:
卓别林
reference: 维基百科 - 查理·卓别林

这张照片有几个资讯:

  1. 大小是宽高比 540 x 720 px (单位为像素,好奇的邦友可以按F12打开开发者工具检查)
  2. 照片是灰阶照片 (也就是只有一种颜色表示的图片:黑色)
  3. 卓别林年轻时真帅

若将上述的资讯用电脑能够理解的资料储存,以矩阵来表示会看起来像这样:

matrix

若用numpy array的方式表示会长这样 (numpy是Python中很常用的矩阵与数值函式库,这里可以先不管):

[[ 67  69  65 ...  60  58  60]
 [ 63  62  67 ...  60  58  59]
 [ 64  59  68 ...  54  54  55]
 ...
 [210 211 209 ...  23  20  21]
 [204 210 216 ...  19  15  16]
 [209 203 213 ...  24  18  17]]

到目前为止我们知道:

  1. 电脑在处理图片时通常会用pixel(像素)来作为基本的单位处理内容 (所以这张照片就有540x720=388800个像素)
  2. 每个像素的值范围是 [0, 255] (灰阶图片来说,数值越大颜色越浅;255代表白色)
  3. 卓别林年轻时真的很帅

因此,如果是一个彩色图片:
彩色卓别林

为了要表示色彩空间,我们用大家所熟悉的三原色(RGB)来表示这张图片的话:
matrix
图片上半部依序由左至右为图片仅红色部分图片仅绿色部分图片仅蓝色部分

那下半部的三张图片呢?
还记得前面提到灰阶图片表示,数值范围是从 [0, 255] 吧?

因此下半部三张图可以想成把三原色(RGB)分别以灰阶数值来表示
头晕了吗?

举例说明:

  • 在左下的图红色部分以灰阶表示中,可以看到卓别林的脸部部分比起其他下半部的图都是特别的亮:
    • 意思是脸部部分红色色彩大多都接近255 (0 ~ 255 是从黑到白);也就是脸部主要是用红色表示
      (上半部分图片由於人对不同颜色的差异感知不同,因此红色部分很难看出脸部比较"亮")
  • 衣服部分可以看出"蓝色图片那张都比较黑" (下半部蓝色部分以灰阶表示的图片,对应的地方则是黑色比较多):
    • 意思是原图衣服部分很少有蓝色的像素存在

以上的范例说明希望能让你对"颜色以数值表示"有一些感觉。
当然,没有很理解也不会影响接下来的主题就是。

最後,图片的原始大小为510 x 706,而图片是彩色的就表示要用三个510 x 706的矩阵来表示:
510 x 706 x 3

numpy来查看图片的"大小"的话:

numpy.shape(image)
> (706, 510, 3)

依序由左至右是:高为706、宽为510、通道(颜色)为3的图片

图片的ROI与Bounding Box

在上面的彩色图片中,如果在做人脸侦测(Face Detection)或是其他物件辨识时,通常会有类似下图的过程:
image_color_box

其中:
ROI (Region of Interest),指的是在准备做某个影像分析处理时 (这里范例就是人脸辨识),後续会特别针对进行处理的区域,通常这个区域是矩形。

而因为目前图片中ROI只有一个,後续在进行人脸辨识分析,最终结果还是同样的一个矩形范围。这个最终人脸辨识结果通常会用Bounding Box(边界框)表示人脸辨识的范围。

通常边界框会有两种表示方式:

  1. (x0, y0, x1, y1):用两个点表示边界框。分别代表左上X座标、左上Y座标、右下X座标、右下Y座标
  2. (x0, y0, w, h):用一个点与宽高表示边界框。分别代表左上X座标、左上Y座标、边界框的宽、边界框的高

再多说一点,由於边界框一定会在原始图片内某一个区块,在做电脑视觉分析(甚至是其他机器学习)时,通常会为了方便进行分析而将边界框的数值结果都用[0, 1]这个范围表示

那要如何做呢?

假设我们现在看上面范例图片的x0位置,可以发现它大概就在整张图片约左右正中心的位置;这时我们就可以把x0的数值标示成0.5

计算方式聪明的你应该也想到了:x0 / 图片宽(image_width),然後再取整数 (座标通常都会用整数表示)

其他数值也是用类似的方式计算。

到目前为止这一些基础知识应该足够了,明天见!


<<:  Day1 学习目标与动机

>>:  DAY1-为何要逼自己参加铁人赛

[第三十只羊] 迷雾森林终章 决斗,抽牌

天亮了 昨晚是平安夜 关於迷雾森林故事 金色山脉 海马的自爆攻击 让整座迷雾森林火势开始蔓延开来 就...

Material UI in React [ Day 28 ] Customization Component 自订组件 (part1)

由於组件可以在不同的context中使用,有几种方法可以解决这个问题,官方连结。 1.一次性情况的特...

Day 23 -资料库应用小程序 资料库设计(系统需求分析)

完善的资料库能够有效地存储数据,提供最新、最精确的资讯,满足使用者的应用需求,因此正确的资料库结构设...

小结

惯例在最後一天做个总结啦,不过回头看第一天条列的内容清单,发现还漏掉一个建构周期任务的介绍没写到,没...

# Day28--让commit像战国时代一样分分合合

上一篇我们学到怎麽使用Vim,还有修改commit message,这次要做的事情呢,就是要来合并跟...