如何在opencv中交换Mat的行?

问题描述

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

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

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

代码不会更改img,为什么?

解决方法

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创建一个矩阵表达式,因此您在Mat& cv::Mat::operator= (const MatExpr& expr)中调用img.row(i) = img.row(j) + 0;赋值运算符。

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

有关更多详细信息,请参见documentation中的注释

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

通过示例对此进行解释。

,

我建议您使用以下步骤来代替克隆,

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

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