Ask Your Question

Is the OpenCV 3d Histogram 3 axis histogram?

asked 2017-09-30 01:54:51 -0500

sazr gravatar image

What exactly is the 3d histogram returned from OpenCV's calcHist()?

For a 1d histogram I know that:
- the x axis represents my desired bins (for simplicity lets say 0-255 - grayscale colour values).
- the y axis represents the number of pixels that have that bin/colour value.

For a 3d I correct that:
- There are 3 x axis arrays? One for each colour channel (in my case b,g,r)?
- There are 3 y axis arrays? One for each of the above?


  • There are still only 1 x and y axis. But the x axis represents a concatenation(?) of b*g*r and the y axis tells me how many pixels have the colour b*g*r?

If its the first scenario, does OpenCV have a way to:
- Produce a unique number to represent a colour (hexadecimal? or combine b*g*r)?
- Produce a histogram of a 3 channel image where the x axis bins represent the unique colour number above and y axis tells me how many pixels have that colour?
- Presumably this is alot more computationally efficient than having a 3d histogram with 255 bins?

edit retag flag offensive close merge delete

1 answer

Sort by » oldest newest most voted

answered 2017-09-30 02:59:21 -0500

LBerger gravatar image

I think everything is in doc here (see detailed description)

n-dimensional dense array class

The class Mat represents an n-dimensional dense numerical single-channel or multi-channel array. It can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms (though, very high-dimensional histograms may be better stored in a SparseMat ). The data layout of the array M is defined by the array M.step[], so that the address of element (i0,...,iM.dims−1), where 0≤ik<m.size[k], is="" computed="" as:<="" p="">


In case of a 2-dimensional array, the above formula is reduced to:


Note that M.step[i] >= M.step[i+1] (in fact, M.step[i] >= M.step[i+1]*M.size[i+1] ). This means that 2-dimensional matrices are stored row-by-row, 3-dimensional matrices are stored plane-by-plane, and so on. M.step[M.dims-1] is minimal and always equal to the element size M.elemSize() .

Now if you want to use calhist for 3d histogram (calcbackproject for example with dim=3 it is a 3d histogram) you can do like this :

    Mat m = imread("f:/lib/opencv/samples/data/baboon.jpg", CV_LOAD_IMAGE_ANYCOLOR);
    Mat mask(m.size(), CV_8UC1, Scalar::all(0));
    Rect rZone(Point(220, 330), Point(260, 360));
    mask(rZone) = 255;

    float hRange[] = { 0, 255 };
    const float* etendu[] = { hRange, hRange,hRange };
    int hBins = 30;
    int tailleHist[] = { hBins, hBins+5, hBins+10 };
    int canaux[] = { 2, 1,0 };
    double hMin, hMax;
    cv::Mat histogramme;
    cv::Mat resultMap;
    cv::Mat backproj1d;
    for (int dim = 1; dim <= 3; dim++)
        cv::calcHist(&m, 1, canaux, mask, histogramme, dim, tailleHist, etendu, true, false);
        minMaxIdx(histogramme, &hMin, &hMax);
        cout << "Hist extremum = " << hMin << "\t" << hMax << "\n";
        cout << "Pixel in Mat = " <<<<endl;
        for (int j=0;j<dim;j++)
            cout <<"dimension " << j <<" : " << tailleHist[j]<<endl; 
            if (j<dim-1)
                cout << "offset in dimension "<<j<<" -> "<<histogramme.step[j]<<endl;
        normalize(histogramme, histogramme, 0, 255, cv::NormTypes::NORM_MINMAX, -1, cv::Mat());

        minMaxIdx(histogramme, &hMin, &hMax);
        cout << "after normalize Hist extremum = " << hMin << "\t" << hMax << "\n";
        cv::calcBackProject(&m, 1, canaux, histogramme, backproj1d, etendu, 1, true);
        applyColorMap(backproj1d, resultMap, cv::COLORMAP_JET);
        imshow(format("backproject %dD", dim), resultMap);
edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower


Asked: 2017-09-30 01:54:51 -0500

Seen: 270 times

Last updated: Sep 30 '17