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); }