我想裁剪一个cv::Mat
- 也就是说,不是简单地让它指向内存中更广泛的 metrix 的 ROI,而是真正摆脱除 ROI 中数据之外的所有原始数据。更重要的是,我需要我的界面与不返回垫子的 opencv 传统保持一致;本质上我想要这个:
void crop(cv::Mat& source, cv::Rect roi, cv::Mat& destination);
(但由于在我的情况下来源===目的地)它可能只是这样:
void crop(cv::Mat& mat, cv::Rect roi);
目前我正在这样做:
void crop(cv::Mat& original, cv::Rect roi) {
cv::Mat roi_in_original {original(roi)};
cv::Mat new_mat;
roi_in_original.copyTo(new_mat);
original = new_mat;
}
这不仅冗长,而且可能是次优的。S 将 ROI 直接复制到原始垫子是否合理:
void crop(cv::Mat& original, cv::Rect roi) {
cv::Mat roi_in_original {original(roi)};
roi_in_original.copyTo(original);
}
那可以吗??
我会将您的第一个版本更改为:
void crop(const Mat& src, const Rect& roi, Mat& dst)
{
dst = src(roi).clone();
}
其中输入参数const
.您可以将结果保存在同一个矩阵调用中:
Mat m = ...
Rect roi = ...
crop(m, roi, m);
我会将您的第二个版本更改为:
void crop( Mat& m, const Rect& roi)
{
m = m(roi).clone();
}
你可以这样使用:
Mat m = ...
Rect roi = ...
crop(m, roi);
请注意,在这两种情况下都需要调用 clone()
以使生成的矩阵连续,如您所料。
我个人更喜欢第一种变体,因为它更通用。但是,您也可以首先避免裁剪功能,因为它就像:
Mat m = ...
Rect roi = ...
m = m(roi).clone();
// Or, to save to a different matrix
//Mat n = m(roi).clone();