快生活 - 生活常识大全

产品讲技术带你看懂什么是计算机视觉一


  做为一名5岁的AI产品汪,刚好利用春节(疫情)假期在家整理了一些CV的文章,发现网上的资料质量参差不齐,内容缺斤少两,小白很难甄别/读懂,想对CV有一个系统的认识很难,就自己做了一个系统总结(小白可以当教材看)。
  本人并非CV领域专业人士(产品经理),但希望可以帮助小白对CV全流程和原理有一个系统的认识,也欢迎各位大牛帮忙纠正。
  适读人群:
  对AI感兴趣的同学
  对AI产品经理感兴趣的同学
  互联网产品经理想转AI产品经理的同学
  对CV或者图像处理有一定基础,想再系统复习的同学
  读完收获:
  对CV全流程有一个了解,明白从一个图像识别需求到输出结果,CV都需要做些什么
  AI产品经理需要掌握的CV常识和专业名词,终于知道算法工程师在说什么了
  熟悉CV的全流程,在数据收集、产品设计时就可以尽量规避问题,提高图像识别准确率
  收藏了本文章,可以经常拿出来复习,再方便不过啦
  首先我把CV的处理流程分为4个阶段:1图像采集->2图像编码->3图像预处理->4特征工程
  图像采集:是CV处理的数据输入来源,根据需要识别的业务需求,对图像的背景光线、噪音、距离、遮挡物等会有相关的要求。
  图像编码:做为计算机视觉处理的前提,通过把图像的二进制数据进行交换,转换为OpenVC等算法模型可用的图片编码格式,常用的方法有模拟处理、脉冲调制、数字编码、预测码等方式。
  图像预处理:是为特征工程扫除障碍和无效信息,提高图像识别准备率的核心主力了,因为在实际的业务场景中收集到的图像数据是非常复杂多样的,会有图像质量太差、大量无效数据、图像变形、失真等情况,而这种图像如果直接由特征工程去处理,输出的结果可想而知。
  特征工程:就是大家常说的AI模型,但可能运用的不只一种模型,根据业务的需求选择对应的算法模型,提前针对需要的输出结果,进行特征提取、特征选择、PCA降维等工作,再用大量已标注好的高质量数据进行训练,输出可以满足此阶段业务识别需求的特征工程。
  下图是我对CV处理流程的理解:
  接下来会对CV处理流程中图像预处理和特征工程部分进行重点介绍。
  文章大纲:(粗体部分是本篇文章分享的内容)
  一、什么是图像预处理?
  1.1灰度化是什么?
  1.1.彩色图像实现灰度化的常用方法
  1.2什么是图像几何转换?
  1.2.1图像的平移转换
  1.2.2图像的镜面变换
  1.2.3图像的转置变换
  1.2.4图像的旋转
  1.2.5图像的缩放
  1.2.6什么是灰度插值算法?
  1.3什么是图像增强?
  1.3.1图像去噪
  1.3.2锐化
  1.3.3低照度增强
  1.3.4去雾
  1.3.5去运动模糊
  1.3.6超分辨率重建
  1.4什么是图像恢复?
  1.4.1图像增强和图像恢复的区别
  1.4.2图像恢复的处理流程
  1.5什么是图像分割/边缘检测
  二、什么是特征工程?
  2.1算法和模型的区别
  2.2特征使用方案
  2.3特征获取方案
  2.4特征处理
  2.4.1特征清洗
  2.4.2特征预处理
  2.5特征监控
  三、参考文献
  一、图像预处理是什么?
  图像预处理主要目的是消除图像中无关的信息,恢复有用的真实信息,增强有关信息的可检测性、最大限度地简化数据,从而改进特征提取、图像分割、匹配和识别的可靠性。
  一般的预处理流程为:1灰度化->2几何变换->3图像增强
  1.1 灰度化是什么?
  现在大部分的彩色图像都是采用 RGB颜色模式,在进行图像处理时,我们往往需要对RGB三个分量通道依次进行处理,花费时间和计算成本会相对较高。但实际上RGB并不能反映图像的形态特征,只是从光学的原理上进行颜色的调配。
  所以我们经常要把彩色图像弄成8位的灰度值图像直接进行处理,可以通过直方图,灰度变化,还有正交变换之类的进行处理,减少所需处理的数据量,从而达到提高整个应用系统的处理速度的目的。
  目的:为了减小图像原始数据量,提升计算效率,因为图像处理中不一定需要对彩色图像的RGB三个分量都进行处理。
  科普环节,大牛请跳过:
  R:Red 红色
  G:Green 绿色
  B:Blue 蓝色
  RGB图像就是我日常见到的大多数彩色图像,它只使用R、G、B三种颜色,每种颜色有0~255范围内的强度值。如果按照不同的比例混合可以组合成约1677万种颜色,几乎包含了人类视力所能感知的所有颜色,而每幅彩色图像是由RGB三幅灰度图像组合而成。
  二值图像(Binary Image):图像中每个像素的灰度值仅可取0或1,即不是取黑,就是取白,二值图像可理解为黑白图像
  灰度图像(Gray Scale Image):图像中每个像素可以由0-255的灰度值表示,具体表现为从全黑到全白中间有255个介于中间的灰色值可以取
  下面用一张图来感受一下灰度图与彩色图像之间的联系与差别
  1.1.1 彩色图像实现灰度化的常用方法
  1)分量法:将彩色图像中的三分量RGB的亮度作为三个灰度图像的灰度值,可根据应用需要选取三种中的一种灰度图像。
  2)最大值法:将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。
  3)平均值法:将彩色图像中的三分量亮度求平均得到一个灰度图。
  4)加权平均法:根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像。
  1.2 什么是图像几何变换?
  图像几何变换又称为图像空间变换,通过平移、转置、镜像、旋转、缩放等几何变换对采集的图像进行处理,用于改正图像采集系统的系统误差和仪器位置(成像角度、透视关系乃至镜头自身原因)的随机误差。
  这就给观测者或是图像识别程序带来了困扰,通过适当的几何变换可以最大程度地消除这些几何失真所产生的负面影响,有利于我们在后续的处理和识别工作中将注意力集中子图像内容本身。更确切地说是图像中的对象,而不是该对象的角度和位置等。
  因此, 几何变换常常作为其他图像处理应用的预处理步骤, 是图像归一化的核心工作之一。它将一幅图像中的坐标位置映射到另一幅图像中的新坐标位置. 我们学习几何变换的关键就是要确定这种空间映射关系, 以及映射过程中的变换参数。
  目的:减少因几何失真而造成图像识别的问题,通过图像空间变换最大程度地消除几何失真产生的负面影响。
  下面会给大家介绍一下几何变换常用的几种方法的原理和Matlab实现方法:
  图像的平移变换;
  图像的镜像变换;
  图像的转置变换;
  图像的旋转变换;
  图像的缩放。
  1.2.1 图像的平移变换
  在进行书写matlab代码之前,先来了解一下图像平移的理论基础。设图像的高度为H,宽度为W,如下所示:
  我们知道,图像是由像素组成的,而像素的集合就相当于一个二维的矩阵,每一个像素都有一个"位置",也就是像素都有一个坐标。假设原来的像素的位置坐标为(x0,y0),经过平移量(△x,△y)后,坐标变为(x1,y1),如下所示:
  用数学式子表示可以表示为:
  x1 = x0 + △x
  y1 = y0 + △y
  用矩阵表示为:
  本来使用二维矩阵就可以了的,但是为了适应像素、拓展适应性,这里使用三位的向量。
  式子中,矩阵:
  称为平移变换矩阵(因子),△x和△y为平移量。
  此外,我们也知道了,图像的高度H其实也就是像素的行数,对于坐标1≤X≤H;图像的长度也就是像素的列数,对应坐标1≤Y≤W。
  我们先来看一下效果,,效果如下所示:
  然后下面分析一下关键的代码:
  读入图像之后,得到im,我们可以看到im是一个三维的变量,包括了像素的位置(高度(即垂直长度)和宽度(即水平长度)),像素的颜色。(注,24位真彩图:也是用矩阵表示,图像像素直接用RGB颜色显示,而不是通过颜色索引表。图像像素的颜色用三个变量表示即(R,G,B),每个变量从0~255变化,因此一个像素也就是8bit*3=24bit,一个像素用24bit表示可以有2^24种颜色。)我们可以看到会有unit8,就是8bit的原因。
  然后我们获取图像的大小,用H,W,Z三个变量接收,其中H接收了图片的高度(也就是垂直长度),W接收了图片的宽度(水平长度),然后Z接收了图片的颜色值。
  然后我们将图像转换成双精度类型 I,这是因为使用双精度可以仿真在转换过程中发生精度损失的问题,也是方便我们进行转换。转换之后,我们可以看到unit8的类型别我们转换成了double类型。
  接着,我们构造一个图像res矩阵,这个图像首先进行归一化,也就是让里面的元素全部为1,对于图像,就是一张白色的图片了。这个图像主要是用来"保存"我们进行位移后的图像。
  然后我们就设置平移量、构造平移变换矩阵。这个矩阵我们根据前面的理论部分可以得到。
  接着便是重点了,进行平移变换。我们来一句一句解读这个循环。当x0=1,y0=1时,得到第一个像素的位置,也就是(x0,y0)这个像素,然后将这个像素位置进行缓存,也就是构造一个矩阵temp,即理论中的:
  然后进行位置转换,也就是进行矩阵相乘,用变换矩阵乘以原像素矩阵,得到了变换后像素矩阵:
  接着,我们需要把变换后的像素位置"提取"出来,用x1,y1进行存储,为什么要获取位置呢?
  这是因为我们要判断这个像素是否越界了,也就是进行平移之后,得到的这个像素位置是否还存在显示区域里面,也就是我们的:
  if(x &lt;= H) &amp; (y &lt;= x=""&gt;= 1) &amp; (y &gt;= 1)语句<!--=-->
  当还在显示区域里面时,我们要进行移位显示:
  res(x1,y1,:)= I(x0,y0,:);%进行图像平移,颜色赋值
  这个语句的含义是,把I中的RGB值(也就是颜色值)赋值给res,也就是说,前面矩阵相乘只是移动的像素位置,但是颜色没有进行移动,这里进行图像颜色的平移,当x0=1,y0=1时,把该点的位置图像颜色进行移动过去。
  当x0=1,y0=2时,移动第二点。我们可以看到,这里的代码是:从左到右平移,也就是先进行宽度的平移;从上到下,进行高度的平移。当两个循环完成之后,图像也就像平移完成了。
  最后的代码就是显示图像了,其中axis on 的意思是打开左边,方便我们进行查看平移后的位置。从上面的效果我们可以得到,delx表示的高度的平移量,delx为正值时往下平移,delx为负值时往上平移;而dely表示的宽度的平移量,正值往右平移,负值往左平移。
  1.2.2 图像的镜像变换
  图像的镜像变换分为水平镜像和垂直镜像,下面分别进行这两种镜像的介绍,首先说明一下,无论是水平镜像还是垂直镜像,镜像后高度和宽度都不变。
  H图像的高度,关联x W:图像的宽度,关联y。
  水平镜像操作:以原图像的垂直中轴线为中心,将图像分为左右两部分进行对称变换。
  示意图如下所示:
  水平镜像中,原图中的(x0,y0)经过水平镜像后,坐标变成了(x0,W-y0),用数学公式表达就是:
  x1 = x0,
  y1 = W-y0;
  写成矩阵就是:
  也就是说,水平镜像变换矩阵(因子)为:
  代码效果如下所示:
  垂直镜像操作:以原图像的水平中轴线为中心,将图像分为上下两部分进行对称变换。
  示意图如下所示:
  垂直镜像中,原图中的(x0,y0)经过垂直镜像后,坐标变成了(H-x0,y0),用数学公式表达就是:
  x1 = H – x0
  y1 = y0
  写成矩阵就是:
  也就是说,垂直镜像变换矩阵(因子)为:
  实现的效果如下所示:
  1.2.3 图像的转置变换
  图像的转置就是将图像像素的x坐标和y坐标互换。这样将改变图像的高度和宽度,转置后图像的高度和宽度也将互换。
  图像的转置用数学公式描述就是:
  x1 = y0
  y1 = x0
  写出矩阵如下所示:
  实现的效果如下所示:
  1.2.4 图像的旋转
  一般情况下,旋转操作会有一个旋转中心,这个旋转中心一般为图像的中心,旋转之后图像的大小一般会发生改变。图像像素原来的坐标为(x0,y0),(顺时针)选择Θ角度后得到(x1,y1),用数学公式表达如下所示:
  x1 = x0·cosΘ+ y0·sinΘ
  y1 = -x0·sinΘ+ y0·cosΘ
  用矩阵表示如下所示:
  代码实现的效果如下所示:
  1.2.5 图像的缩放
  下面值来介绍一下图像的缩放主要是根据函数imresize来实现的,我们先来看看代码和效果图,然后分析图像的缩放函数。
  效果图像所示:
  缩小:
  等大:
  放大:
  缩放并且设置行列:
  线性插值:
  感谢原作者的无私奉献,希望可以有更多大牛可以分享出更好的文章~
  对原文进行了部分删减和修改,转载自:https://www.cnblogs.com/IClearner/p/6842334.html
  现在大家对图像几何变换已经有一些了解了吧,但是几何变换不会改变图像的像素值,只是在图像平面上进行像素的重新安排。
  一个完整的几何变换需要两部分运算:除了空间变换所需的运算外,还需要使用灰度插值算法。因为按照几何变换关系进行计算,输出图像的像素可能被映射到输入图像的非整数坐标上。而像素做为最小显示单位(矢量图形不是由像素构成的,矢量可以是一个点或一条线),我们要为输出图像找到最合适的整数像素点。
  1.2.6 什么是灰度插值算法?
  灰度插值算法,通常采用的方法有最近邻插值、双线性插值和双三次插值。在讲插值算法之前,我们先来看下图像的缩放问题。
  传统的绘图工具中,有一种叫做"放大尺"的绘图工具,画家常用它来放大图画。在计算机上,我们将不再需求用放大尺去放大或缩小图像了,把这个工作交给程序来完成就可以了。
  我们所说的图像都是指点阵图,也就是用一个像素矩阵来描述图像的方法,对于另一种图像:用函数来描述的图像的矢量图,不再本文讨论之列。
  图像放大时,像素也相应地增加,但这些增加的像素从何而来?
  这时插值就派上用场了:插值就是在不生成像素的情况下增加图像像素大小的一种方法,在周围像素色彩的基础上用数学公式计算丢失像素的色彩。
  所以在放大图像时,图像看上去会比较平滑、干净,但必须注意的是插值并不能增加图像信息。
  目的:因为图像空间变换不改变图像的像素值,只是对图像的像素值重新进行映射,在表示映射关系时,输出图像的像素可能被映射到输入图像的非整数坐标上,灰度插值算法就是为输出图像找到最合适的整数像素坐标。
  在知道什么是插值后,让我们来一起看一下常用的插值算法的原理。
  (1)最近邻插值法 Nearest Neighbour Interpolate
  是最简单的一种插值算法,也称作零阶插值,就是令变换后像素的灰度值等于距它最近的输入像素的灰度值。也就是说照搬旁边的像素这样做结果,会产生明显可见的锯齿,在待求像素的四邻像素中,将距离待求像素最近的邻灰度值赋给待求像素。
  设i+u, j+v(i, j为正整数, u, v为大于零小于1的小数,下同)为待求象素坐标,则待求象素灰度的值 f(i+u, j+v)
  如下图所示:
  如果(i+u, j+v)落在A区,即u&lt;0.5, v&lt;0.5,则将左上角象素的灰度值赋给待求象素。同理,落在B区则赋予右上角的象素灰度值,落在C区则赋予左下角象素的灰度值,落在D区则赋予右下角象素的灰度值。最邻近元法计算量较小,但可能会造成插值生成的图像灰度上的不连续,在灰度变化的地方可能出现明显的锯齿状。
  最近邻插值法实现的效果如下所示:
  从效果图上,可以看到明显的锯齿,这就是因为最近邻插值法不断在复制最近邻像素灰度值的原因,假设A、B、C、D为四个不同的像素点,现在把输入图像扩大4倍:
  输出图像就由原来的4个像素点变成了16像素点,而新增的12个像素点并不是图像新的真实像素,而是复制图像邻近像素产生的,就很容易出现锯齿这种图像失真现象。
  (2)双线性插值Bilinear Interpolation
  1)双线性插值
  假设源图像大小为mxn,目标图像为axb。那么两幅图像的边长比分别为:m/a和n/b。注意,通常这个比例不是整数,编程存储的时候要用浮点型。目标图像的第(i,j)个像素点(i行j列)可以通过边长比对应回源图像。其对应坐标为(i*m/a,j*n/b)。
  显然,这个对应坐标一般来说不是整数,而非整数的坐标是无法在图像这种离散数据上使用的。双线性插值通过寻找距离这个对应坐标最近的四个像素点,来计算该点的值(灰度值或者RGB值)。如果你的对应坐标是(2.5,4.5),那么最近的四个像素是(2,4)、(2,5)、(3,4),(3,5)。
  若图像为灰度图像,那么(i,j)点的灰度值可以通过一下公式计算:
  f(i,j)=w1*p1+w2*p2+w3*p3+w4*p4;
  其中,pi(i=1,2,3,4)为最近的四个像素点,wi(i=1,2,3,4)为各点相应权值。关于权值的计算,在维基百科和百度百科上写的很明白。
  2)存在的问题
  这部分的前提是,你已经明白什么是双线性插值并且在给定源图像和目标图像尺寸的情况下,可以用笔计算出目标图像某个像素点的值。
  当然,最好的情况是你已经用某种语言实现了网上一大堆博客上原创或转载的双线性插值算法。然后发现计算出来的结果和matlab、openCV对应的resize()函数得到的结果完全不一样。
  那这个究竟是怎么回事呢?
  其实答案很简单,就是坐标系的选择问题,或者说源图像和目标图像之间的对应问题。
  按照网上一些博客上写的,源图像和目标图像的原点(0,0)均选择左上角,然后根据插值公式计算目标图像每点像素。
  假设你需要将一幅5×5的图像缩小成3×3,那么源图像和目标图像各个像素之间的对应关系如下:
  只画了一行,用做示意,从图中可以很明显的看到,如果选择右上角为原点(0,0),那么最右边和最下边的像素实际上并没有参与计算,而且目标图像的每个像素点计算出的灰度值也相对于源图像偏左偏上。
  那么,让坐标加1或者选择右下角为原点怎么样呢?很不幸,还是一样的效果,不过这次得到的图像将偏右偏下。
  最好的方法就是,两个图像的几何中心重合,并且目标图像的每个像素之间都是等间隔的,并且都和两边有一定的边距,这也是matlab和openCV的做法。如下图:
  如果你不懂我上面说的什么,没关系,只要在计算对应坐标的时候改为以下公式即可:
  int x=(i+0.5)*m/a-0.5
  int y=(j+0.5)*n/b-0.5
  instead of
  int x=i*m/a
  int y=j*n/b
  利用上述公式,将得到正确的双线性插值结果
  双线性内插法实现的效果如下所示:
  双线性内插法的计算比最邻近点法复杂,计算量较大但没有灰度不连续的缺点,结果基本令人满意。它具有低通滤波性质,使高频分量受损,图像轮廓可能会有一点模糊。
  (3)双三次插值Bicubic interpolation
  双三次插值是一种更加复杂的插值方式,它能创造出比双线性插值更平滑的图像边缘。双三次插值方法通常运用在一部分图像处理软件、打印机驱动程序和数码相机中,对原图像或原图像的某些区域进行放大。Adobe Photoshop CS 更为用户提供了两种不同的双三次插值方法:双三次插值平滑化和双三次插值锐化。
  在数值分析这个数学分支中,双三次插值是二维空间中最常用的插值方法。在这种方法中,函数f在点 (x,y) 的值可以通过矩形网格中最近的十六个采样点的加权平均得到,在这里需要使用两个多项式插值三次函数,每个方向使用一个。
  双三次插值又叫双立方插值,用于在图像中"插值"(Interpolating)或增加"像素"(Pixel)数量/密度的一种方法。通常利用插值技术增加图形数据,以便在它打印或其他形式输出的时候,能够增大打印面积以及(或者)分辨率。
  有不同的插值技术可供选用。双立方插值通常能产生效果最好,最精确的插补图形,但它速度也几乎是最慢的。"双线性插值"(Bilinear interpolation)的速度则要快一些,但没有前者精确。
  在商业性图像编辑软件中,经常采用的是速度最快,但也是最不准确的"最近相邻"(Nearest Neighbor)插值。其他一些插值技术通常只在高档或单独应用的程序中出现。
  显然,无论技术多么高级,插补过的数据肯定没有原始数据准确。这意味着对一个图形文件进行插值处理后,虽然文件长度增加了(数据量增大),但不会有原先那幅图锐利,可能会在图形质量上打折扣。
  这公式是什么?我是谁?我在干嘛……
  这部分确实还没整明白,先把结果告诉大家,原理后续再继续更新……
  双三次曲线插值法实现的效果如下所示:
  双三次曲线插值方法计算量较大,但处理图像效果是最好的。这种算法是一很常见的算法,普遍用在图像编辑软件、打印机驱动和数码相机上。
  现在有许多数码相机厂商将插值算法用在了数码相机上,并将通过算法得到的分辨率值大肆宣传。固然他们比双三次插值算法等先进很多,但是事实图像的细节不能凭空造出来的。因为插值分辨率是数码相机通过自 身的内置软件来增加图像素,从而达到大分辨率效果。
  啊哈,对于小白来说这些内容已经很烧脑了,大家看完之后要尽量动手尝试一下哦,下一篇会继续为大家更新图像增强和图像恢复的部分。
  注:文章部分内容和图片来自于互联网,在参考文献中会注明出处,如有侵权等问题,请及时联系我删除,谢谢大佬们的支持和无私奉献~
  第二篇连载已更新,已经完成的图像预处理的所有内容,喜欢小伙伴可以继续阅读哈~
  《产品讲技术 | 带你看懂什么是计算机视觉(二)》
网站目录投稿:乐天