我收集了大小不同的cv :: Mat对象。我希望它们都具有与集合中最宽矩阵相同的列数。列数较少的矩阵应使用固定的颜色填充到右侧。本质上,我想要与Photoshop的“画布大小...”操作相同的功能。我应该如何在C ++中做到这一点?
cv::resize不会剪切它,因为它会拉伸内容,而不是填充内容。 cv::Mat::resize也不符合要求,因为它只能添加行,而不能添加列。
答案 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));