mercredi 20 mai 2020

VideoCapture(0) and VideoCapture.open(0) Do Not Seem To Work With CMake (UBUNTU) (OpenCV4)

I am trying to open my in-built camera in order to make a Face Detection program, but I notice that VideoCapture.open(0) does not work when I attempt to run through a cmake compilation, but DOES work when I compile and run through g++.

This program is part of a project, and compiling through CMake is necessary, but nothing seems to work...

(I'm using Ubuntu)

My code compiles and runs, opening the in-built camera (returning "true" on if(capture.isOpened())), when I use

g++ main.cpp FaceDetection.cpp `pkg-config --cflags --libs opencv4`

but returns false on if(capture.isOpened()) and does not open the in-built camera when I compile through cmake.

Any ideas on what I should do for this to run like it runs when I compile it with g++?

Here's the code I'm trying to run:

main.cpp:

#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include "FaceDetection.hpp"

using namespace std;
using namespace cv;

string cascadeName, nestedCascadeName;

int main(int argc, const char **argv)
{
    // VideoCapture class for playing video for which faces to be detected
    VideoCapture capture;
    Mat frame, image;

    FaceDetector Detect("../models/haarcascade_frontalface_alt.xml");

    int scale;
    scale = Detect.getScale();

    // Start Video..1) 0 for WebCam 2) "Path to Video" for a Local Video
    capture.open(0);
    if (capture.isOpened())
    {
        // Capture frames from video and detect faces
        cout << "Face Detection Started...." << endl;
        while (1)
        {
            vector<Rect> faces;
            Mat frame;
            capture >> frame;

            faces = Detect.detection(frame);

            for (Rect area : faces)
            {
                Scalar drawColor = Scalar(255, 0, 0);

                rectangle(frame, Point(cvRound(area.x * scale), cvRound(area.y * scale)),
                                    Point(cvRound(((double)area.x + (double)area.width - 1) * scale),
                                                cvRound(((double)area.y + (double)area.height - 1) * scale)),
                                    drawColor);
            } //Close for

            imshow("Webcam", frame);
            char c = (char)waitKey(10);

            // Press q to exit from window
            if (c == 27 || c == 'q' || c == 'Q')
                break;
        }
    }
    else
        cout << "Could not Open Camera";
    return 0;
}

FaceDetection.cpp:

#include "FaceDetection.hpp"
#include <chrono>

using namespace std::chrono;
using namespace std;
using namespace cv;

// Default constructor, initializes variables with "default" values (set by us)
FaceDetector::FaceDetector(){
    faceCascade.load("../models/haarcascade_frontalface_alt.xml");
    size = 30;
    scale = 5.0;
    window_scaling = 1.1; //This multiplies by the size to find the next bigger image, if there even is one to begin with 
    minClassifiers = 4;
    imgHeight = 30;
    flags = 0;
}

// Constructor that initializes faceCascade path to a chosen one
FaceDetector::FaceDetector(const string path){
    faceCascade.load(path);
    size = 30;
    scale = 5.0;
    window_scaling = 1.1; //This multiplies by the size to find the next bigger image, if there even is one to begin with 
    minClassifiers = 4;
    imgHeight = 30;
    flags = 0;
}

// Overload constructor that initializes every other variable to user choice
FaceDetector::FaceDetector(string faceCascadeFile, int scale, int size, double scale_factor, int minConsensus, int flag){
    faceCascade.load(faceCascadeFile);
    this->scale = scale;
    this->size = size;
    window_scaling = scale_factor;
    minClassifiers = minConsensus;
    imgHeight = size;
    flags = flag;
}

// Converts image into grayscale, detects faces of different sizes and returns a list of different-sized faces as rectangle vectors
vector<Rect> FaceDetector::detection(Mat frame){
    vector<Rect> faces;
    Mat grayscale;

    cvtColor(frame, grayscale, COLOR_BGR2GRAY); // Converts "frame" image into grayscale and outputs into "grayscale"

    auto start = high_resolution_clock::now();  // Starts timer for execution time of face detection

    // Resizes image, necessary if rectangles drawn around the face are needed.
    //resize(grayscale, grayscale, Size(grayscale.size().width / scale, grayscale.size().height / scale));

    // Detects faces of different sizes and returns a list of rectangles in "faces"
    FaceDetector::faceCascade.detectMultiScale(grayscale, faces, window_scaling, minClassifiers, flags, cv::Size(size, size));

    auto stop = high_resolution_clock::now();   // Stops timer for execution time of face detection
    auto duration = duration_cast<microseconds>(stop - start);  // Calculates duration for execution time of face detection
    cout << "\nExecution time for detecting a face: " << duration.count() << " microseconds." << endl;  // Prints execution time

    return faces;   // Returns faces of different sizes as rectangle vectors
}

// Getter method for scale variable
int FaceDetector::getScale(){
    return scale;
}

FaceDetection.hpp:

#pragma once    // Tells compiler to "copy" this only once, even if FaceDetection.hpp used more than once.

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <string>
#include <stdio.h>
#include <vector>

class FaceDetector {
private:
    cv::CascadeClassifier faceCascade;
    int scale;
    int size;
    double window_scaling;
    int minClassifiers;
    int imgHeight;
    int flags;

public:
    FaceDetector(); // Default constructor, initializes variables with "default" values (set by us)
    FaceDetector(const std::string path);   // Constructor that initializes faceCascade path to a chosen one
    FaceDetector(std::string faceCascadeFile, int scale, int size, double scale_factor, int minConsensus, int flag);    // Overload constructor that initializes every other variable to user choice
    std::vector<cv::Rect> detection(cv::Mat frame); // Converts image into grayscale, detects faces of different sizes and returns a list of different-sized faces as rectangle vectors
    int getScale(); // Getter method for scale variable
};

CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)
message("Module 1 'FaceDetection' starting ...")
project(FaceDetection)

## OPEN CV
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(
FaceDetection
${PROJECT_SOURCE_DIR}/source/FaceDetection.cpp
${PROJECT_SOURCE_DIR}/source/main.cpp
)

target_link_libraries(FaceDetection ${OpenCV_LIBS})

Aucun commentaire:

Enregistrer un commentaire