CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Как научить робота видеть лица даже в облаках

голова робота
Для поездки на выставку Robotics Expo 2014, мы захотели научить нашего робота Элвина распознавать лица.
Это оказалось довольно просто — достаточно было воспользоваться готовым каскадным классификатором, а в поставке OpenCV уже есть готовые обученные классификаторы для детектирования лиц и глаз.
В итоге, наш робот Элвин стал детектировать лица и произносить приветствие.
Но этот функционал, оказывается, можно использовать и для более забавных целей — например, искать лица в облаках, как сделал Shinseungback Kimyonghun.
Для этого, несколько модифицируем пример и получим:

//
// Simple face detection (for search faces in the clouds :)
//
// http://robocraft.ru
//
 
#include "opencv2/opencv.hpp"

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

void detectAndDisplay( Mat frame );

String face_cascade_name = "/usr/share/opencv/lbpcascades/lbpcascade_frontalface.xml";
String eyes_cascade_name = "/usr/share/opencv/haarcascades/haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
String window_name = "FaceDetection";

int counter=0;
char filename[512] = {0};
 
int main( void )
{
    VideoCapture capture;
    Mat frame;

    // загрузка каскада для распознавания лиц и глаз
    if( !face_cascade.load( face_cascade_name ) ) { 
		printf("[!] Error loading face cascade\n");
		return -1;
	}
    if( !eyes_cascade.load( eyes_cascade_name ) ) {
		printf("[!] Error loading eyes cascade\n");
		return -1; 
	}

    // начинаем захват видео
    capture.open( -1 );
    if ( ! capture.isOpened() ) {
		printf("[!] Error opening video capture\n");
		return -1;
	}
	
	// установка разрешения для видео
	capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
	capture.set(CV_CAP_PROP_FRAME_HEIGHT, 480);

	// цикл получения кадров с камеры
    while ( capture.read(frame) ) {
        if( frame.empty() ) {
            printf("[!] No captured frame -- Break!\n");
            break;
        }

        // обработка кадра
        detectAndDisplay( frame );

        // обработка клавиатуры
        int c = waitKey(10);
        if( (char)c == 27 ) { 
			break;
		}
    }
    return 0;
}

void detectAndDisplay( Mat frame )
{
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor( frame, frame_gray, COLOR_BGR2GRAY );
    equalizeHist( frame_gray, frame_gray );

    // детектор лиц
    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0, Size(80, 80) );

	printf("[i] frame %d x %d detect faces: %d\n", frame.cols, frame.rows, faces.size());
	
    for( size_t i = 0; i < faces.size(); i++ ) {	
        Mat faceROI = frame_gray( faces[i] );
        std::vector<Rect> eyes;

        // на каждом лице пробуем найти глаза
        eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CASCADE_SCALE_IMAGE, Size(30, 30) );
        if( eyes.size() == 2) {
#if 0		
            // отрисовка рамки вокруг лица
            Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );
            ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2 ), 0, 0, 360, Scalar( 255, 0, 0 ), 2, 8, 0 );

            for( size_t j = 0; j < eyes.size(); j++ ) { 
				// отрисовка кругов вокруг глаз
                Point eye_center( faces[i].x + eyes[j].x + eyes[j].width/2, faces[i].y + eyes[j].y + eyes[j].height/2 );
                int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 );
                circle( frame, eye_center, radius, Scalar( 255, 0, 255 ), 3, 8, 0 );
            }
#endif		
			printf("[i] eyes!\n");	
        }
		
		// сохранение в файл
		Mat roiImg;
		roiImg = frame(faces[i]);
		sprintf(filename, "face_%d.png", counter++);
		imwrite(filename, roiImg);
    }
    // показываем результат
    //imshow( window_name, frame );

}

Устанавливаем OpenCV на Raspberry Pi, подключаем модуль камеры или, как в случае с Элвином, используем web-камеру, пишем Makefile и остаётся только собрать проект и проверить работу.

Вот так и получилось, что если раньше Элвин смотрел на своё отражение в телевизоре,

то теперь он стоит задрав голову и смотрит в окно, в поисках человеческих лиц в облаках.
К сожалению, низкое и хмурое калининградское небо пока не показало роботу никакого подходящего кандидата :)

UPD 2014-12-09 Элвин смотрит в небо

Ссылки:
Cascade Classifier
Cloud Face
Облака–лица. Компьютерное зрение (OpenCV) на службе человеческих фантазий

По теме:
RoboCraft на HackDay #34 в Калининграде
Подключение модуля камеры к Raspberry Pi
  • +1
  • 8 декабря 2014, 14:51
  • noonv

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.