以前的时候用OpenCV老是不太清楚其中的算法,只是任务驱动着去使用某些功能,后来有点空闲总结了一下,水平不高,如有错误,希望原谅。
图像数字化
首先当然是要了解一些常规操作,比如说构造ndarray,mat等等。然后有几个地方很容易记错,比如说rows是行,cols是列,vec构造x*1的向量等等,这里就不赘述了。
几何变换
过了图像数字化这关之后就是了解一些几何变换,下面列出几种常见矩阵:
平移矩阵:
放缩矩阵
旋转矩阵
插值算法
其实说来插值算法就是一个矩阵:
那么怎么来算这个矩阵呢,有以下几种算法:
最近邻插值
这个很简单,大多数地方可以找到而且不常用,说说它的缺点:会出现锯齿外观。一般都是用双线性插值或者三次样条插值。
双线性插值
这里简单提一下双线性插值,因为我看算法的时候觉得这个还是有点意思。
第一步:|x - [x]|是点 (x,y) 和点 ([x], [y]) 的水平距离,|[x]+1-x|是点 (x,y) 和 点 ([x]+1, [y]) 的水平距离,显然0<|x - [x]|<1, 0<|[x]+1-x|<1且二者之和为1,所以可以根据下面的公式估计 f 在(x, [y])处的值:
第二步: 同第一步类似,|x - [x]|是点 (x,y) 和点 ([x], [y]) 的水平距离,|[x]+1-x|是点 (x,y) 和 点 ([x]+1, [y]) 的水平距离,显然0<|x - [x]|<1, 0<|[x]+1-x|<1且二者之和为1,所以可以根据下面的公式估计 f 在(x, [y]+1)处的值:
第三步:得到f 在(x, [y])和x, [y]+1)处的估计函数值后,我们需要进一步估计f在(x,y)处的函数值。由于(x,y)和(x, [y])的垂直距离为|y-[y]|, (x,y)和(x, [y]+1)的垂直距离为|[y]+1-y|,那么我们得到如下公式:
其他
除此之外还有投影变换和极坐标变化等等,投影变换主要就是用个变换矩阵,极坐标变换主要体现在实现上,这里也不赘述了。
对比度增强
首先我们要有灰度直方图的概念,简单说就是灰度占有率的描述直方图。
直方图正规化
其实就是一个公式:
那再讲一讲范数的概念好了:
1-范数:矩阵绝对值的和
2-范数:矩阵值的平方和的开方
∞-范数:矩阵值的绝对值的最大值
伽马变换
就是对每个灰度值进行乘方。
全局直方图均衡化
假设输入图像为I,高为H,宽为W,histI 代表 I 的灰度直方图,histI(k)代表灰度值等于k的像素点个数,其中k∈[0,255]。全局直方图均衡化操作是对图像I进行改变,使得输出图像O的灰度直方图histO是“平”的。即histO≈ HW/256,且满足:
其中等式两边称为I和O的累加直方图。又因为histO≈ HW/256,所以有:
化简可得:
上式给出一个从亮度级为p到亮度级为q的输出像素的映射,那么令:
其中I(r,c)是I的第r行第c列的灰度值,O(r,c)是对应位置输出的灰度值,其中r∈[0,H),c∈[0,W),然后就算出来输出图像O的每一个位置的灰度值。
限制对比度的直方图均衡化
简单地说就是多了就均分一下。
图像平滑
首先说一下卷积,譬如full卷积,valid卷积和same卷积啥的,建立一下基本概念。
二维离散卷积之full卷积
就是让I矩阵绕K矩阵一圈,然后通过乘法算出数值计入矩阵中:
但是很显然Opencv里不是这样做的,直接这样的话算法复杂度太高,所以Opencv里用了一些矩阵的变换。大致思路是这样的:
1、在I,K矩阵右侧和下侧填充0,将尺寸扩展到H*W,生成的新矩阵即为Ip,Kp;
2、将Ip按行堆叠,构成(H*W)*1的列向量Ipp;
3、将Kp的每一行构造一个W*W的循环矩阵;
4、得到的H个循环矩阵作为块,构造块循环矩阵G;
5、计算(H*W)*1的列向量C = G · Ipp;
6、将此列向量重排成H*W的矩阵,即所求。
二维离散卷积之valid卷积
很简单,其实就是两个矩阵的H、W不相同时出现的情况。