当前位置:网站首页>Image scaling with aspect ratio preserving by opencv

Image scaling with aspect ratio preserving by opencv

2022-06-11 03:36:00 szfhy

It's been done before C For aspect ratio maintenance RGB Image zoom , In fact, the computational efficiency is not high .

opencv Many implementations of are built-in mmx, sse Accelerated . So let's study how to use opencv To achieve aspect ratio preserving image scaling .

Have a look opencv resize Detailed definition of function :

resize function

The function prototype :

void cv::resize( 
InputArray _src, 
OutputArray _dst, 
Size dsize,
double inv_scale_x = 0,
double inv_scale_y = 0, 
int interpolation = INTER_LINEAR 
)

Parameter description :

  • src, The input image ,Mat The type is enough ;

  • dst, Output image , When it is non-zero , with dsize( The third parameter ) The size of or having src.size() Work it out ;

  • dsize, The size of the output image . If it's equal to 0, It is calculated from the following formula :

     dsize = Size( round(fx*src.cols, round(fy*src.rows)));
     among fx,fy,dsize Can't do it 0
    
  • fx, Scaling factor along the horizontal axis , The default value is 0, And it's equal to 0 when , It is calculated from the following formula :

     inv_scale_x = (double)dsize.width/ssize.width;
    
  • fy, Scaling factor along the vertical axis , The default value is 0, And it's equal to 0 when , It is calculated from the following formula :

     inv_scale_y = (double)dsize.height/ssize.height;
    
  • interpolation, Used to specify the interpolation method , The default value is INTER_LINEAR( linear interpolation ), The optional interpolation methods are as follows :

Value explain
INTER_NEAREST Nearest neighbor interpolation
INTER_LINEAR linear interpolation ( The default value is )
INTER_AREA Area interpolation ( Resampling interpolation using pixel region relationship )
INTER_CUBIC Cubic spline interpolation ( exceed 4×4 Bicubic interpolation in pixel domain )
INTER_LANCZOS4Lanczos interpolation ( exceed 8×8 Pixel neighborhood Lanczos interpolation )

Be careful : To reduce the image , In general INTER_AREA To interpolate ; And to enlarge the image , In general INTER_CUBIC( The efficiency is not high , Not recommended ) or INTER_LINEAR( Efficient , recommend )

But this function can not realize the image scaling with arbitrary aspect ratio .

Think about it , You can do it first crop operation , And then zoom , A two-step , This allows for image scaling with aspect ratio preserved .

The code is as follows :

#include "opencv2/opencv.hpp"
#include "opencv2/opencv.hpp"
#include<fstream>
#include <chrono>

using namespace std;
using namespace cv;

int main(int, char**)
{
    cv::Size szSize(3840 , 2160);
    uchar *b_Buffer = new uchar[szSize.width * szSize.height * 2];
    uchar *rgb_Buffer = new uchar[szSize.width * szSize.height * 3];

    string binFile("input.yuv");
    ifstream File_VideoFile;
    File_VideoFile.open(binFile, ios::in | ios::binary);

    if (!File_VideoFile.is_open())
    {
        std::cerr << "[ERROR] cannot open the YUV Input File " << binFile << endl;
        std::cerr << std::endl;
        assert(0);
    }
    File_VideoFile.read((char*)b_Buffer, sizeof(uchar)*szSize.width*szSize.height*2);
    File_VideoFile.close();

    cv::Mat mSrc(szSize,CV_8UC2, b_Buffer);
    cv::Mat mSrc_BGR(szSize, CV_8UC3);

    auto time1 = std::chrono::steady_clock::now();
    cvtColor(mSrc, mSrc_BGR, COLOR_YUV2BGR_YUYV);
    auto time2 = std::chrono::steady_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(time2-time1).count();
    printf("cv time: %.2f ms.\n", (float)duration / 1000);

    Size dstSize(1600, 1600);
    Size srcSize(3840, 2160);
    Mat dst_img(dstSize, CV_8UC3);
    //crop first
    double fx = dstSize.width / srcSize.width;
    double fy = dstSize.height / srcSize.height;
    int xmin = 0, xmax = 0;
    int ymin = 0, ymax = 0;
    if (fx > fy) {
        //crop y
        xmin = 0;
        xmax = srcSize.width;
        ymin = (srcSize.height - srcSize.width) >> 1;
        ymax = srcSize.height - ymin;
    } else {
        //crop x
        ymin = 0;
        ymax = srcSize.height;
        xmin = (srcSize.width - srcSize.height) >> 1;
        xmax = srcSize.width - xmin;
    }
    Mat crop_img = mSrc_BGR(Range(ymin, ymax), Range(xmin, xmax));
    //scale second
    resize(crop_img, dst_img, dstSize);

	


    imwrite( "dst.bmp", dst_img);

    imwrite( "rgb24.bmp", mSrc_BGR);

    delete[] b_Buffer;
    delete[] rgb_Buffer;
    return 0;
}

原网站

版权声明
本文为[szfhy]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206110316479780.html