vector<cv::Mat> *ImageDataFloat2ndStageCombined::getLabelIntegralImages(unsigned int iImg)
{
    CImageCacheElement *pImgElem;
    vector<cv::Mat> *pLabelIntegrals = NULL;

    pImgElem = &(vectImageData[iImg]);
    if (pImgElem->bLoaded==true)
        pLabelIntegrals = &(pImgElem->vectFeaturesIntegral);
    else {
        cout<<"Loading integrals (one,x,y,xx,yy,xy) of image "<<iImg<<endl;
        if (ReadImageData(iImg)==true)
        {
            pImgElem->bLoaded = true;

            pLabelIntegrals = &(pImgElem->vectFeaturesIntegral);

            listIndicesImagesLastLoaded.push_back(iImg);
            while (listIndicesImagesLastLoaded.size()>iNbMaxImagesLoaded)
            {
                CloseImageData(listIndicesImagesLastLoaded.front());
                listIndicesImagesLastLoaded.pop_front();
            }
        }
    }

    return pLabelIntegrals;
}
bool ImageDataFloat2ndStageBinaryCombined::setConfiguration(ConfigReader &cfg)
{
    double scaleFactor = cfg.rescaleFactor;
    vector<string>::iterator it, end;
    unsigned int iImg, iFeature;
    cv::Mat imgInput;
    cv::Mat imgSegmap1stStage, imgLabel;
    CImageCacheElement *pImgElem;
    char strPostfix[100];
    string strInputLabelPath;

    // iNbMaxImagesLoaded = 10;
    // bUseIntegralImages = true;

    pData1stStage = new ImageDataFloat();
    pData1stStage->bGenerateFeatures = false;

    pData1stStage->setConfiguration(cfg);

    it = cfg.imageFilenames.begin();
    end = cfg.imageFilenames.end();

    vectImageData.resize(end-it);

#ifndef SHUT_UP
    if (bGenerateFeatures==true)
        cout << "Set paths and generate HOT1 features for " << end-it << " images: "<<endl;
    else
        cout << "Just set paths for " << end-it << " images: "<<endl;
#endif

    iNbLabels = cfg.numLabels;
    iNbFeatures = pData1stStage->getNbFeatures() + iNbLabels;

    iWidth = pData1stStage->getWidth();
    iHeight = pData1stStage->getHeight();

    // load image data
    for(iImg = 0; it != end; ++it, ++iImg)
    {
        pImgElem = &(vectImageData[iImg]);

        sprintf(strPostfix, "%04d", iImg);

        pImgElem->strInputImage = cfg.imageFolder + "/" + *it;
        pImgElem->strFeatureImagesPath = cfg.feature2ndStageFolder + "/features" + strPostfix;
        pImgElem->strFeatureImagesIntegralPath = cfg.feature2ndStageFolder + "/features_integral" + strPostfix;
        pImgElem->strLabelImagePath = cfg.outputFolder + "/segmap_1st_stage" + strPostfix + ".png";

        if (bGenerateFeatures==true)
        {
            cout<<"Generating 2nd-stage HOT1 features for image "<<iImg<<endl;

            imgSegmap1stStage = cv::imread(pImgElem->strLabelImagePath, cv::IMREAD_GRAYSCALE);
            if (imgSegmap1stStage.data==NULL)
            {
                cout<<"Failed to read 1st-stage segmentation map "<<iImg<<": "<<pImgElem->strLabelImagePath<<endl;
                return false;
            }

            // Check if segmentation map and ground truth image have the same size
            strInputLabelPath = cfg.groundTruthFolder + "/label_rearranged" + strPostfix + ".png";
            imgLabel = cv::imread(strInputLabelPath, cv::IMREAD_GRAYSCALE);
            if (imgLabel.data==NULL)
            {
                cout<<"Failed to read ground truth image "<<iImg<<": "<<pImgElem->strLabelImagePath<<endl;
                return false;
            }

            if (imgSegmap1stStage.size()!=imgLabel.size())
            {
                cv::resize(imgSegmap1stStage, imgSegmap1stStage, imgLabel.size(), 0, 0, cv::INTER_NEAREST);
                cout<<"Segmentation map "<<iImg<<" resized"<<endl;
            }

            computeFeatures(imgSegmap1stStage, pImgElem->vectFeatures);

            if (bUseIntegralImages==true)
            {
                pImgElem->vectFeaturesIntegral.resize(pImgElem->vectFeatures.size());
                for (iFeature=0; iFeature<pImgElem->vectFeatures.size(); iFeature++)
                {
                    cv::integral(pImgElem->vectFeatures[iFeature], pImgElem->vectFeaturesIntegral[iFeature], CV_32F);
                    /*
                    if (pImgElem->vectFeaturesIntegral[iFeature].rows!=pImgElem->vectFeatures[iFeature].rows+1
                        || pImgElem->vectFeaturesIntegral[iFeature].cols!=pImgElem->vectFeatures[iFeature].cols+1)
                    {
                        cout<<"Size differ"<<endl;
                    }*/
                }
            }

            pImgElem->bLoaded = true;
            if (WriteImageData(iImg)==false)
                return false;

            CloseImageData(iImg);
        }
        else {
            pImgElem->bLoaded = false;
        }
    }

    cout<<"2nd-stage image data initialized"<<endl;

    return true;
}
bool ImageDataFloat2ndStageCombined::setConfiguration(ConfigReader &cfg)
{
    double scaleFactor = cfg.rescaleFactor;
    vector<string>::iterator it, end;
    unsigned int iImg, iFeature;
    cv::Mat imgInput;
    cv::Mat imgSegmap1stStage, imgLabel;
    CImageCacheElement *pImgElem;
    char strPostfix[100];
    string strInputLabelPath;
    CLabelFeature labelFeature;

    // iNbMaxImagesLoaded = 10;
    // bUseIntegralImages = true;

    pData1stStage = new ImageDataFloat();
    pData1stStage->bGenerateFeatures = false;

    pData1stStage->setConfiguration(cfg);

    it = cfg.imageFilenames.begin();
    end = cfg.imageFilenames.end();

    vectImageData.resize(end-it);

    if (bGenerateFeatures==true)
        cout << "Set paths and generate label features for " << end-it << " images: "<<endl;
    else
        cout << "Just set paths for " << end-it << " images: "<<endl;

    iNbLabels = cfg.numLabels;
    iNbScales = NO_REGION_SCALES;
    iNbFeatures = pData1stStage->getNbFeatures() + regFeatures;

    iWidth = pData1stStage->getWidth();
    iHeight = pData1stStage->getHeight();

    // load image data
    for(iImg = 0; it != end; ++it, ++iImg)
    {
        pImgElem = &(vectImageData[iImg]);

        sprintf(strPostfix, "%04d", iImg);

        pImgElem->strInputImage = cfg.imageFolder + "/" + *it;
        pImgElem->strFeatureImagesPath = cfg.feature2ndStageFolder + "/features" + strPostfix;
        pImgElem->strFeatureImagesIntegralPath = cfg.feature2ndStageFolder + "/label_integral" + strPostfix;
        pImgElem->strLabelImagePath = cfg.outputFolder + "/segmap_1st_stage" + strPostfix + ".png";

        if (bGenerateFeatures==true)
        {
            cout<<"Generating 2nd-stage features for image "<<iImg<<endl;

            imgSegmap1stStage = cv::imread(pImgElem->strLabelImagePath, cv::IMREAD_GRAYSCALE);
            if (imgSegmap1stStage.data==NULL)
            {
                cout<<"Failed to read 1st-stage segmentation map "<<iImg<<": "<<pImgElem->strLabelImagePath<<endl;
                return false;
            }

            // Check if segmentation map and ground truth image have the same size
            strInputLabelPath = cfg.groundTruthFolder + "/label_rearranged" + strPostfix + ".png";
            imgLabel = cv::imread(strInputLabelPath, cv::IMREAD_GRAYSCALE);
            if (imgLabel.data==NULL)
            {
                cout<<"Failed to read ground truth image "<<iImg<<": "<<pImgElem->strLabelImagePath<<endl;
                return false;
            }

            if (imgSegmap1stStage.size()!=imgLabel.size())
            {
                cv::resize(imgSegmap1stStage, imgSegmap1stStage, imgLabel.size(), 0, 0, cv::INTER_NEAREST);
                cout<<"Segmentation map "<<iImg<<" resized"<<endl;
            }

            labelFeature.SetImage(imgSegmap1stStage);
            pImgElem->vectFeaturesIntegral.resize(6*NO_LABELS);

            unsigned int iLabel;

            for (iLabel=0; iLabel<NO_LABELS; iLabel++)
            {
                pImgElem->vectFeaturesIntegral[iLabel*6 + 0] = labelFeature.arrayIntegralImages[iLabel].one;
                pImgElem->vectFeaturesIntegral[iLabel*6 + 1] = labelFeature.arrayIntegralImages[iLabel].x;
                pImgElem->vectFeaturesIntegral[iLabel*6 + 2] = labelFeature.arrayIntegralImages[iLabel].y;
                pImgElem->vectFeaturesIntegral[iLabel*6 + 3] = labelFeature.arrayIntegralImages[iLabel].xx;
                pImgElem->vectFeaturesIntegral[iLabel*6 + 4] = labelFeature.arrayIntegralImages[iLabel].yy;
                pImgElem->vectFeaturesIntegral[iLabel*6 + 5] = labelFeature.arrayIntegralImages[iLabel].xy;
            }

            pImgElem->bLoaded = true;
            if (WriteImageData(iImg)==false)
                return false;

            CloseImageData(iImg);
        }
        else {
            pImgElem->bLoaded = false;
        }
    }

    cout<<"2nd-stage image data initialized"<<endl;

    return true;
}