Reputation: 91
I am rewriting some legacy code that does matrix operations on doubles using a raw C-style array. Since the code already has a dependency on OpenCV somewhere else, I want to use the cv::Mat
class instead.
The specific code that bothers me works on square matrixes from size 1*1 to NN. It does so by allocating an NN buffer and uses a subset of it for smaller matrixes.
double* buf = new double[NxN];
for (int i = 1; i < N; ++i) {
// Reuse buf to create a i*i matrix and perform matrix operations
...
}
delete[] buf;
Basically, I want to replace that code to use cv::Mat
objects in the loop instead. Problem is, the code requires a lot of loop iterations (there are nested loops and so on) and there are too many allocations/deallocations if I just use the naïve and clean approach. Therefore, I want to reserve the size of my matrix object beforehand and resize it for each iteration. This would ideally look like this:
cv::Mat m;
m.reserveBuffer(N * N * sizeof(double));
for (int i = 1; i < N; ++i) {
m = cv::Mat(i, i, CV_64F);
// Perform matrix operations on m
...
}
But in my understanding this would simply drop the previous instance of m
and then allocate a i*i matrix. What would the right approach be?
Upvotes: 1
Views: 1465
Reputation: 1647
You can create a submatix header for your buffer using cv::Mat::operator()
. Pass a cv::Rect
for ROI you want to process in current loop iteration ({0, 0, i, i}
in your case) and it will return a view of your buffer region as another cv::Mat
instance. It will not allocate new buffer but will refer to original buffer data instead.
cv::Mat m(N, N, CV_64FC1);
for (int i = 1; i < N; ++i) {
cv::Mat subM = m({0, 0, i*i});
// Perform matrix operations on "subM"
// Modifying "subM" will modify "m" buffer region that "subM" represents
}
Note that subM
will not be continious, so you will need to process it row by row if you do any raw buffer processing.
Upvotes: 1