/*
* 图像金字塔-上采样与降采样
图像金字塔:比如1*1的图像,2*2的图像,4*4的图像,8*8的图像 ,把图像按照从小到大的顺序放在空间上的位置,如果从上向下形状就跟古埃及金字塔一样了
我们也可以把这些不同的看成图像的分辨率,从上向下看分辨率不断增加,增加分辨率的过程就可以看成向图片进行采样的过程,采样愈多图像分辨率越高
我们经常见到的两千万像素多少万像素就是指在同一张我们镜头对准的同一个地方一个是采样是500万,另一个是采样1000万,那肯定是采样1000万的清楚,
因为它采样点多更密集,如果它连续的根本不间断的那更厉害了
上采样:所以可以看出来金字塔从上往下是上采样,得到一个更高分辨率的图像,上采样和降采样还可以改变图像的大小:上采样得到的图像是原来图像宽高的两倍
降采样:金字塔从下往上,把8*8那张图作为模板向上进行的一个采样得到的4*4的图叫降采样, 降采样是得到的图像是原来图像的宽高的1/2
我们在图像处理中经常会调整图像大小,最常见的就是放大(zoom in)和缩小(zoom out),尽管几何变换也可以实现图像的放大和缩小,但是这里我们介绍图像金字塔
因为我们在图像处理当中,我们最常见的就是要通过图像金字塔产生一系列不同分辨率的图像,然后在不同的尺度空间去寻找我们图像对应的特征,因为我们不知道我们输入的
图像到底是个什么样的情况,因为图像的金字塔变换它是会保证特征一直存在的,这个是最重要的一个概念
一个图像金字塔是一系列的图像组成,最底下一张是图像尺寸最大,最上方的图像尺寸最小,从空间上从上向下看就像一个古代的金字塔
怎么得到图像金字塔:高斯金字塔-用来对图像进行降采样
拉普拉斯金字塔-用来重建一张图片,根据它的上层降采样图片
高斯金字塔:是从底向上逐层降采样得到(因为最底下那层是最大的,必须逐层采样不能隔一层之类的),降采样之后图像大小是原图像M*N的M/2 * N/2,就是对原图像删除偶数行与列,即得到降采样之后上一层的图片
高斯金字塔的生成过程分为两步:-对当前层进行高斯模糊
-删除当前层的偶数行与列
即可得到上一层的图像,这样上一层跟下一层相比,都只有它的1/4大小
做了高斯金字塔之后在每一层上要得到图像的特征就可以通过高斯不同或者拉普拉斯不同
高斯不同(Difference of Gaussian - DOG):就是把同一张图像在不同的参数下做高斯模糊之后的结果相减,的到的输出图像称为高斯不同(DOG)
高斯不同是图像的内在特征,在灰度图像增强、角点检测中经常用到
采样相关API:上采样(cv::pyrUp) -zoom in 放大 得到的金字塔分片不断的向底端方向发展
上采样的API:pyrUp(Mat src, Mat dest, Size(src.cols*2, src.rows*2)) 生成的图像是原图在宽与高各放大两倍
降采样(cv::pyrDown) -zoom out 缩小 向尖端发展就是向金字塔顶上发展叫不断的降采样
降采样的API:pyrDown(Mat src, Mat dest, Size(src.cols/2, src.rows/2)) 生成的图像是原图在宽与高各缩小1/2
*
*/
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat src;
src = imread("D:/A_Graduation/Learning/opencv/learningOpencv/1.png");
imshow("src", src);
//上采样
Mat res;
pyrUp(src, res, Size(src.cols*2, src.rows*2));
imshow("pyrUp", res);
//降采样
pyrDown(src, res, Size(src.cols/2, src.rows/2));
imshow("pyrDown", res);
//DOG高斯不同,跟高斯金字塔息息相关,因为得到高斯金字塔第一步之后我们并不是得到这个每一层的图像就算完事,然后对每一层的
//图像进行模糊,进行一个高斯模糊,这里我们就以原图像为例,不对每一层,因为对每一层进行模糊然后对每一层提取特征然后对每一层提取出来
//的不同层数然后跟原图像提取的特征进行匹配,看原图像匹配哪一层,然后上面的特征减下匹配就找到原图像的特征,对原图像进行识别了,讲起来就这么多
//但做起来是非常复杂的
//就对原图进行一个高斯分差,首先要把图像转换成灰度图像
Mat gray_src;
cvtColor(src, gray_src, CV_BGR2BGRA);
Mat g1, g2;
GaussianBlur(gray_src, g1, Size(3, 3), 0, 0); //用Size自动生成Σ,它会按照一定的算法进行生成
imshow("g1", g1);
GaussianBlur(g1, g2, Size(3, 3), 0, 0);//g1再进行模糊就得到g2,除了原图像和输出图像其他参数一定要保持一致,相当于是对它做了迭代的模糊
imshow("g2", g2);
//我们可以对每一层都进行迭代高斯模糊,每一层都可以得到DOG,得到的DOG图像对我们后面的处理在每一层上寻找特征很有作用
Mat dogImg;
subtract(g1, g2, dogImg, Mat()); //得到了模糊的结果后就g1 - g2(低的减去高的)就得到结果, 没有mask就用Mat()
//imshow("DOG", dogImg);
//归一化显示
//得到DOG的图像很模糊,高斯分叉得出来的差值非常低会反映灰度值的时候灰度也非常低,所以整个图像就很暗
//这时候normalize可以通过最大最小值把图像从0-255的空间给它scale到0-1之间去了,normalize同样可以把最小最大值的图像放大到0-255这个空间,然后看起来就很清楚了
normalize(dogImg, dogImg, 255, 0, NORM_MINMAX); //参数为最大最小值,norm_type l1l2就是两个值a跟b,计算a跟b之间最大最小的差值δ,把输入图像的每一个值减去最小值除以δ再乘以最大值255再加上最小值0,NORM_MINMAX就是通过这种方式归一化的,归一化0-255空间之后显示出来就不会太暗了
imshow("DOG", dogImg);
waitKey(0);
return 0;
}