Ask Your Question

Revision history [back]

You should take care of the scope of hist object, if it is outside the first loop, then your will obtain errors since your Histograms vector will contains references to one hist object. It must be one local Mat object or you have to push_back its clone, not the reference to it (in this case, the name - hist). Below is the wrong code:

    vector<cv::Mat> hists;
    vector<string> files = { "1.pgm", "2.pgm", "4.pgm" };
    int histSize = 256;

    float range[] = { 0, 256 };
    const float* histRange = { range };

    bool uniform = true; bool accumulate = false;
    Mat img;
    Mat hist;
    for (int i = 0; i < files.size(); i++)
    {
        img = cv::imread(files[i], 0);
        cv::calcHist(&img, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
        hists.push_back(hist);
    }
    for (int i = 0; i < files.size(); i++)
    {
        cout << hists[i].rows << endl;
        cout << hists[i].t() << endl;
    }

And the two versions hereafter are correct:

    Mat img;
    for (int i = 0; i < files.size(); i++)
    {
        Mat hist;
        img = cv::imread(files[i], 0);
        cv::calcHist(&img, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
        hists.push_back(hist);
    }
    for (int i = 0; i < files.size(); i++)
    {
        cout << hists[i].rows << endl;
        cout << hists[i].t() << endl;
    }

Or:

    Mat img;
    Mat hist;
    for (int i = 0; i < files.size(); i++)
    {
        img = cv::imread(files[i], 0);
        cv::calcHist(&img, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
        hists.push_back(hist.clone());
    }
    for (int i = 0; i < files.size(); i++)
    {
        cout << hists[i].rows << endl;
        cout << hists[i].t() << endl;
    }