以前的时候用OpenCV老是不太清楚其中的算法,只是任务驱动着去使用某些功能,后来有点空闲总结了一下,水平不高,如有错误,希望原谅。

图像数字化

首先当然是要了解一些常规操作,比如说构造ndarray,mat等等。然后有几个地方很容易记错,比如说rows是行,cols是列,vec构造x*1的向量等等,这里就不赘述了。

几何变换

过了图像数字化这关之后就是了解一些几何变换,下面列出几种常见矩阵:


平移矩阵:

opencv指数和幂数 opencv常用算法_插值

放缩矩阵

opencv指数和幂数 opencv常用算法_插值_02

旋转矩阵

opencv指数和幂数 opencv常用算法_插值_03

插值算法

其实说来插值算法就是一个矩阵:

opencv指数和幂数 opencv常用算法_opencv指数和幂数_04

那么怎么来算这个矩阵呢,有以下几种算法:

最近邻插值

这个很简单,大多数地方可以找到而且不常用,说说它的缺点:会出现锯齿外观。一般都是用双线性插值或者三次样条插值。

双线性插值

这里简单提一下双线性插值,因为我看算法的时候觉得这个还是有点意思。

第一步:|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])处的值:

opencv指数和幂数 opencv常用算法_灰度值_05

第二步: 同第一步类似,|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)处的值:

opencv指数和幂数 opencv常用算法_卷积_06

第三步:得到f 在(x, [y])和x, [y]+1)处的估计函数值后,我们需要进一步估计f在(x,y)处的函数值。由于(x,y)和(x, [y])的垂直距离为|y-[y]|, (x,y)和(x, [y]+1)的垂直距离为|[y]+1-y|,那么我们得到如下公式:

opencv指数和幂数 opencv常用算法_opencv指数和幂数_07

其他

除此之外还有投影变换和极坐标变化等等,投影变换主要就是用个变换矩阵,极坐标变换主要体现在实现上,这里也不赘述了。

对比度增强

首先我们要有灰度直方图的概念,简单说就是灰度占有率的描述直方图。

直方图正规化

其实就是一个公式:

opencv指数和幂数 opencv常用算法_opencv指数和幂数_08


那再讲一讲范数的概念好了:

1-范数:矩阵绝对值的和

2-范数:矩阵值的平方和的开方

∞-范数:矩阵值的绝对值的最大值

伽马变换

就是对每个灰度值进行乘方。

全局直方图均衡化

假设输入图像为I,高为H,宽为W,histI 代表 I 的灰度直方图,histI(k)代表灰度值等于k的像素点个数,其中k∈[0,255]。全局直方图均衡化操作是对图像I进行改变,使得输出图像O的灰度直方图histO是“平”的。即histO≈ HW/256,且满足:

opencv指数和幂数 opencv常用算法_opencv指数和幂数_09


其中等式两边称为I和O的累加直方图。又因为histO≈ H
W/256,所以有:

opencv指数和幂数 opencv常用算法_卷积_10


化简可得:

opencv指数和幂数 opencv常用算法_卷积_11


上式给出一个从亮度级为p到亮度级为q的输出像素的映射,那么令:

opencv指数和幂数 opencv常用算法_插值_12


其中I(r,c)是I的第r行第c列的灰度值,O(r,c)是对应位置输出的灰度值,其中r∈[0,H),c∈[0,W),然后就算出来输出图像O的每一个位置的灰度值。

限制对比度的直方图均衡化

简单地说就是多了就均分一下。

图像平滑

首先说一下卷积,譬如full卷积,valid卷积和same卷积啥的,建立一下基本概念。

二维离散卷积之full卷积

opencv指数和幂数 opencv常用算法_opencv指数和幂数_13


就是让I矩阵绕K矩阵一圈,然后通过乘法算出数值计入矩阵中:

opencv指数和幂数 opencv常用算法_卷积_14


但是很显然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不相同时出现的情况。