更改现有的cv :: Mat尺寸,同时保留适合新尺寸的内容

时间:2018-11-27 15:29:20

标签: c++ opencv

我收集了大小不同的cv :: Mat对象。我希望它们都具有与集合中最宽矩阵相同的列数。列数较少的矩阵应使用固定的颜色填充到右侧。本质上,我想要与Photoshop的“画布大小...”操作相同的功能。我应该如何在C ++中做到这一点?

cv::resize不会剪切它,因为它会拉伸内容,而不是填充内容。 cv::Mat::resize也不符合要求,因为它只能添加行,而不能添加列。

2 个答案:

答案 0 :(得分:2)

诀窍是创建具有所需尺寸的新矩阵,然后将数据从原始图像复制到表示保留数据的ROI:

// Creates a new matrix with size newSize with data copied from source.
// Source data outside the new size is discarded.
// If any of the dimensions of newSize is larger than that dimension in source,
// the extra area is filled with emptyColor.
cv::Mat resizeCanvas(const cv::Mat& source, cv::Size newSize, cv::Scalar emptyColor) {
    cv::Mat result(newSize, source.type(), emptyColor);

    int height = std::min(source.rows, newSize.height);
    int width = std::min(source.cols, newSize.width);
    cv::Rect roi(0, 0, width, height);

    auto sourceWindow = source(roi);
    auto targetWindow = result(roi);
    sourceWindow.copyTo(targetWindow);

    return result;
}

答案 1 :(得分:2)

您也可以使用copyMakeBorder

void resizeCanvas(const cv::Mat& src, cv::Mat& dst, const cv::Size& canvasSize, const cv::Scalar& emptyColor)
{
    if((canvasSize.height < src.rows) || canvasSize.width < src.cols) {
        // Canvas is smaller than source image
        return;
    }

    int bottom = canvasSize.height - src.rows;
    int right = canvasSize.width - src.cols;

    cv::copyMakeBorder(src, dst, 0 /*top*/, bottom, 0 /*left*/, right, cv::BORDER_CONSTANT, emptyColor);
}

用法:

cv::Mat3b img = cv::imread("...");
cv::Mat3b resized;
resizeCanvas(img, resized, cv::Size(1000, 1000), cv::Scalar(0,0,0,0));