Beispiel #1
0
bool vgg_process::process(cv::Mat image_in, string &name, float &conf)
{
    int i=0, j=0, k=0;
    int top5_idx[5];
    float mean_val[3] = {103.939, 116.779, 123.68}; // bgr mean

    // input
    float output[1000];
    vector<Blob<float>*> input_vec;
    Blob<float> blob(1, 3, IMAGE_SIZE, IMAGE_SIZE);

    cv::Mat image_small(cv::Size(IMAGE_SIZE, IMAGE_SIZE), CV_8UC3);

    cv::resize(image_in, image_small, cv::Size(IMAGE_SIZE, IMAGE_SIZE));

    for (k=0; k<3; k++)
        {
            for (i=0; i<IMAGE_SIZE; i++)
                {
                    for (j=0; j< IMAGE_SIZE; j++)
                        {
                            blob.mutable_cpu_data()[blob.offset(0, k, i, j)] = (float)(unsigned char)image_small.data[i*image_small.step+j*image_small.channels()+k] - mean_val[k];
                        }
                }
        }

    input_vec.push_back(&blob);

    // forward propagation
    float loss;

    const vector<Blob<float>*>& result = caffe_test_net.Forward(input_vec, &loss);

    // copy output
    for(i=0; i<1000; i++)
        {
            output[i] = result[0]->cpu_data()[i];
        }

    get_top5(output, top5_idx);

    char str[256];
    sprintf(str, "%s", label[top5_idx[0]]);
    name = str;

    conf = output[0];

    if (conf < 0.3)
        return false;
    else
        return true;
}
void FaceRecognition::detectAndDraw(cv::Mat image,
                                    cv::CascadeClassifier &cascade,
                                    cv::CascadeClassifier &nested_cascade,
                                    double scale,
                                    bool try_flip)
{
    int    i    = 0;
    double tick = 0.0;
    std::vector<cv::Rect> faces_a, faces_b;
    cv::Scalar colors[] = {
        CV_RGB(0, 0, 255),
        CV_RGB(0, 128, 255),
        CV_RGB(0, 255, 255),
        CV_RGB(0, 255, 0),
        CV_RGB(255, 128, 0),
        CV_RGB(255, 255, 0),
        CV_RGB(255, 0, 0),
        CV_RGB(255, 0, 255)
    };
    cv::Mat image_gray;
    cv::Mat image_small(cvRound(image.rows / scale),
                        cvRound(image.cols / scale),
                        CV_8UC1);
    // Convert to gray image.
    cv::cvtColor(image, image_gray, CV_BGR2GRAY);
    // Convert gray image to small size.
    cv::resize(image_gray, image_small, image_small.size(), 0, 0,
               cv::INTER_LINEAR);
    cv::equalizeHist(image_small, image_small);

    tick = (double)cvGetTickCount();
    cascade.detectMultiScale(image_small, faces_a, 1.1, 2, 0 |
                             CV_HAAR_SCALE_IMAGE, cv::Size(30, 30));

    if (try_flip) {
        cv::flip(image_small, image_small, 1);
        cascade.detectMultiScale(image_small, faces_b, 1.1, 2, 0 |
                                 CV_HAAR_SCALE_IMAGE, cv::Size(30, 30));
        std::vector<cv::Rect>::const_iterator it = faces_b.begin();
        for (; it != faces_b.end(); it++) {
            faces_a.push_back(cv::Rect(image_small.cols - it->x - it->width,
                                       it->y, it->width, it->height));
        }
    }

    // Calculate detection's time.
    tick = (double)cvGetTickCount() - tick;
    std::cout << "Detection time: "
              << tick / ((double)cvGetTickCount() * 1000.0)
              << " ms"
              << std::endl;

    std::vector<cv::Rect>::const_iterator it = faces_a.begin();
    for (; it != faces_a.end(); it++, i++) {
        int radius;
        double aspect_ratio = (double)it->width / it->height;
        std::vector<cv::Rect> nested_objects;
        cv::Mat small_image_roi;
        cv::Point center;
        cv::Scalar color = colors[i % 8];

        // Capture detected face and predict it.
        cv::Mat image_gray;
        cv::Mat image_result(cvRound(IMG_HEIGH), cvRound(IMG_WIDTH), CV_8UC1);
        cv::Mat image_temp;
        cv::Rect rect;
        rect.x = cvRound(it->x * scale);
        rect.y = cvRound(it->y * scale);
        rect.height = cvRound(it->height * scale);
        rect.width  = cvRound(it->width  * scale);
        image_temp  = image(rect);
        cv::cvtColor(image_temp, image_gray, CV_BGR2GRAY);
        cv::resize(image_gray, image_result, image_result.size(), 0, 0,
                   cv::INTER_LINEAR);
        int predicted_label = g_model->predict(image_result);

        std::cout << "*************************" << std::endl
                  << "The predicted label: "     << predicted_label
                  << std::endl
                  << "*************************"
                  << std::endl;

        // Recognize specific face for sending character to serial device.
        if (predicted_label == 1) {
            g_face_recognition.writeCharToSerial('Y');
        }
        else {
            g_face_recognition.writeCharToSerial('N');
        }

        // Draw the circle for faces.
        if (0.75 < aspect_ratio && aspect_ratio > 1.3) {
            center.x = cvRound((it->x + it->width * 0.5) * scale);
            center.y = cvRound((it->y + it->height * 0.5) * scale);
            radius = cvRound((it->width + it->height) * 0.25 * scale);
            cv::circle(image, center, radius, color, 3, 8, 0);
        }
        else {
            // Draw the rectangle for faces.
            cv::rectangle(image,
                          cvPoint(cvRound(it->x * scale),
                                  cvRound(it->y * scale)),
                          cvPoint(cvRound((it->x + it->width  - 1) * scale),
                                  cvRound((it->y + it->height - 1) * scale)),
                          color,
                          3,
                          8,
                          0);
            if (nested_cascade.empty()) {
                continue ;
            }
            small_image_roi = image_small(*it);
            nested_cascade.detectMultiScale(small_image_roi, nested_objects,
                                            1.1, 2, 0 | CV_HAAR_SCALE_IMAGE,
                                            cv::Size(30, 30));
            std::vector<cv::Rect>::const_iterator it_temp =
                nested_objects.begin();
            // Draw the circle for eyes.
            for (; it_temp != nested_objects.end(); it_temp++) {
                center.x = cvRound((it->x + it_temp->x + it_temp->width * 0.5)
                    * scale);
                center.y = cvRound((it->y + it_temp->y + it_temp->height * 0.5)
                    * scale);
                radius = cvRound((it_temp->width + it_temp->height) * 0.25
                    * scale);
                cv::circle(image, center, radius, color, 3, 8, 0);
            }
        }
    }
    // Open camera window.
    cv::imshow("Face Recognition", image);
}