(1)模拟人类视觉的优越能力
(2)弥补人类视觉的缺陷
•语义感知(semantic)
(1)神经网络不断增加层数一定会导致过拟合
(2)工业领域没有大量样本之前需要数据增强方式去获取数据
(3) OpenCL•URL: http://opencv.org/
(4)Caffe•函数库:http://caffe.berkeleyvision.org
(5)Torch(PyTorch)•函数库:URL: https://torch.ch(http://pytorch.org/)
(6)Tensorflow:https://www.tensorflow.org/
(7)Keras:兼容 Theano 和 Tensorflow 的深度学习高级包, https://keras.io
1.使用图 (graph) 来表示计算任务.
2. 在被称之为 会话 (Session) 的上下文 (context) 中执行图.
3. 使用 张量(tensor) 表示数据.
4. 通过 变量 (Variable) 维护状态.
5. 使用 feed 和 fetch 可以为任意的操作赋值或者从其中获取数据
亮度:即人眼对光的明亮程度的感受。
色调:人眼能看到的颜色种类,与光的波长有关
饱和度:颜色深浅程度。与各种颜色混入白光的比例有关。
以上 色调 + 饱和度 = 色度
RGB彩色空间利用相加混合法将三个彩色分量按照不同的比例叠加,最终就可以在屏幕中显现出各种颜色。
任意的彩色光F都有一个配色的公式:F = r[R]+g[G]+b[B]
式中r,g,b为系数,r+g+b=1。故,知其二便可唯一确定色调。
此外对于一个像素颜色值的表示可以是(B,G,R)
取值范围:[0, 255] 或者[0.0, 1.0]
•减法混色,印刷
•4通道
•Cyan通道•Magenta通道•Yellow通道•Key通道
•一个像素颜色值:(c, m, y, k)
•取值范围•[0, 255]•[0.0, 1.0]
(1)分成三个通道然后去保存:
RGB三通道彩色图:图片转成3维矩阵([0,255])
(2)把图片灰度化存储:
单通道灰度图:亮度信息([0,255])
** Gray=Rx0.3+Gx0.59+Bx0.11**
常见的存储的格式有:bmp, jpg, png, tiff, gif, pcx, tga, exif, fpx, svg, psd, cdr, pcd, dxf, ufo, eps, ai, raw, WMF, webp等
通过直方图对图片数据/特征分布进行统计,包括以下特征:
•灰度、颜色
•梯度/边缘、形状、纹理
•局部特征点、视觉词汇
•区间(bin)----如上图区间就是5
•具有一定的统计或物理意义
•一种数据或特征的代表
•需要预定义或基于数据进行学习
•数值是一种统计量:概率、频数
所以实际上直方图就是对数据空间(bin)进行量化
定义:利用图像直方图对对比度进行调整的方法。
均衡化的基本思想是:尽量使得每个灰度级的像素数量相等。即不存在大片的相似像素,提高图像的对比度。
从下图的对比上看HE的实质上是对图像进行非线性拉伸,重新分配各个灰度单位中的像素点数量,使一定灰度范围像素点数量的值大致相等:
进行HE操作以后,值变化不大,但是被拉开了:
(1)作用:直方图均衡化通常用来增加许多图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候。
直方图均衡化以后,亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。
(2)缺点:无法处理图片中明显亮或者明显暗的部分,而且拉伸后有些灰度级可能不被映射到,造成图像观感上的颗粒感。
对于图片中明显亮或者明显暗的部分,可以使用AHE进行操作
实质上AHE是通过对局部区域进行直方图均衡,步骤如下:
(1)移动模板在原始图片上按特定步长滑动
(2)每次移动后,模板区域内做直方图均衡
(3)映射后的结果赋值给模板区域内所有点
(4)每个点会有多次赋值,最终的取值为这些赋值的均值。
问题点:AHE 对局部对比度提高过大,会导致图像失真。而且会放大噪声。
限制对比度的本质就是相当于限制Hist的幅度。
因此具体操作是对子块中统计得到的直方图进行裁剪,使其幅值低于某个上限,当然裁剪掉的部分又不能扔掉,我们还需要将这部分裁剪值均匀地分布在整个灰度区间上,以保证直方图总面积不变:
由于AHE和CLAHE都是利用模板对于子块进行操作,所以会造成最终图像呈块状效应,这里需要引入一个插值来保证连贯性:
插值方法解析:
(1)小黑点的灰度直接由映射函数计算得到;
(2)粉色区域内点的灰度由映射函数计算而得;
(3)绿色区域内点的灰度由由相邻2块灰度映射值线性插值而得;
(4)其他区域所有点的灰度由相邻4块的灰度映射值双线性插值而得。
通过双线性插值可以基本消除块状效应
具体CLAHE的步骤如下:
1.图像分块,以块为单位;
2.先计算直方图,然后修剪直方图,最后均衡;
3.遍历操作各个图像块,进行块间双线性插值;
4.与原图做图层滤色混合操作。(可选项!!)
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread('timg.jpg', 0) # 直接读为灰度图像
# 直方图均值化
he = cv.equalizeHist(img)
# CLAHE(阈值上限是2,子块大小为10*10)
clahe = cv.createCLAHE(clipLimit=2, tileGridSize=(10, 10))
cl1 = clahe.apply(img)
plt.figure(figsize=(40, 16), dpi=160)
plt.subplot(131), plt.imshow(img, 'gray')
plt.subplot(132), plt.imshow(he, 'gray')
plt.subplot(133), plt.imshow(cl1, 'gray')
plt.show()
膨胀是图像中的高亮部分进行膨胀,类似于领域扩张
⑴ 用结构元素B(即一个核),扫描图像A的每一个像素
⑵ 用结构元素与其覆盖的二值图像做“或”操作
⑶ 如果有一个元素为0,结果图像的该像素为0。否则为255
腐蚀是原图的高亮部分被腐蚀,类似于领域被蚕食。
⑴ 用结构元素B,扫描图像A的每一个像素
⑵ 用结构元素与其覆盖的二值图像做“与”操作
⑶ 如果都为0,结果图像的该像素为0。否则为255
腐蚀处理的结果是使原来的二值图像减小一圈。
开运算:可以去掉目标外的孤立点。
开运算 = 先腐蚀运算,再膨胀运算(看上去把细微连在一起的两块目标分开了)
开运算的效果图如下图所示:
开运算总结:
(1)开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不便。
(2)开运算是一个基于几何运算的滤波器。
(3)结构元素大小的不同将导致滤波效果的不同。
(4)不同的结构元素的选择导致了不同的分割,即提取出不同的特征。
闭运算:可以去掉目标内的孔。
闭运算 = 先膨胀运算,再腐蚀运算(看上去将两个细微连接的图块封闭在一起)
闭运算的效果图如下图所示:
- 闭运算总结:
(1)闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。
(2)闭运算是通过填充图像的凹角来滤波图像的。
(3)结构元素大小的不同将导致滤波效果的不同。
(4)不同结构元素的选择导致了不同的分割。
开闭运算应用范围:
通常,当有噪声的图像用阈值二值化后,所得到的边界是很不平滑的,物体区域具有一些错判的孔洞,背景区域散布着一些小的噪声物体,连续的开和闭运算可以显著的改善这种情况。
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# a.图像的二值化
img = cv.imread('./1.png', 0)
# b.设置卷积核5*5
kernel = np.ones((20, 20), np.uint8)
# 图像的腐蚀,默认迭代次数
ero = cv.erode(img, kernel)
# 图像的膨胀,默认迭代次数
dst = cv.dilate(img, kernel)
# 闭运算
def close_opration(img):
kernel = cv.getStructuringElement(cv.MORPH_RECT, (10, 10))
iClose = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
return iClose
iclose = close_opration(img)
# 闭运算
def close_opration(img):
kernel = cv.getStructuringElement(cv.MORPH_RECT, (10, 10))
iOpen = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
return iOpen
iopen = close_opration(img)
plt.figure(figsize=(40, 16))
plt.subplot(121), plt.imshow(img, 'gray')
# plt.subplot(122), plt.imshow(ero, 'gray')
# plt.subplot(122), plt.imshow(dst, 'gray')
# plt.subplot(122), plt.imshow(iclose, 'gray')
plt.subplot(122), plt.imshow(iopen, 'gray')
plt.show()
公式:
参数解析:
•x, y是像素在图片中的位置/坐标
•k, l是卷积核中的位置/坐标•中心点的坐标是(0,0)
•f[k, l]是卷积核中在(k, l)上的权重参数
•I[x+k, y+l]是与f[k, l]相对应的图片像素值
•h[x, y]是图片中(x, y)像素的滤波/卷积结果
注意避免大卷积核的出现
上面的图片说明了图像的卷积操作,但是也反映出一个问题,如上图,原始图片尺寸为44,卷积核的大小为33,当卷积核沿着图片滑动后只能滑动出一个2*2的图片出来,这就造成了卷积后的图片和卷积前的图片尺寸不一致,这显然不是我们想要的结果,所以为了避免这种情况,需要先对原始图片做边界填充处理。
填充方法(Padding)有以下几种(常用的方法是补零填充):
输入图片66,先进行边界补零:以下卷积核是33的(1/9的平均卷积核),6的计算方法是6=9*6/9
均值滤波本身存在缺陷,既没有很好地去除噪声点,也破坏了图像的细节反而使图像变得模糊。
操作原理:
卷积域内的像素值从小到大排序
取中间值作为卷积输出
所谓椒盐噪声就是如下图左图:
模拟人眼,关注中心区域
有效去除高斯噪声
参数解释:
x, y是卷积参数坐标:
标准差 :σ -这个参数也代表了高斯分布峰值的尖锐性
如当σ =1的55卷积核如下时候:
关于σ:核的宽度与σ的比值差不多是三倍,因为3倍标准差差不多包含了99%的信息。所以σ=1,关注部分差不多是卷积核是33,而σ=4,关注部分即卷积核差不多是12*12
可以把一个2D卷积拆分成两个相同的1D卷积:
然后分别进行行卷积核列卷积,从而减少计算量:
Laplacian滤波锐化:先滤波,然后原图减滤波图得到锐化图,补偿图像的轮廓,增强图像的边缘及灰度跳变的部分。如下图所示:
图像金字塔化:先进行图像平滑,再进行降采样
根据降采样率,得到一系列尺寸逐渐减小的图像。
降采样:提取图片的信息,压缩图片,如下图
操作:n次(高斯卷积2倍降采样)n层金字塔
目的:捕捉不同尺寸的物体
所以其实高斯滤波是为了平滑图像,防止直接去降采样损失很多信息,从而产生很多的像素断层,如下图所示:
(1)一次降采样
(2)二次降采样
(3)3次降采样
高频细节信息在卷积和下采样中丢失,所以通过拉普拉斯金字塔保留所有层所丢失的高频信息,用于上采样的图像恢复
直接上采样:
所以整个上采样和下采样过程简化如下:
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
img = cv.imread("./opencv.png", 0)
# 添加噪声
for i in range(2000):
temp_x = np.random.randint(0, img.shape[0])
temp_y = np.random.randint(0, img.shape[1])
img[temp_x][temp_y] = 255
# 高斯滤波(卷积核5*5,sigma=0)
blur1 = cv.GaussianBlur(img, (5, 5), 0)
# 中值滤波(卷积核5*5)
blur2 = cv.medianBlur(img, 5)
# 均值滤波
blur3 = cv.blur(img, (5, 5))
plt.figure(figsize=(45, 16))
plt.subplot(1, 4, 1), plt.imshow(img, "gray")
plt.subplot(1, 4, 2), plt.imshow(blur1, "gray")
plt.subplot(1, 4, 3), plt.imshow(blur2, "gray")
plt.subplot(1, 4, 4), plt.imshow(blur3, "gray")
plt.show()
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('./dave.png', 0)
laplacian = cv.Laplacian(img, cv.CV_64F)
sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize=5)
sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize=5)
plt.subplot(2, 2, 1), plt.imshow(img, cmap='gray')
plt.title('Original'), plt.xticks([]), plt.yticks([])
plt.subplot(2, 2, 2), plt.imshow(laplacian, cmap='gray')
plt.title('Laplacian'), plt.xticks([]), plt.yticks([])
plt.subplot(2, 2, 3), plt.imshow(sobelx, cmap='gray')
plt.title('Sobel X'), plt.xticks([]), plt.yticks([])
plt.subplot(2, 2, 4), plt.imshow(sobely, cmap='gray')
plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])
plt.show()
如何让卷积更快:空域卷积=频域乘积!!!
通过快速傅里叶变换转到频域上,然后再做计算!!!
如何把图像从空间域转换到频域,如下所示(这个帖子里有个人讲的巨清楚,说了如何把图像通过傅里叶转换到频域的过程):本质上就是通过一系列的基图片和原图片进行卷积计算得到频域图片:
(1)基图片可以理解成是满足正弦或者余弦得到的卷积核
(1)
低通是保留频域图里亮的部分
高铁是删除频域图里亮的部分
(2)频段滤除是去掉频域图异常亮的点
傅里叶变换假设前提为信号平稳,但实际中信号多数为非平稳信号。
对于非平稳信号可以进行短时傅里叶变换:
STFT(短时傅里叶变换)添加时域信息的方法是设置窗格,认为窗格内的信号是平稳的;o然后对窗格内的信号分段进行傅里叶变换。n优点是可以获得频域信息的同时可以获得时域信息。对于时变的非稳态信号,高频适合小窗口,低频适合大窗口
但是STFT(短时傅里叶变换)窗格大小很难设置。会出现以下情况
小波变换与STFT思路接近,但小波变换直接把傅里叶变换的基给换了—将无限长的三角函数基换成了有限长的会衰减的小波基。这样不仅能够获取频率,还可以定位到时间
常用的小波变换函数