opencv學習(二十七)之圖像縮放函數resize

上一篇介紹了分別利用高斯金字塔和拉普拉斯金字塔結合opencv提供的pyrDown和pyrUp函數實現了圖像的縮放,opencv還提供了另外一種圖像縮放函數resize()實現對輸入圖像縮放到指定大小,其函數原型如下:

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

參數解釋:
. InputArray src: 輸入圖像,可以是Mat類型
. OutputArray dst: 輸出圖像,其尺寸由第三個參數dsize(如果dsize不爲0),當dsize爲0,輸出圖像的尺寸由src.size()、fx和fy計算得到,但是輸出圖像類型與輸入圖像一致
. Size dsize: 輸出圖像的尺寸,如果dsize設置爲0,則dsize的值將由下式計算得到

dsize=Size(round(fx*src.cols), round(fy*src.rows))

需要注意的是dsize和fx、fy不能同時爲0

. double fx = 0: 水平方向上的縮放係數,當fx爲0時,將由如下公式計算得到

(double)dsize.width/src.cols

. double fy = 0: 垂直方向上的縮放係數,如果fy爲0,將由如下公式計算得到

(double)dsize.height/src.rows

. int interpolation=INTER_LINEAR: 圖像縮放的插值算法類型,默認是INTER_LINEAR(線性插值),在opencv3.2中通過查看InterpolationFlags查看詳細信息,可選的插值方式如下:
這裏寫圖片描述

以上的情況是沒有初始化目標圖像的類型和尺寸也就是沒有提前設置好目標圖像的類型和尺寸而是由函數根據size.size,dsize,fx和fy計算得到,如果想調整輸入圖像適應已經創建好的目標圖像的時候應該這樣調用resize()函數:

resize(src, dst, dst.size(), 0, 0, interpolation);

如果指定圖像在水平方向和垂直方向的縮放係數,則調用方式如下:

resize(src, dst, Size(), 0.5, 0.5, interpolation);

一般情況下,如果要縮小桐鄉用cv::INTER_AREA算法實現,而放大圖像如果想取得較好的效果則使用cv::INTER_CUBIC,此插值算法效果好但是速度慢,而cv::INTER_LINEAR插值相對較快而且效果也是可以接受。

示例程序:

/*
 *程序主要演示了不同的插值算法在圖像縮放中效果不同
 *其中圖像放大圖像原圖像用的是縮小後的圖像
 *也可以將g_shrinkImage改爲g_srcImage觀察直接從原圖像放大效果
*/

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

//定義全局變量
Mat g_srcImage;
Mat g_shrinkImage;
Mat g_enlargeImage;

//定義軌跡條屬性
const int resizeTypeMaxValue = 4;   //共八種插值運算類型
int resizeTypeValue = 0;

//聲明類型轉換函數
int typeDef(int typeNum);

//聲明回調函數
void shrinkFun(int, void*);
void enlargeFun(int, void*);

int main()
{
    g_srcImage = imread("resize.jpg");

    //判斷文件是否加載成功
    if(!g_srcImage.data)
    {
        cout << "圖像加載失敗!" << endl;
        return -1;
    }
    else
        cout << "圖像加載成功!" << endl << endl;

    namedWindow("原圖像", WINDOW_AUTOSIZE);
    imshow("原圖像", g_srcImage);

    //軌跡條屬性
    char resizeTypeName[20];
    sprintf(resizeTypeName, "插值運算類型 %d", resizeTypeMaxValue);

    namedWindow("圖像縮小", WINDOW_AUTOSIZE);
    namedWindow("圖像放大", WINDOW_AUTOSIZE);

    //創建軌跡條
    createTrackbar(resizeTypeName, "圖像縮小", &resizeTypeValue, resizeTypeMaxValue, shrinkFun);
    shrinkFun(resizeTypeValue, 0);

    createTrackbar(resizeTypeName, "圖像放大", &resizeTypeValue, resizeTypeMaxValue, enlargeFun);
    enlargeFun(resizeTypeValue, 0);

    waitKey(0);

    return 0;
}

int typeDef(int typeNum)
{
    int type;

    switch(typeNum)
    {
    case 0:
            type = INTER_NEAREST; break;
    case 1:
            type = INTER_LINEAR; break;
    case 2:
            type = INTER_CUBIC; break;
    case 3:
            type = INTER_AREA; break;
    case 4:
            type = INTER_LANCZOS4; break;
    default:
            break;
    }

    return type;

}

//圖像縮小函數
void shrinkFun(int, void*)
{
    int shrinkType;
    shrinkType = typeDef(resizeTypeValue);
    resize(g_srcImage, g_shrinkImage, Size(g_srcImage.cols/2, g_srcImage.rows/2), 0, 0, shrinkType);
    imshow("圖像縮小", g_shrinkImage);
}

//圖像放大函數
void enlargeFun(int, void*)
{
    int enlargeType;
    enlargeType = typeDef(resizeTypeValue);
    resize(g_shrinkImage, g_enlargeImage, Size(g_shrinkImage.cols*2, g_shrinkImage.rows*2), 0, 0, enlargeType);
    imshow("圖像放大", g_enlargeImage);
}

程序運行結果如下:
這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章