1

I am calculating a histogram from a greyscale image using the above code; it is working fine.

cv::Mat imgSrc = cv::imread("Image.jpg", cv::IMREAD_UNCHANGED);
cv::Mat histogram; //Array for the histogram
int channels[] = {0}; 
int binNumArray[] = {256}; 
float intensityRanges[] = { 0, 256 }; 
const float* ranges[] = { intensityRanges };
cv::calcHist( &imgSrc, 1, channels, cv::noArray(), histogram, 1,     binNumArray, ranges, true, false) ;    

In the book of Kaehler & Bradski they refer to this as the "old-fashioned C-style arrays" and they say the new style would use STL vector templates, and the arrays of images from which to calculate the histogram are to be given using cv::InputArrayOfArrays. However, if I try to replace for example the channel array by:

std::vector channels {0};

Gives compilation error.So my questions are these: 1. How can I define the arrays of the 'channels', 'binNumArray', 'intensityRanges' using vectors? 2. How can I define the array of input images using cv::InputArrayOfArrays?

szecsit
  • 21
  • 1
  • 4
  • I always found `calcHist` very wierd... you can compute simple histograms just like: `vector histogram(256,0); for(int i=0; i – Miki Mar 20 '17 at 13:21
  • I know there are many ways of calculating a histogram without calcHist(), and even with calcHist with the 'old C-type arrays' it does work, I was just curious why I could't do it with vectors just like it says in the book. Thanks for the reply anyway (to Miki). – szecsit Mar 20 '17 at 16:58
  • ok got it. Posted an answer with both methods (obviously the result is the same) – Miki Mar 20 '17 at 17:23

1 Answers1

4

This example show both the "old" approach and the "new" approach, so you can appreciate the difference. It's based on the example found in the OpenCV documentation.

The "new" approach is just a convenience wrapper that internally calls the "old" one.

#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;


int main()
{
    Mat3b src = imread("path_to_image");
    Mat3b hsv;
    cvtColor(src, hsv, CV_BGR2HSV);

    Mat hist;
    Mat hist2;
    {
        // Quantize the hue to 30 levels
        // and the saturation to 32 levels
        int hbins = 30, sbins = 32;
        int histSize[] = { hbins, sbins };
        // hue varies from 0 to 179, see cvtColor
        float hranges[] = { 0, 180 };
        // saturation varies from 0 (black-gray-white) to
        // 255 (pure spectrum color)
        float sranges[] = { 0, 256 };
        const float* ranges[] = { hranges, sranges };

        // we compute the histogram from the 0-th and 1-st channels
        int channels[] = { 0, 1 };
        calcHist(&hsv, 1, channels, Mat(), // do not use mask
            hist, 2, histSize, ranges,
            true, // the histogram is uniform
            false);
    }

    {
        // Quantize the hue to 30 levels
        // and the saturation to 32 levels
        vector<int> histSize = { 30, 32 };
        // hue varies from 0 to 179, see cvtColor
        // saturation varies from 0 (black-gray-white) to
        // 255 (pure spectrum color)
        vector<float> ranges = { 0, 180, 0, 256 };
        // we compute the histogram from the 0-th and 1-st channels
        vector<int> channels = { 0, 1 };

        vector<Mat> mats = { hsv };
        calcHist(mats, channels, Mat(), // do not use mask
            hist2, histSize, ranges,
            /*true, // the histogram is uniform, this is ALWAYS true*/
            false);
    }
    return 0;
}
Miki
  • 40,887
  • 13
  • 123
  • 202
  • Thanks (Miki) for the example, I have figured what my problem was: if I use the vector formats the parameter list is different; I must not specify the number of images it should process (second parameter in the 'old' example. – szecsit Mar 21 '17 at 09:46
  • Why does it say "do not use mask"? I used mask with non-empty values. It spits out an error `OpenCV(3.4.4) /home/username/opencv-3.4.4/modules/imgproc/src/histogram.cpp:904: error: (-215:Assertion failed) mask.empty() || mask.type() == CV_8UC1 in function 'calcHist'` – midtownguru Nov 23 '19 at 02:16