如何在opencv中交换Mat行?

Posted

技术标签:

【中文标题】如何在opencv中交换Mat行?【英文标题】:How to swap rows of Mat in opencv? 【发布时间】:2020-09-17 03:06:11 【问题描述】:

我想在Mat M 中交换两行,我有两个小问题:

    要交换两行,我需要一个MatrixRow temp(伪代码)来备份要替换的第一行。但是我不知道Mat的一行应该是什么类型。

Mat temp = img.row(i).clone();
img.row(i) = img.row(j).clone();
img.row(j) = temp.clone();

这段代码没有改变img,为什么?

【问题讨论】:

这里的 i 和 j 是什么?他们在循环吗? @YunusTemurlenk:是的。 【参考方案1】:
img.row(i) = img.row(j).clone();

img.row(j) = temp.clone();

不要复制克隆的数据,因为它们调用了以下赋值运算符

Mat& cv::Mat::operator= (const Mat& m)  

见documentation

矩阵赋值是一个 O(1) 运算。这意味着没有数据 复制但数据是共享的,并且引用计数器(如果有)是 递增。

要进行复制,您可以使用another assignment operator:

Mat& cv::Mat::operator= (const MatExpr& expr)

详情请见matrix expressions。

因此,您可以执行以下操作来实际复制数据。

img.row(i) = img.row(j).clone() + 0;
img.row(j) = temp.clone() + 0;

而且,您不需要克隆。所以可以写成

img.row(i) = img.row(j) + 0;
img.row(j) = temp + 0;

这里,img.row(j) + 0 创建了一个矩阵表达式,因此您在img.row(i) = img.row(j) + 0; 中调用Mat& cv::Mat::operator= (const MatExpr& expr) 赋值运算符。

另一种选择是按照其他答案所述复制数据。您可以为此使用Mat::copyTo

更多详情,请参阅documentation 中的注释

Mat cv::Mat::row(int y) const

它用例子解释了这一点。

【讨论】:

在你写答案之前,我实际上发现img.row(j).copyTo(img.row(i)) 有效,我从他们的教程中读到了你的第一句话的结论:只复制了标题。 + 0 技术对我来说是一个新想法,如果你能详细说明它,我会感谢你的工作。总之,你解决了我的问题,谢谢! 这学期我正在学习OpenCV,你可以关注我的id来回答我的问题,如果你的答案都这么高质量,我会一直投票给你。 @Raining img.row(j) + 0 创建一个矩阵表达式,因此您在img.row(i) = img.row(j) + 0; 中调用Mat& cv::Mat::operator= (const MatExpr& expr) 赋值运算符。 我会建议您更新您的答案,或者,(如果我有空闲时间)我将通过将我认为对我有帮助的内容附加到您的答案中来帮助您编辑您的答案。【参考方案2】:

建议您使用以下步骤,而不是使用克隆:

    创建一个大小为 1 行 x n 列的临时垫,其中 n 是图像的宽度 借助 for 循环将第 i 行的像素值复制到临时垫中 使用相同的 for 循环技术将像素值从第 j 行复制到第 i 行 将像素值从临时垫子复制到第 j 行

这是基于我从提供的信息中理解的解决方案。

【讨论】:

但是我想要代码,抱歉这实际上并没有帮助......仍然感谢您的时间。

以上是关于如何在opencv中交换Mat行?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不同线程的 C++/CLI 中将图像数据从 BitmapSource (WPF) 复制到 cv::Mat (OpenCV)?

如何在 Opencv 中显示一个 Mat

高效地在 OpenCV Mat 中查找元素

如何在 Python 中使用 OpenCV 创建 Mat 矩阵?

opencv编程中cvMat到Mat如何进行数据转换?

打印 cv::Mat opencv