将图像调整为正方形但保持纵横比c ++ opencv

MLM*_*LTL 10 c++ opencv image image-resizing

有没有办法调整任何形状或大小[500x500]的图像,但要保持图像的纵横比,空白空间填充白色/黑色填充物?

所以说图像是[2000x1000]在调整尺寸以[500x500]使实际图像本身成为之后[500x250],125任何一面都是白色/黑色填充物.

像这样的东西:

输入

在此输入图像描述

产量

在此输入图像描述

编辑

我不希望简单地在方形窗口中显示图像,而是将图像更改为该状态,然后保存到文件中,创建尽可能少的图像失真的相同尺寸图像的集合.

我遇到的唯一一个问类似问题的是这篇文章,但是它的内容php.

Ros*_*chi 14

没有完全优化,但你可以试试这个:

EDIT处理非500x500像素的目标大小并将其作为函数包装起来.

cv::Mat GetSquareImage( const cv::Mat& img, int target_width = 500 )
{
    int width = img.cols,
       height = img.rows;

    cv::Mat square = cv::Mat::zeros( target_width, target_width, img.type() );

    int max_dim = ( width >= height ) ? width : height;
    float scale = ( ( float ) target_width ) / max_dim;
    cv::Rect roi;
    if ( width >= height )
    {
        roi.width = target_width;
        roi.x = 0;
        roi.height = height * scale;
        roi.y = ( target_width - roi.height ) / 2;
    }
    else
    {
        roi.y = 0;
        roi.height = target_width;
        roi.width = width * scale;
        roi.x = ( target_width - roi.width ) / 2;
    }

    cv::resize( img, square( roi ), roi.size() );

    return square;
}
Run Code Online (Sandbox Code Playgroud)


ali*_*eza 7

一般方法:

cv::Mat utilites::resizeKeepAspectRatio(const cv::Mat &input, const cv::Size &dstSize, const cv::Scalar &bgcolor)
{
    cv::Mat output;

    double h1 = dstSize.width * (input.rows/(double)input.cols);
    double w2 = dstSize.height * (input.cols/(double)input.rows);
    if( h1 <= dstSize.height) {
        cv::resize( input, output, cv::Size(dstSize.width, h1));
    } else {
        cv::resize( input, output, cv::Size(w2, dstSize.height));
    }

    int top = (dstSize.height-output.rows) / 2;
    int down = (dstSize.height-output.rows+1) / 2;
    int left = (dstSize.width - output.cols) / 2;
    int right = (dstSize.width - output.cols+1) / 2;

    cv::copyMakeBorder(output, output, top, down, left, right, cv::BORDER_CONSTANT, bgcolor );

    return output;
}
Run Code Online (Sandbox Code Playgroud)


Dra*_*jić 5

Alireza的答案很好,但是我稍微修改了代码,以便当图像垂直适合时我不添加垂直边框,并且当图像水平适合时我不添加水平边框(这更接近原始请求):

cv::Mat utilites::resizeKeepAspectRatio(const cv::Mat &input, const cv::Size &dstSize, const cv::Scalar &bgcolor)
{
    cv::Mat output;

    // initially no borders
    int top = 0;
    int down = 0;
    int left = 0;
    int right = 0;
    if( h1 <= dstSize.height) 
    {
        // only vertical borders
        top = (dstSize.height - h1) / 2;
        down = top;
        cv::resize( input, output, cv::Size(dstSize.width, h1));
    } 
    else 
    {
        // only horizontal borders
        left = (dstSize.width - w2) / 2;
        right = left;
        cv::resize( input, output, cv::Size(w2, dstSize.height));
    }

    return output;
}
Run Code Online (Sandbox Code Playgroud)