在另一个分配的矩阵中为特定范围创建 cv::Mat 标头

create cv::Mat header for a certain range within another allocated matrix

本文关键字:范围 创建 cv Mat 标头 分配 另一个      更新时间:2023-10-16

我希望给定的 ColumnVector 的值被右移并复制到另一个比 ColumnVector 大 1 elemnt 的 RowVector。我想通过将columnVector复制到RowVector中的某个范围来实现这一点。

// The given columnVector ( this code snippet is added to make the error reproducable)
int yDimLen = 26; // arbitrary value
cv::Mat columnVector(yDimLen, 1, CV_32SC1, cv::Scalar(13)); // one column AND yDimLen rows
for (int r = 0; r < yDimLen; r++)   // chech the values
{
    printf("%dt", *(columnVector.ptr<int>(r)));
}
// Copy elemnets of columnVector to rowVector starting from column number 1
cv::Mat rowVector(1, yDimLen + 1, CV_32SC1, cv::Scalar(0));
cv::Mat rowVector_rangeHeader = rowVector.colRange(cv::Range(1, yDimLen + 1)); // header matrix, 1 in included AND (yDimLen + 1) is excluded
columnVector.copyTo(rowVector_rangeHeader);
// check the values
printf("n---------------------------------n");
for (int c = 0; c < yDimLen; c++)
{
    printf("%dt", rowVector_rangeHeader.ptr<int>(0)[c]); // displays 13
}
printf("n---------------------------------n");
for (int c = 0; c < yDimLen + 1; c++)
{
    printf("%dt", rowVector.ptr<int>(0)[c]); // displays 0 !!!
}

标头矩阵是否不指向包含rowVector的相同内存地址? 如果没有,如何将数据复制到行的某个部分?

来自cv::Mat::copyTo的文档:

在复制数据之前,该方法调用:

m.create(this->size(), this->type());

以便在需要时重新分配目标矩阵。

每当目标的形状或数据类型与源不匹配时,都需要重新分配。在你的例子中,它是形状。为了演示这一点,让我们围绕copyTo调用添加一些跟踪:

std::cout << "Shapes involved in `copyTo`:n";
std::cout << "Source: " << columnVector.size() << "n";
std::cout << "Destination: " << rowVector_rangeHeader.size() << "n";
columnVector.copyTo(rowVector_rangeHeader);
std::cout << "After the `copyTo`:n";
std::cout << "Destination: " << rowVector_rangeHeader.size() << "n";

输出:

Shapes involved in `copyTo`:
Source: [1 x 26]
Destination: [26 x 1]
After the `copyTo`:
Destination: [1 x 26]

解决方案很简单 - reshape源以匹配目标。

columnVector.reshape(1, 1).copyTo(rowVector_rangeHeader);

现在我们得到以下输出:

Shapes involved in `copyTo`:
Source: [1 x 26]
Destination: [26 x 1]
After the `copyTo`:
Destination: [26 x 1]

rowVector内容如下:

[0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13]

作为替代方案,您可以将std::copyMatIterator一起使用。

std::copy(columnVector.begin<int>()
    , columnVector.end<int>()
    , rowVector_rangeHeader.begin<int>());

rowVector内容与以前相同:

[0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13]