OpenCV & QT: 'emit' undeclared identifier error



  • I'm using OpenCV with QT and trying to implement facial recognition but as soon as I include <face.hpp> from the OpenCV "contrib" branch, QT complains about error: C2065: 'emit': undeclared identifier. I've tried including "qobjectdefs.h" and #define emit at the top of the appropriate header file, but it does not work. Suggestions? Code:

    Header

    #ifndef FACEDETECTOR_H
        #define FACEDETECTOR_H
    
        #include <QObject>
        #include <QBasicTimer>
        #include <QTimerEvent>
        #include <QDir>
        #include <QDebug>
        #include <QImage>
        #include <QString>
        #include <QResource>
        #include <QVector>
    //This causes the error as soon as I uncomment it
        #include <opencv2/face.hpp>
        #include <opencv2/opencv.hpp>
    
        class FaceDetector : public QObject {
            Q_OBJECT
    
        public:
            FaceDetector(QObject *parent=0) : QObject(parent), processAll_(true) {}
            void setProcessAll(bool all);
            ~FaceDetector();
    
        signals:
            void image_signal(const QImage&);
    
        public slots:
            void processFrame(const cv::Mat& frame);
            void facecascade_filename(QString filename);
    
        private:
            QString facecascade_filename_;
            QString eyecascade_filename_;
            QBasicTimer timer_;
            QVector<cv::Mat> m_CSVimages;
            QVector<int> m_CSVlabels;
            cv::Mat frame_;
            bool processAll_;
            cv::CascadeClassifier faceCascade;
            cv::CascadeClassifier eyeCascade;
    
    //I need face.hpp for this:
            //cv::Ptr<cv::face::FaceRecognizer> m_faceModel;
    
            void process(cv::Mat frame);
            void loadFiles(const cv::String& faceCascadeFilename, const cv::String& eyesCascadeFilename);
            static void loadCSV(const cv::String& filePath, QVector<cv::Mat>& images, QVector<int>& labels, char separator = ';');
            void queue(const cv::Mat & frame);
            void timerEvent(QTimerEvent* ev);
            static void matDeleter(void* mat);
        };
    
        #endif // FACEDETECTOR_H
    

    Implementation: Other functions omitted for brevity.

     #include "faceDetector.h"
    
        void FaceDetector::process(cv::Mat frame) {
            cv::Mat grey_image;
            cv::cvtColor(frame, grey_image, CV_BGR2GRAY);
            cv::equalizeHist(grey_image, grey_image);
    
    
            std::vector<cv::Rect> faces;
            // Calculate the camera size and set the size to 1/8 of screen height
            faceCascade.detectMultiScale(grey_image, faces, 1.1, 8,  0|CV_HAAR_SCALE_IMAGE, cv::Size(frame.cols/4, frame.rows/4)); // Minimum size of obj
    
            //-- Draw rectangles around faces
            for( size_t i = 0; i < faces.size(); i++) {
                cv::rectangle(frame, faces[i], cv::Scalar( 255, 0, 255 ));
            }
            cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);
            const QImage image(static_cast<const unsigned char*>(frame.data), frame.cols, frame.rows, frame.step, QImage::Format_RGB888, &matDeleter, new cv::Mat(frame));
            image.rgbSwapped();
            Q_ASSERT(image.constBits() == frame.data);
    
    //This is the error location
            emit image_signal(image);
        }
    

  • Moderators

    Try including OpenCV headers before Qt ones.
    If all else fails you can replace emit with Q_EMIT macro.



  • @Chris-Kawa The Q_EMIT macro did the trick. Any ideas why this happened? I thought emit was an empty macro defined in the QT headers.


  • Moderators

    Most probably because of this silly "fix" :/
    As I mentioned earlier - including Qt after OpenCV could possibly fix this.



  • @htmlboss said:

    @Chris-Kawa The Q_EMIT macro did the trick. Any ideas why this happened? I thought emit was an empty macro defined in the QT headers.

    Emiting a signal is just calling it. The emit keyword is not a compiler token. It's just a empty macro for auto completion reason. If you don't like it, don't use emit keyword in anywhere.
    Flowing three lines are equal

    //Line 1
    emit signal();
    
    //Line 2
    Q_EMIT signal();
    
    //Line 3
    signal();  // !!!
    

  • Lifetime Qt Champion

    Hi,

    Just a quick note, taking a look at fixing this "fix", I just saw that the latest version of the contrib repository doesn't contain the offending code anymore.