Search code examples
c++opencvstorageface-detection

Show the detected face images in a window


How can I show all the images in a window? My face detection will come out with different size of detected face images. Should I save all the detected images then read using imread(), then display it using showmanyimage()? But this step will eat my storage. I need another solution please.


Solution

  • take a look at the code below

    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include "opencv2/objdetect.hpp"
    
    using namespace cv;
    using namespace std;
    
    int showManyImages( const String& _winName, const vector<Mat>& _imgs );
    
    int main( int argc, char** argv )
    {
        string cascadeName = "haarcascade_frontalface_alt.xml";
    
        Mat img = imread(argv[1]);
        if( img.empty() )
        {
            printf( "Could not read input image file\n");
            return -1;
        }
    
        CascadeClassifier cascade;
    
        if( !cascade.load( cascadeName ) )
        {
            printf("ERROR: Could not load classifier cascade\n");
            return -1;
        }
    
        vector<Mat> imgs;
        vector<Rect> faces;
        cascade.detectMultiScale( img, faces, 1.3, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );
    
            for ( size_t i = 0; i < faces.size(); i++ )
            {
                 if(i < 12)
                 imgs.push_back(img(faces[i]));
            }
    
        showManyImages("Images", imgs);
        waitKey();
        return 0;
    }
    
    int showManyImages( const String& _winName, const vector<Mat>& _imgs )
    {
        int nImg = (int)_imgs.size();
    
        Mat dispImg;
    
        int size;
        int x, y;
    
        // w - Maximum number of images in a row
        // h - Maximum number of images in a column
        int w, h;
        // scale - How much we have to resize the image
        float scale;
        int max;
    
        if (nImg <= 0)
        {
            printf("Number of arguments too small....\n");
            return -1;
        }
        else if (nImg > 12)
        {
            printf("Number of arguments too large....\n");
            return 1;
        }
    
        else if (nImg == 1)
        {
            w = h = 1;
            size = 300;
        }
        else if (nImg == 2)
        {
            w = 2;
            h = 1;
            size = 300;
        }
        else if (nImg == 3 || nImg == 4)
        {
            w = 2;
            h = 2;
            size = 300;
        }
        else if (nImg == 5 || nImg == 6)
        {
            w = 3;
            h = 2;
            size = 200;
        }
        else if (nImg == 7 || nImg == 8)
        {
            w = 4;
            h = 2;
            size = 200;
        }
        else
        {
            w = 4;
            h = 3;
            size = 150;
        }
    
        dispImg = Mat::zeros(Size(100 + size*w, 60 + size*h), CV_8UC3);
    
        for (int i= 0, m=20, n=20; i<nImg; i++, m+=(20+size))
        {
            x = _imgs[i].cols;
            y = _imgs[i].rows;
    
            max = (x > y)? x: y;
            scale = (float) ( (float) max / size );
    
            if (i%w==0 && m!=20)
            {
                m = 20;
                n += 20+size;
            }
    
            Mat imgROI = dispImg(Rect(m, n, (int)(x/scale), (int)(y/scale)));
            resize(_imgs[i], imgROI, Size((int)(x/scale), (int)(y/scale)));
        }
    
        imshow(_winName, dispImg);
        return 0;
    }
    

    input image : enter image description here output image : enter image description here