【问题标题】:create cv::Mat header for a certain range within another allocated matrix在另一个分配的矩阵中为某个范围创建 cv::Mat 标头
【发布时间】:2018-10-02 04:40:01
【问题描述】:

我希望将给定 ColumnVector 的值右移并复制到另一个比 ColumnVector 大一个元素的 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("%d\t", *(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("%d\t", rowVector_rangeHeader.ptr<int>(0)[c]); // displays 13
}

printf("\n---------------------------------\n");
for (int c = 0; c < yDimLen + 1; c++)
{
    printf("%d\t", rowVector.ptr<int>(0)[c]); // displays 0 !!!
}

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

【问题讨论】:

    标签: c++ opencv opencv-mat


    【解决方案1】:

    来自the docs of 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::copyMatIterators 一起使用。

    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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-30
      • 2021-11-16
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2019-05-04
      相关资源
      最近更新 更多