1

我希望将给定 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的同一个内存地址吗?如果没有,如何将数据复制到行的某个部分?

4

1 回答 1

1

From the docs of cv::Mat::copyTo:

Before copying the data, the method invokes:

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

so that the destination matrix is reallocated if needed.

Reallocation is needed whenever the shape or data type of the destination does not match the source. In your case it's the shape. To demonstrate this, let's add some tracing around the copyTo call:

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";

Output:

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

The solution is simple -- reshape the source to match the destination.

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

Now we get the following output:

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

and rowVector contents are as follows:

[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]

As an alternative, you could just use std::copy together with MatIterators.

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

rowVector contents are the same as before:

[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]
于 2018-04-21T20:02:45.967 回答