void ViewFinderWrapper::startCamera()
{
    m_processor = new VideoEncoder(this);
    connect(m_processor, SIGNAL(queueFull()), this, SLOT(onThreadCongested()));
    connect(m_processor, SIGNAL(frameProcessed(QByteArray)),this,SIGNAL(newFrameToSend(QByteArray)));

    m_processor->start();

    m_camera = new QCamera(this);

    QList<QByteArray> cameras = m_camera->availableDevices();

    m_camera = new QCamera(cameras.first());
    m_camera->setViewfinder(new QCameraViewfinder);

    if (m_camera) {
        m_camera->start();
        if(m_camera->state()==QCamera::ActiveState){
            m_cameraActive = true;
            startViewFinder();
        }
        else qDebug()<<"camera didn't start";
    }

}
void QOpencvProcessor::customProcess(const cv::Mat &input)
{
    cv::Mat output(input); // Copy the header and pointer to data of input object
    cv::Mat temp; // temporary object

    //-------------CUSTOM ALGORITHM--------------

    //You can do here almost whatever you wnat...
    cv::cvtColor(output,temp,CV_BGR2GRAY);
    cv::equalizeHist(temp,temp);
    cv::Canny(temp,output,10,100);

    //----------END OF CUSTOM ALGORITHM----------

    //---------Drawing of rectangle--------------
    if( (m_cvRect.width > 0) && (m_cvRect.height > 0) )
    {
        cv::rectangle( output , m_cvRect, cv::Scalar(255,255,255)); // white color
    }

    //-------------Time measurement--------------
    m_framePeriod = (cv::getTickCount() -  m_timeCounter) * 1000.0 / cv::getTickFrequency(); // result is calculated in milliseconds
    m_timeCounter = cv::getTickCount();

    emit frameProcessed(output, m_framePeriod, output.cols*output.rows);
}
 void VideoWidget::initialize(QStatusBar *bar, SFMViewer *sfmViewer, SceneModel * sceneModel){

     // Connect surface to our slot
     connect(surface, SIGNAL(frameAvailable()), this, SLOT(frameReady()));

     processor = new ProcessingThread(this);
     connect(processor, SIGNAL(frameProcessed()), this, SLOT(onFrameProcessed()));
     connect(processor, SIGNAL(queueFull()), this, SLOT(onThreadCongested()));

	 processor->initialize(bar, sceneModel);
	 processor->setUpdateListener(sfmViewer);

     processor->start();
}
//------------------------------------------------------------------------------------------------------
void QOpencvProcessor::faceProcess(const cv::Mat &input)
{
    cv::Mat output;
    if(f_fill)
        output = input;
    else
        output = input.clone();

    cv::Mat gray; // Create an instance of cv::Mat for temporary image storage
    cv::cvtColor(input, gray, CV_BGR2GRAY);
    cv::equalizeHist(gray, gray);
    std::vector<cv::Rect> faces_vector;

    m_classifier.detectMultiScale(gray, faces_vector, 1.1, 7, cv::CASCADE_FIND_BIGGEST_OBJECT, cv::Size(OBJECT_MINSIZE, OBJECT_MINSIZE)); // Detect faces (list of flags CASCADE_DO_CANNY_PRUNING, CASCADE_DO_ROUGH_SEARCH, CASCADE_FIND_BIGGEST_OBJECT, CASCADE_SCALE_IMAGE )

    if(faces_vector.size() == 0) {
        m_emptyFrames++;
        if(m_emptyFrames > FRAMES_WITHOUT_FACE_TRESHOLD)
            setAverageFaceRect(0, 0, 0, 0);
    } else {
        m_emptyFrames = 0;
        enrollFaceRect(faces_vector[0]);
    }
    cv::Rect face = getAverageFaceRect();

    unsigned int X = face.x; // the top-left corner horizontal coordinate of future rectangle
    unsigned int Y = face.y; // the top-left corner vertical coordinate of future rectangle
    unsigned int rectwidth = face.width; //...
    unsigned int rectheight = face.height; //...
    unsigned long red = 0; // an accumulator for red color channel
    unsigned long green = 0; // an accumulator for green color channel
    unsigned long blue = 0; // an accumulator for blue color channel
    unsigned int dX = rectwidth/16;
    unsigned int dY = rectheight/30;
    unsigned long area = 0;

    if(face.area() > 10000)
    {
        for(int i = 0; i < 256; i++)
            v_temphist[i] = 0;
        cv::Mat blurRegion(output, face);
        cv::blur(blurRegion, blurRegion, cv::Size(m_blurSize, m_blurSize));
        m_ellipsRect = cv::Rect(X + dX, Y - 6 * dY, rectwidth - 2 * dX, rectheight + 6 * dY);
        X = m_ellipsRect.x;
        rectwidth = m_ellipsRect.width;
        unsigned char *p; // this pointer will be used to store adresses of the image rows
        unsigned char tempBlue;
        unsigned char tempRed;
        unsigned char tempGreen;
        if(output.channels() == 3)
        {
            if(m_skinFlag)
            {
                if(f_fill){
                    for(unsigned int j = Y; j < Y + rectheight; j++) // it is lucky that unsigned int saves from out of image memory cells processing from image top bound, but not from bottom where you should check this issue explicitly
                    {
                        p = output.ptr(j); //takes pointer to beginning of data on row
                        for(unsigned int i = X; i < X + rectwidth; i++)
                        {
                            tempBlue = p[3*i];
                            tempGreen = p[3*i+1];
                            tempRed = p[3*i+2];
                            if( isSkinColor(tempRed, tempGreen, tempBlue) && isInEllips(i, j)) {
                                area++;
                                blue += tempBlue;
                                green += tempGreen;
                                red += tempRed;
                                //p[3*i] = 255;
                                //p[3*i+1] %= LEVEL_SHIFT;
                                p[3*i+2] %= LEVEL_SHIFT;
                                v_temphist[tempGreen]++;
                            }
                        }
                    }
                } else {
                    for(unsigned int j = Y; j < Y + rectheight; j++) // it is lucky that unsigned int saves from out of image memory cells processing from image top bound, but not from bottom where you should check this issue explicitly
                    {
                        p = output.ptr(j); //takes pointer to beginning of data on row
                        for(unsigned int i = X; i < X + rectwidth; i++)
                        {
                            tempBlue = p[3*i];
                            tempGreen = p[3*i+1];
                            tempRed = p[3*i+2];
                            if( isSkinColor(tempRed, tempGreen, tempBlue) && isInEllips(i, j)) {
                                area++;
                                blue += tempBlue;
                                green += tempGreen;
                                red += tempRed;
                                v_temphist[tempGreen]++;
                            }
                        }
                    }
                }
            } else {
                for(unsigned int j = Y; j < Y + rectheight; j++)
                {
                    p = output.ptr(j); //takes pointer to beginning of data on row
                    for(unsigned int i = X; i < X + rectwidth; i++)
                    {
                        blue += p[3*i];
                        green += p[3*i+1];
                        red += p[3*i+2];
                        if(f_fill)  {
                            //p[3*i] = 255;
                            //p[3*i+1] %= LEVEL_SHIFT;
                            p[3*i+2] %= LEVEL_SHIFT;
                        }
                        v_temphist[p[3*i+1]]++;
                    }
                }
                area = rectwidth*rectheight;
            }
        } else {
            for(unsigned int j = Y; j < Y + rectheight; j++)
            {
                p = output.ptr(j);//pointer to beginning of data on rows
                for(unsigned int i = X; i < X + rectwidth; i++)
                {
                    green += p[i];
                    //Uncomment if want to see the enrolled domain on image
                    if(f_fill)  {
                        p[i] %= LEVEL_SHIFT;
                    }
                    v_temphist[p[i]]++;
                }
            }
            blue = green;
            red = green;
            area = rectwidth*rectheight;
        }
    }


    //-----end of if(faces_vector.size() != 0)-----
    m_framePeriod = ((double)cv::getTickCount() -  m_timeCounter)*1000.0 / cv::getTickFrequency();
    m_timeCounter = cv::getTickCount();
    if(area > 1000)
    {
        if(!f_fill)
            cv::rectangle( cv::Mat(input), face, cv::Scalar(15,15,250),1,CV_AA);

        emit dataCollected(red, green, blue, area, m_framePeriod);

        unsigned int mass = 0;
        for(int i = 0; i < 256; i++)
            mass += v_temphist[i];
        if(mass > 0)
        for(int i = 0; i < 256; i++)
            v_hist[i] = (qreal)v_temphist[i]/mass;
        emit histUpdated(v_hist, 256);
    }
    else
    {
        if(m_classifier.empty())
            emit selectRegion( QT_TRANSLATE_NOOP("QImageWidget", "Load cascade for detection") );
        else
            emit selectRegion( QT_TRANSLATE_NOOP("QImageWidget", "Come closer or change light") );
    }
    emit frameProcessed(input, m_framePeriod, area);
}
void QOpencvProcessor::rectProcess(const cv::Mat &input)
{
    cv::Mat output(input); //Copy constructor
    unsigned int rectwidth = m_cvRect.width;
    unsigned int rectheight = m_cvRect.height;
    unsigned int X = m_cvRect.x;
    unsigned int Y = m_cvRect.y;

    if( (output.rows < (Y + rectheight)) || (output.cols < (X + rectwidth)) )
    {
        rectheight = 0;
        rectwidth = 0;
    }

    unsigned long red = 0;
    unsigned long green = 0;
    unsigned long blue = 0;
    unsigned long area = 0;
    //-------------------------------------------------------------------------
    if((rectheight > 0) && (rectwidth > 0))
    {
        for(int i = 0; i < 256; i++)
            v_temphist[i] = 0;

        cv::Mat blurRegion(output, m_cvRect);
        cv::blur(blurRegion, blurRegion, cv::Size(m_blurSize, m_blurSize));

        unsigned char *p; // a pointer to store the adresses of image rows
        if(output.channels() == 3)
        {
            if(m_seekCalibColors)
            {
                unsigned char tempRed;
                unsigned char tempGreen;
                unsigned char tempBlue;
                for(unsigned int j = Y; j < Y + rectheight; j++)
                {
                    p = output.ptr(j); //takes pointer to beginning of data on rows
                    for(unsigned int i = X; i < X + rectwidth; i++)
                    {
                        tempBlue = p[3*i];
                        tempGreen = p[3*i+1];
                        tempRed = p[3*i+2];
                        if( isCalibColor(tempGreen) && isSkinColor(tempRed, tempGreen, tempBlue) ) {
                            area++;
                            blue += tempBlue;
                            green += tempGreen;
                            red += tempRed;
                            if(f_fill)  {
                                //p[3*i] = 255;
                                //p[3*i+1] %= LEVEL_SHIFT;
                                p[3*i+2] %= LEVEL_SHIFT;
                            }
                            v_temphist[tempGreen]++;
                        }
                    }
                }
            } else {
            if(m_skinFlag)
            {
                unsigned char tempRed;
                unsigned char tempGreen;
                unsigned char tempBlue;
                for(unsigned int j = Y; j < Y + rectheight; j++)
                {
                    p = output.ptr(j); //takes pointer to beginning of data on rows
                    for(unsigned int i = X; i < X + rectwidth; i++)
                    {
                        tempBlue = p[3*i];
                        tempGreen = p[3*i+1];
                        tempRed = p[3*i+2];
                        if( isSkinColor(tempRed, tempGreen, tempBlue)) {
                            area++;
                            blue += tempBlue;
                            green += tempGreen;
                            red += tempRed;
                            if(f_fill)  {
                                //p[3*i] = 255;
                                //p[3*i+1] %= LEVEL_SHIFT;
                                p[3*i+2] %= LEVEL_SHIFT;
                            }
                            v_temphist[tempGreen]++;
                        }
                    }
                }
            }
            else
            {
                for(unsigned int j = Y; j < Y + rectheight; j++)
                {
                    p = output.ptr(j); //takes pointer to beginning of data on rows
                    for(unsigned int i = X; i < X + rectwidth; i++)
                    {
                        blue += p[3*i];
                        green += p[3*i+1];
                        red += p[3*i+2];
                        if(f_fill)  {
                            //p[3*i] = 255;
                            //p[3*i+1] %= LEVEL_SHIFT;
                            p[3*i+2] %= LEVEL_SHIFT;
                        }
                        v_temphist[p[3*i+1]]++;
                    }
                }
                area = rectwidth*rectheight;
            }
            }
        }
        else
        {
            for(unsigned int j = Y; j < Y + rectheight; j++)
            {
                p = output.ptr(j);//pointer to beginning of data on rows
                for(unsigned int i = X; i < X + rectwidth; i++)
                {
                    green += p[i];
                    if(f_fill)  {
                        p[i] %= LEVEL_SHIFT;
                    }
                    v_temphist[p[i]]++;
                }
            }
            area = rectwidth*rectheight;
        }
    }
    //------end of if((rectheight > 0) && (rectwidth > 0))
    m_framePeriod = ((double)cv::getTickCount() -  m_timeCounter)*1000.0 / cv::getTickFrequency();
    m_timeCounter = cv::getTickCount();
    if( area > 0 )
    {
        cv::rectangle( output , m_cvRect, cv::Scalar(15,250,15), 1, CV_AA);
        emit dataCollected(red, green, blue, area, m_framePeriod);

        unsigned int mass = 0;
        for(int i = 0; i < 256; i++)
            mass += v_temphist[i];
        if(mass > 0)
        for(int i = 0; i < 256; i++)
            v_hist[i] = (qreal)v_temphist[i]/mass;
        emit histUpdated(v_hist, 256);

        if(m_calibFlag)
        {
            v_calibValues[m_calibSamples] = (qreal)green/area;
            m_calibMean += v_calibValues[m_calibSamples];
            m_calibSamples++;
            if(m_calibSamples == CALIBRATION_VECTOR_LENGTH)
            {
                m_calibMean /= CALIBRATION_VECTOR_LENGTH;
                m_calibError = 0.0;
                for(quint16 i = 0; i < CALIBRATION_VECTOR_LENGTH; i++)
                {
                    m_calibError += (v_calibValues[i] - m_calibMean)*(v_calibValues[i] - m_calibMean);
                }
                m_calibError = 10 * sqrt( m_calibError /(CALIBRATION_VECTOR_LENGTH - 1) );
                qWarning("mean: %f; error: %f; samples: %d", m_calibMean,m_calibError, m_calibSamples);
                m_calibSamples = 0;
                m_calibFlag = false;
                m_seekCalibColors = true;
                emit calibrationDone(m_calibMean, m_calibError/10, m_calibSamples);
            }
        }
    }
    else
    {
        emit selectRegion( QT_TRANSLATE_NOOP("QImageWidget", "Select region on image" ) );
    }
    emit frameProcessed(output, m_framePeriod, area);
}
void FrameConsumer::run()
{
    cv::Mat prevFrame;
    cv::Mat alignedPrevFrame;
    cv::Mat currentDiffImage;

    int w = 320;
    int h = 240;
    float f = 0.0;

    while(1)
    {

        if(frameBuffer->size() > 0 )
        {
            cv::Mat frame_ = frameBuffer->front();

            cv::Mat frame = frame_.clone();

            //Do Processing
            pFrame = frame.clone();
            if( f == 0.0)
            {
                f = (float) frame.size().width / 320 ;
                w = cvRound(f*frame.size().width);
                h = cvRound(f*frame.size().height);
            }

            cv::resize(pFrame, pFrame, cv::Size(w,h));
            cv::cvtColor(pFrame,pFrame,CV_BGR2GRAY);


            cv::Mat copyCurrentFrame = pFrame.clone();
            cv::equalizeHist(copyCurrentFrame,copyCurrentFrame);
            cv::Mat H;
            calc.process(copyCurrentFrame);

            if(calc.getHomography(H) == true)
            {
                cv::Mat canImg = frame.clone();
                cv::Mat tarImg = frame.clone();

                qDebug()<<"Homography Found \n";
                // Düzgün dönüşüm matrisi bulunduysa
                cv::Mat mask(prevFrame.size(),CV_8U);
                mask=cv::Scalar(255);

                // Önceki frame aktif frame çevir
                aligner.process(prevFrame,H,alignedPrevFrame);
                // çevrilmiş önceki frame için maske oluştur
                aligner.process(mask,H,mask);
                mask=copyCurrentFrame&mask;
                cv::absdiff(alignedPrevFrame,mask,currentDiffImage);
                processedFrame2UiAbsDiff = currentDiffImage.clone();
                cv::Mat element = cv::getStructuringElement( cv::MORPH_RECT,cv::Size( 3, 3 ),cv::Point( 1, 1 ) );


                cv::threshold(currentDiffImage,currentDiffImage,dynamicThresholdValue(currentDiffImage),255,cv::THRESH_BINARY);
                cv::dilate(currentDiffImage,currentDiffImage, element,cv::Point(-1,-1),4 );
                cv::erode(currentDiffImage,currentDiffImage, element,cv::Point(-1,-1),4 );

                cDet.process(currentDiffImage);
                cDet.showCandidates(canImg);
                cFilt.process(&cDet.candidateList);
                cFilt.showTargets(tarImg,cDet.scaleFactor);

                processedFrame2UiCandidates = canImg.clone();
                processedFrame2UiTargets = tarImg.clone();

            }
            prevFrame = copyCurrentFrame;

            emit frameProcessed();

            frameBuffer->pop();

/* causes a error "Debug Assertion Failed!" and
 * "Expression: deque iterator not dereferencable."
 * mutex not solved

            QMutex mutex;
            mutex.lock();
            for(int i=0; i < nPass ; i++) // to by pass some frame
            {
                qDebug()<<"frame Buffersize : " <<frameBuffer->size()<<"\n";
                if(frameBuffer->size() < 1)
                    break;
                else
                    frameBuffer->pop();
            }
            mutex.unlock();
*/

        }
        else
        {
           QThread::msleep(100);
        }
    }

}