I want to declare, populate, access a Multi-Dimensional Matrix in OpenCV (C++) which is compatible with namespace cv. I found no quick and easy to learn examples on them. Can you please help me out?
Asked
Active
Viewed 2.1k times
2 Answers
13
Here is a short example from the NAryMatIterator documentation; it shows how to create, populate, and process a multi-dimensional matrix in OpenCV:
void computeNormalizedColorHist(const Mat& image, Mat& hist, int N, double minProb)
{
const int histSize[] = {N, N, N};
// make sure that the histogram has a proper size and type
hist.create(3, histSize, CV_32F);
// and clear it
hist = Scalar(0);
// the loop below assumes that the image
// is a 8-bit 3-channel. check it.
CV_Assert(image.type() == CV_8UC3);
MatConstIterator_<Vec3b> it = image.begin<Vec3b>(),
it_end = image.end<Vec3b>();
for( ; it != it_end; ++it )
{
const Vec3b& pix = *it;
hist.at<float>(pix[0]*N/256, pix[1]*N/256, pix[2]*N/256) += 1.f;
}
minProb *= image.rows*image.cols;
Mat plane;
NAryMatIterator it(&hist, &plane, 1);
double s = 0;
// iterate through the matrix. on each iteration
// it.planes[*] (of type Mat) will be set to the current plane.
for(int p = 0; p < it.nplanes; p++, ++it)
{
threshold(it.planes[0], it.planes[0], minProb, 0, THRESH_TOZERO);
s += sum(it.planes[0])[0];
}
s = 1./s;
it = NAryMatIterator(&hist, &plane, 1);
for(int p = 0; p < it.nplanes; p++, ++it)
it.planes[0] *= s;
}
Also, check out the cv::compareHist
function for another usage example of the NAryMatIterator
here.

mevatron
- 13,911
- 4
- 55
- 72
-
So a 3-dimensional array should be something like this right? int sz[] = {3, 3, 3}; Mat accumarray(3, sz, CV_8U, Scalar::all(0)); accumarray.at
(0, 1, 2) = 20; – garak Jan 11 '12 at 00:42 -
1Well, it seems that above method doesn't work for 4 dimensional Matrix. Do you know the reason? – garak Jan 16 '12 at 14:52
-
what is the parameter minProb ? – lilouch Jan 06 '15 at 15:47
-
not sure which version this is based on, but in opencv 4, ` NAryMatIterator` takes a pointer to pointer to mat, not a pointer to mat, so this code does not compile. – oarfish Aug 31 '20 at 13:57
-
the API seems to have changed a bit, updated example is here: https://docs.opencv.org/master/d5/dd2/classcv_1_1NAryMatIterator.html#acbc0100414fe60ab212553a67dd788b6 – oarfish Aug 31 '20 at 14:00
7
To create a multi-dimensional matrix that is of size 100x100x3, using floats, one channel, and with all elements initialized to 10 you write like this:
int size[3] = { 100, 100, 3 };
cv::Mat M(3, size, CV_32FC1, cv::Scalar(10));
To loop over and output the elements in the matrix you can do:
for (int i = 0; i < 100; i++)
for (int j = 0; j < 100; j++)
for (int k = 0; k < 3; k++)
std::cout << M.at<cv::Vec3f>(i,j)[k] << ", ";
However, beware of the troubles with using multi-dimensional matrices as documented here: How do i get the size of a multi-dimensional cv::Mat? (Mat, or MatND)

Community
- 1
- 1

Reed Richards
- 4,178
- 8
- 41
- 55