[OpenCV] 图像金字塔和图片缩放

发布时间 2023-04-17 09:36:08作者: 冷小男

高斯金字塔 : PyrDown 图像变小,细节减少

拉普拉斯金字塔 : PyrUp 图像变大 , 尽量弥补细节

Resize

CV_EXPORTS_W void resize( InputArray src, OutputArray dst,
                          Size dsize, double fx = 0, double fy = 0,
                          int interpolation = INTER_LINEAR );

第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。

第二个参数,OutputArray类型的dst,输出图像,当其非零时,有着dsize(第三个参数)的尺寸,或者由src.size()计算出来。

第三个参数,Size类型的dsize,输出图像的大小。如果它等于零,由下式进行计算:
dsize=Size(round(fx*src.cols),round(fy*src.rows))
其中,dsize、fx、fy都不能为0。

第四个参数,double类型的fx,沿水平轴的缩放系数,有默认值0,当其等于0时,由下式进行计算:

    (double)dsize.width/src.cols

第五个参数,double类型的y,沿垂直轶的缩放系数,有默认值0,当其等于0时,由下式进行计算:

    (double)dsize.height/src.rows

第六个参数,int类型的interpolation,用于指定插值方式,默认为

INTER_LINEAR(线性插值)。
可选的插值方式如下:
    INTER_NEAREST 最近邻插值
    INTER_LINEAR 线性插值
    INTER_AREA 区域插值
    INTER_CUBIC 三次样条插值
    INTER_LANCZOS4 lanczos插值

若要缩小图像,一般情况下最好用CV_INTER_AREA来插值;而若要放大图像,一般情况下最好用CV_INTER_CUBIC〔(效率不高,慢,不推荐使用)或CV_INTER_LINEAR(效率较高,速度较快,推荐使用)。

 

pyrUp

CV_EXPORTS_W void pyrUp( InputArray src, OutputArray dst,
                         const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );

第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。

第二个参数,OutputArray类型的dst,辈出图像,和源图片有一样的尺寸和类型。

第三个参数,constSize&类型的dstsize,输出图像的大小;有默认值Size(),即默认情况下,由Size〔(src.cols*2,src.rows*2) 来进行计算,且一直需要满足下列条件:

      | dstsize.width - src.cols*2 | <= (dstsize.width mod2)

      | dstsize.height- src.rows*2 | <= (dstsize.height mod2)

第四个参数,int类型的borderType 边界模式,一般不用去管它

 pyrDown

CV_EXPORTS_W void pyrDown( InputArray src, OutputArray dst,
                           const Size& dstsize = Size(), int borderType = BORDER_DEFAULT );

第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。

第二个参数,OutputArray类型的dst,辈出图像,和源图片有一样的尺寸和类型。

第三个参数,constSize&类型的dstsize,输出图像的大小;有默认值Size(),即默认情况下,由Size〔(src.cols/2,src.rows/2) 来进行计算,且一直需要满足下列条件:

      | dstsize.width*2 - src.cols | <= 2

      | dstsize.height*2- src.rows | <= 2

该pyrDown函数执行了高斯金字塔建造的向下采样的步骤。首先,它将源图像与如下内核做卷积运算:

 

 

综合练习: 

    /*
    程序要求: 
    使用resize pyrdown pyrup对图片进行操作
    按 1 或者 w ,进行resize放大
    按 2 或者 s ,进行resize缩小
    按 3 或者 a ,进行pyrup放大
    按 4 或者 d ,进行pydown缩小
    按 5 , 获取原图
    按q退出
    */
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include <iostream>
    using namespace cv;
    using namespace std;
    
    void image_control( int e,Mat **);
    
    int main() {
        Mat src = imread("C:/dev/cpp_test/kun.png");
        
        Mat dst ,tmp;
        src.copyTo(tmp);
        src.copyTo(dst);
        imshow("src",src);
        Mat* image_group[3] = {&tmp, &dst,&src};
        int key=0;
        while(true){
            key = waitKey(10);      
            image_control(key,image_group);
            if(key == '5'){cout<<"recovery"<<endl;dst=src;tmp=src;} // if press 5 ,recover to src image
            imshow("dst",dst);
        }
    
    
        return 0;
    } 
    
    void image_control(int e,Mat *image_group[]){
        Mat src = *image_group[0];
        Mat dst = *image_group[1];
        switch (e)
        {
        //exit
        case 'Q':
            cout << "Exit" <<endl;
            exit(0);
            break;
        case 'q':
            cout << "Exit" <<endl;
            exit(0);
            break;
        case 27:
            cout << "Exit" <<endl;
            exit(0);
            break;
            
        //resize expansion
        case 'W':
            cout <<"expansion" << endl;     
            resize(src,dst,Size(src.cols*2,src.rows*2));
            break;
        case 'w':
            cout <<"expansion" << endl;
            resize(src,dst,Size(src.cols*2,src.rows*2));
            break;
        case '1':
            cout <<"expansion" << endl;
            resize(src,dst,Size(src.cols*2,src.rows*2));
            break;
        //resize reduction
        case 'S':
            cout <<"reduction" << endl;
            resize(src,dst,Size(src.cols/2,src.rows/2));
            break;
        case 's':
            cout <<"reduction" << endl;
            resize(src,dst,Size(src.cols/2,src.rows/2));
            break;
        case '2':
            cout <<"reduction" << endl;
            resize(src,dst,Size(src.cols/2,src.rows/2));
            break;
        // pyramid Up
        case 'A':   
            cout <<"pyramid up" << endl;    
            pyrUp(src,dst,Size(src.cols*2,src.rows*2));
            break;
        case 'a':
            cout <<"pyramid up" << endl;
            pyrUp(src,dst,Size(src.cols*2,src.rows*2));
            break;
        case '3':
            cout <<"pyramid up" << endl;
            pyrUp(src,dst,Size(src.cols*2,src.rows*2));
            break;
        
        //pyramid Down
        case 'D':
            cout <<"pyramid down" << endl;      
            pyrDown(src,dst,Size(src.cols/2,src.rows/2));
            break;
        case 'd':
            cout <<"pyramid down" << endl;
            pyrDown(src,dst,Size(src.cols/2,src.rows/2));
            break;
        case '4':
            cout <<"pyramid down" << endl;
            pyrDown(src,dst,Size(src.cols/2,src.rows/2));
            break;
    
        
        }
        *image_group[0] = dst;
        *image_group[1] = dst;
    }

 

 threshold 固定阈值

CV_EXPORTS_W double threshold( InputArray src, OutputArray dst,
                               double thresh, double maxval, int type );

第一个参数,InputArray类型的src,输入数组,填单通道,8或32位浮点类型的Mat即可。

第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放输出结果,且和第一个参数中的Mat变量有一样的尺寸和类型。

第三个参数,double类型的thresh,阗值的具体值。

第四个参数,double类型的maxval,当第五个参数阀值类型type取CV_THRESH_BINARY或CV_THRESH_BINARY_INV时阗值类型时的最大值(对应地,OpenCV2中可以为CV_THRESH_BINARY和 CV_THRESH_BINARY_INV)。

第五个参数,int类型的type,阙值类型。threshold()函数支持的对图像取阙值的方法由其确定,具体用法如图6.70。

对应取值 0 ,1 ,2 ,3, 4

 adaptiveThreshold 自适应阈值

CV_EXPORTS_W void adaptiveThreshold( InputArray src, OutputArray dst,
                                     double maxValue, int adaptiveMethod,
                                     int thresholdType, int blockSize, double C );

第-个参数InputArray类型的src,输入图像,即源图像,填Mat类的对象即可,且需为8位单通道浮点型图像。

第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,需和源图片有一样的尺寸和类型。

第三个参数,double类型的maxValue,给像素赋的满足条件的非零值。具体看下面的讲解。

第四个参数,int类型的adaptiveMethod,用于指定要使用的自适应阈值算法,可取值为ADAPTIVE_THRESH_MEAN_C或ADAPTIVE_THRESH_GAUSSIAN_C。

第五个参数,int类型的thresholdType阈值类型。取值必须为THRESH_BINARY、THRESH_BINARY_INV其中之一。

第六个参数,int类型的blockSize, 用于计算阈值大小的一个像素的邻域尺寸,取值为3、5、7等。

第七个参数,double类型的C,减去平均或加权平均值后的常数值。通常其为正数,但少数情况下也可以为零或负数。


adaptiveThreshold()函数的类型根据如下公式,将衣服灰度图变换为一副二值图。

当第五个参数,“阈值类型” thresholdType取值为THRESH_BINARY时,公式如下:

 


当第五个参数,“阈值类型” thresholdType取值为THRESH_BINARY_INV时,公式为:

 


而其中的T(x,y)为分别计算每个单独像素的阈值,取值如下。

对于ADAPTIVE_THRESH_MEAN_C 方法,阈值 T(x,y)为blockSize X blockSize邻域内(x,y)减去第七个参数C的平均值

对于ADAPTIVE_THRESH_GUASSIAN_C方法,阈值T(x,y),为blockSize X blockSize邻域内的(x,y)减去第七个参数C 与高斯窗交叉相关(Cross-correlation with a Gaussian window)的加权总和