一:图像金子塔概念
- 我们再图像处理中经常后调整图像的大小,最常见的就是放大和缩小,这是几何变换的放大和缩小。在图像处理当中,最常见的就是通过图像金子塔产生一系列不同分辨率的图像。然后再不同的尺度空间来寻找图像的对应特征。因为不知道输入的图像到底是什么情况,而图像金子塔处理会保证图像特征一直存在,不会改变的,这是重要一点。
- 一个图像 像金子塔样式有一系列的图像组成,最底下一张是图像最大的,最上方是图像尺寸最小的,从空间上从上向下看,就像一个金子塔一样。
二:方法
再OpenCv中有两种方法:
- 高斯金子塔 – 用来对图像进行降采样
- 拉普拉斯金子塔 – 用来重建一张图片根据它的上层降采样图片。
高斯金子塔:
- 高斯金子塔是从低向上,逐层降采样得到。
- 降采样之后图像大小是原图像 M ∗ N M*N M∗N (宽乘高)的 M / 2 ∗ N / 2 M/2*N/2 M/2∗N/2 ,就是对原图像删除偶数行与列,即得到降采样上一层图片。
- 高斯金子塔采样分为两步:
1:对当前图像进行高斯模糊
2:删除当前层的偶数行列
即可得到上一层图像,这样上一次与下一层相比,都只有它的 1 / 4 1/4 1/4大小。
1 16 [ 1 4 6 4 1 4 16 24 16 4 6 24 36 24 6 4 16 24 16 4 1 4 6 4 1 ] \frac{1}{16}\left[ \begin{matrix} 1 & 4 & 6&4&1 \\ 4 & 16 & 24&16&4 \\ 6 & 24 & 36&24&6 \\ 4 & 16 & 24&16&4 \\ 1 & 4 & 6&4&1 \\ \end{matrix} \right] 161⎣⎢⎢⎢⎢⎡1464141624164624362464162416414641⎦⎥⎥⎥⎥⎤
高斯不同概念:
Difference of Gaussian – DOG
- 定义:就是把同一张图像再不同的参数下作高斯模糊之后的结果相减,得到的输出图像成为高斯不同 (DOG)
- 高斯不同是图像的内在特征,再灰度图像增强,角点检测中经常用到。
三:相关API:
上采样:Cv2.PyrUp:对图像进行上采样(放大),然后使其模糊。
参数 | 说明 |
---|---|
InputArray src | 输入图像 |
OutputArray dst | 输出图像。它具有指定的大小和与src相同的类型。 |
Size? dstSize = null | 输出图像的大小;默认情况下 Size(src.cols2, (src.rows2) |
borderType = BorderTypes.Reflect101 | 边缘处理方法 |
降采样 Cv2.PyrDown:模糊图像并对其进行降采样(缩小)。
参数 | 说明 |
---|---|
InputArray src | 输入图像 |
OutputArray dst | 输出图像。它具有指定的大小和与src相同的类型。 |
Size? dstSize = null | 输出图像的大小;默认情况下 Size(src.cols/2, (src.rows/2) |
borderType = BorderTypes.Reflect101 | 边缘处理方法 |
高斯不同 Cv2.Subtract:计算两个数组或数组与标量之间的每个元素差
参数 | 描述 |
---|---|
InputArray src1 | 第一个源数组 |
InputArray src2 | 第二个源数组。它必须具有与src1相同的大小和类型 |
OutputArray dst | 目标数组;它将具有与src1相同的大小和类型 |
InputArray mask = null | 可选操作掩码,8位单通道阵列;指定要更改的目标数组的元素。[默认为空] |
int dtype = -1 | 图像深度 默认为 -1 |
四:代码
上采样和降采样:
private static void Sampling(string path)
{
using (Mat src = new Mat(path, ImreadModes.AnyColor | ImreadModes.AnyDepth))
using (Mat dst = new Mat())
{
//上采样 放大两倍
Cv2.PyrUp(src, dst,new Size(src.Cols*2,src.Rows*2),BorderTypes.Default);
Mat mat = new Mat();
//降采样 缩小两倍
Cv2.PyrDown(src, mat, new Size(src.Cols / 2, src.Rows / 2), BorderTypes.Default);
using (new Window("Down", WindowMode.AutoSize, mat))
using (new Window("InputImage",WindowMode.AutoSize,src))
using (new Window("UP", WindowMode.AutoSize, dst))
{
Cv2.WaitKey(0);
}
}
}
高斯不同 DOG:
/// <summary>
/// 图像采样
/// </summary>
private static void ImageSampling(string path)
{
using (Mat src = new Mat(path, ImreadModes.AnyColor | ImreadModes.AnyDepth))
using (Mat dst = new Mat())
{
Mat dst2 = new Mat();
//上采样
Cv2.PyrUp(src, dst, new Size(src.Cols * 2, src.Rows * 2), BorderTypes.Default);
//降采样
Cv2.PyrDown(src, dst2, new Size(src.Cols / 2, src.Rows / 2), BorderTypes.Default);
//高斯不同DOG
/*
* 1:转为灰度图
* 2:高斯模糊(归一化处理)-模型一直
* 3:再次高斯模糊(归一化处理)-模型一直
* 4:得到分差dog
*/
Mat dogImg = new Mat();
Mat g1 = new Mat();
Mat g2 = new Mat();
Mat gray_src = new Mat();
Cv2.CvtColor(src, gray_src, ColorConversionCodes.BGR2GRAY); //转为灰度图像
Cv2.GaussianBlur(gray_src, g1, new Size(3, 3), 0, 0);//高斯模糊(滤波)
Cv2.GaussianBlur(g1, g2, new Size(3, 3), 0, 0);
Cv2.Subtract(g1, g2, dogImg); //获取分差图像 g1-g2=dogImg ,灰度图像可能看不清楚(高斯模糊得到的像素值很低)
/* Normalize
* 该函数归一化输入数组使它的范数或者数值范围在一定的范围内
* 参数:
* 1 src 输入数组
* 2 dst 输出数组,支持原地运算
* 3 alpha range normalization模式的最小值
* 4 beta range normalization模式的最大值,不用于norm normalization(范数归一化)模式。
* 5 normType 归一化的类型,可以有以下的取值:
* NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用。
* NORM_INF: 此类型的定义没有查到,根据OpenCV 1的对应项,可能是归一化数组的C-范数(绝对值的最大值)
* NORM_L1 : 归一化数组的L1-范数(绝对值的和)
* NORM_L2: 归一化数组的(欧几里德)L2-范数
* 6 dtype dtype为负数时,输出数组的type与输入数组的type相同;
* 否则,输出数组与输入数组只是通道数相同,而tpye=CV_MAT_DEPTH(dtype).
* 7 mask 操作掩膜,用于指示函数是否仅仅对指定的元素进行操作。
*/
Cv2.Normalize(dogImg, dogImg, 255, 0, NormTypes.MinMax); //放大图像(归一化显示)
using (new Window("Output Subtract", WindowMode.AutoSize, dogImg))
using (new Window("Output DownSmapl", WindowMode.AutoSize, dst2))
using (new Window("Output UPSmapl", WindowMode.AutoSize, dst))
using (new Window("Input SRC", WindowMode.AutoSize, src))
{
Cv2.WaitKey(0);
}
}
}