OpenCVで顔認識をしてみる

PHP

http://hirokawa.netflowers.jp/entry/4874 にあるPHP Bindingを利用

<?php
    $faces = face_detect('test.jpg', '/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml');
    $im = imagecreatefromjpeg('test.jpg');
    $color = imagecolorallocate($im, 255, 255, 0);

    foreach($faces as $face) {
        imagerectangle($img, $face['x'], $face['y'], $face['x'] + $face['width'], $face['y'] + $face['height'], $color);
    }
    imagejpeg($im, 'output.jpg', 100);
    imagedestroy($img);
?>

Perl

Image::ObjectDetectを利用する

use strict;
use warnings;
use Imager;
use Image::ObjectDetect;

my $img = Imager->new->read(file => 'test.jpg');
my $detector = Image::ObjectDetect->new('/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml');
my @faces = $detecttor->detect('test.jpg');

for my $face (@faces) {
    $img->box(
        xmin => $face->{x},
        xmax => $face->{x} + $face->{width},
        ymin => $face->{y},
        ymax => $face->{y} + $face->{height}
    );
}
$img->write(file => 'output.jpg');

Ruby

RubyGems::objectdetectを利用

require 'rubygems'
require 'objectdetect'
require 'RMagick'

d = Magick::Draw.new.stroke('yellow').stroke_width(1).fill_opacity(0)
ObjectDetect::detect('/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml', 'test.jpg').map do |p|
    x, y, w, h = p;
    d.rectangle(x, y , x+w, y+h)
end

image = Magick::ImageList.new('test.jpg')
d.draw(image)
image.write('output.jpg')

C/C++

opencv以外にlibgdが必要

#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <gd.h>

int main(void) {
    CvHaarClassifierCascade* cascade;
    IplImage *img,*gray_scale;
    CvMemStorage *storage;
    CvSeq *objects;
    CvRect *rect;
    FILE *fp_in,*fp_out;
    gdImagePtr im;
    int i,color;

    cascade = (CvHaarClassifierCascade*)cvLoad("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml", 0, 0, 0);
    img = cvLoadImage("test.jpg", 1);
    gray_scale = cvCreateImage(cvSize(img->width, img->height), 8, 1);

    cvCvtColor(img,gray_scale, CV_BGR2GRAY);
    cvEqualizeHist(gray_scale, gray_scale);

    storage = cvCreateMemStorage(0);
    objects = cvHaarDetectObjects(gray_scale, cascade,storage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(0, 0));

    fp_in = fopen("test.jpg", "rb");
    im = gdImageCreateFromJpeg(fp_in);
    color = gdImageColorAllocate(im, 255, 255, 0);

    for(i = 0; i < (objects ? objects->total : 0); i++) {
        rect = (CvRect*)cvGetSeqElem(objects, i);
        gdImageRectangle(im, rect->x, rect->y, rect->x + rect->width, rect->y + rect->height, color);
    }
    fp_out = fopen("output.jpg", "wb");
    gdImageJpeg(im,fp_out, 100);

    cvReleaseMemStorage(storage)
    cvReleaseImage(img)
    cvReleaseImage(gray_scale)
    cvReleaseHaarClassifierCascade(cascade)
    gdImageDestroy(im);
    fclose(fp_out);
    fclose(fp_in);
    return 0;
}

ビルドは

gcc -lgd -lcv -lhighgui opencv.c