Автоматическое обнаружение лица с использованием API Picasa для извлечения отдельных изображений

StackOverflow https://stackoverflow.com/questions/3872112

Вопрос

(Подобный вопрос был задан на суперпользовательских ответах, связанных с заявками. Вопрос опубликован здесь, чтобы собрать программируемые решения для одного и того же)

На моем рабочем месте фотографии размеров паспорта сканируются вместе, затем вырезать на отдельные изображения и сохранены уникальными номерами файлов. В настоящее время мы используем Paint.net, чтобы вручную выбрать, вырезать и сохранить картинки.

Образец отсканированного документа Picasa Screenshot:(От: Google Image Search Поиск нескольких источников, Fairuse)

picasa screenshot

Например, В Picasa 3.8, нажав на нажатие> Люди, все лица показаны, и мне просят назвать их, могу ли я сохранить эти отдельные изображения автоматически с именами как разные картинки?

Обновленный

Все, что я хочу сделать, это преобразовать картину выше на отдельные фотографии.

На изображении выше, я показал, как Picasa 3.8 обнаруживает изображения и предложит мне назвать их называть. Мне не нужно распознавание лица, мне просто нужно обнаружение лица. Picasa обнаруживает отдельные изображения и показывает их на RHS. Эти индивидуальные изображения - это то, что мне нужно. Picasa создает файл .ini, который сохраняет шестнадцатеричные значения, которые содержат координаты отдельных лиц.

Эти индивидуальные лица - это то, что я заинтересован, если у меня могут быть координаты, я могу обрезать необходимые изображения с картинки.

Образец .jpg.

sample.jpg

Содержание INI

 [SAMPLE.jpg]
faces=rect64(c18f4c8ef407851e),d4ff0a020be5c3c0;rect64(534a06d429ae627),dff6163dfd9d4e41;rect64(b9c100fae46b3046),e1059dcf6672a2b3;rect64(7b5105daac3a3cf4),4fc7332c107ffafc;rect64(42a036a27062a6c),ef86c3326c143248;rect64(31f4efe3bd68fd8),90158b3d3b65dc9b;rect64(327904e0614d390d),43cbda6e92fcb63e;rect64(4215507584ae9b8c),15b6a967e857f334;rect64(895d4efeb8b68425),5c4ff70ac70b27d3
backuphash=3660

* Файл INI, похоже, сохраняет координаты тегов лица, как rect64(534a06d429ae627),dff6163dfd9d4e41 для каждого тега. Цитируя от Picasa Help сайта Пользователь Technonath. говорит

@oedious писал: - Это будет несколько техническим, поэтому держись. * Число, заключенное в RECT64 (), является 64-битным шестнадцатеричным числом. * Разбить это на четыре 16-битных номера. * Разделите каждый максимальный 16-битный номер без знака (65535), и у вас будет четыре количества от 0 до 1. * Четыре числа, остающиеся дают вам относительные координаты для прямоугольника лица: (левый, верхний, правый, нижний). * Если вы хотите в конечном итоге с абсолютной координатами, несколько левых и вправо по ширине изображения и верхней и нижней части высотой изображения.

Вышеуказанные цитаты рассказывают о количестве, заключенном в RECT64 () Как насчет номера за пределами скобок после запятой?

Я задал связанный вопрос. Ответы которого могут вам помочь.Получите четыре 16-битные номера из 64-битного шестигранного значения

Примечание. Подробности INI являются одинаковыми, которые Picasa генерируется для конкретного изображения.

Плюс вопрос был обновлен несколько раз и может быть недостаточно четко.

Есть некоторые ответы на Picasa Help сайта, Где я задал тот же вопрос один из ответов из этой нити, чтобы получить координаты на основе шестигранных значений из файла INI. Следующий код находится в C # из esac. с помощи сайта. Могу ли я сделать то же самое в PHP?

public static RectangleF GetRectangle(string hashstr)
{
    UInt64 hash = UInt64.Parse(hashstr, System.Globalization.NumberStyles.HexNumber);
    byte[] bytes = BitConverter.GetBytes(hash);

    UInt16 l16 = BitConverter.ToUInt16(bytes, 6);
    UInt16 t16 = BitConverter.ToUInt16(bytes, 4);
    UInt16 r16 = BitConverter.ToUInt16(bytes, 2);
    UInt16 b16 = BitConverter.ToUInt16(bytes, 0);

    float left = l16 / 65535.0F;
    float top = t16 / 65535.0F;
    float right = r16 / 65535.0F;
    float bottom = b16 / 65535.0F;

    return new RectangleF(left, top, right - left, bottom - top);
} 

PHP код пытаясь Конвертировать 64 бит до номеров от 1 до 0

<?php
$dim = getimagesize("img.jpg");    
$hex64=array();
$b0="c18f4c8ef407851e";
$hex64[]=substr($b0,0,4);
$hex64[]=substr($b0,4,4);
$hex64[]=substr($b0,8,4);
$hex64[]=substr($b0,12,4);
$width=$dim[0];
$height=$dim[1];
foreach($hex64 as $hex16){
$dec=hexdec($hex16);
$divide=65536;
$mod=$dec%$divide;
$result=$dec/$divide;
$cordinate1=$result*$width;
$cordinate2=$result*$height;
echo "Remainder 1 : ".$mod." ; Result 1 :  ".$result."<br/>CO-ORDINATES : <B>".$cordinate1." ".$cordinate2."</B><br/>";
}
?>

Выход

Остальная часть 1: 49551; Результат 1: 0,75608825683594 Координаты: 371.99542236328 396.946328 396.94633483887 Остальная часть 1: 19598; Результат 1: 0.29904174804688 Координаты: 147.12854003906 156.99691772461 Остальная часть 1: 62471; Результат 1: 0.95323181152344 Координаты: 468.99005126953 500.4467010498 Остальная часть 1: 34078; Результат 1: 0.519989013671888 Координаты: 255.83459472656 272.99423217773

Поэтому у меня тоже координаты, а @nirmal показано, как их обрезать. Отказ Теперь следующие шаги будут проанализировать Picasa.ini для шестнадцатеричных кодов и имени файлов и интегрировать код. Picasa в настоящее время не предоставляет шестнадцатеричные коды через API (или Они?). Если это было так, все было бы лучше.

Таким образом, мы приближаемся к решению. Спасибо всем, я бы хотел наградить щедрость для всех (я не могу, но не бойся и не обращаться за шипом в вашем представлении!)

Это было полезно?

Решение

Чтобы ответить на вопрос Picasa, посмотрите этот ответ на форумах Picasa:
http://www.google.com/support/forum/p/picasa/thread?tid=36ae553a7b49088e&hl=en.

@oedious писал: - Это будет несколько техническим, поэтому держись. * Число, заключенное в RECT64 (), является 64-битным шестнадцатеричным числом. * Разбить это на четыре 16-битных номера. * Разделите каждый максимальный 16-битный номер без знака (65535), и у вас будет четыре количества от 0 до 1. * Четыре числа, остающиеся дают вам относительные координаты для прямоугольника лица: (левый, верхний, правый, нижний). * Если вы хотите в конечном итоге с абсолютной координатами, несколько левых и вправо по ширине изображения и верхней и нижней части высотой изображения.

Другие советы

смотреть на Openc. - Один из примеров, которые поставляются с распределением, предназначен для обнаружения лица.

Ваше решение проблемы - это сверху. Игнорировать грани. То, что у вас есть сплошной белый фон и куча прямоугольных изображений на нем. Все, что вам нужно сделать, это найти прямоугольник, который охватывает каждое изображение и урожай.

Начните с запуска фильтра над исходным изображением, которое отмечает все нерусные пиксели. Это займет некоторую настройку, потому что иногда фона будет иметь прикосновение оттенка в нем (грязь) или фото будет иметь несколько пикселей, которые выглядят как фон (действительно белые зубы).

Теперь вы ищете большие районы без цвета фона в них. Обрезать их в прямоугольники.

Поскольку вы делаете сканирование, почему бы не сделать фон зеленого цвета? Зеленый может быть легким цветом для фильтрации, особенно поскольку фотографии паспорта принимаются на белом фоне.

Вы можете упростить проблему еще дальше :-) Если отсканированные изображения всегда будут в сетке 5x4 ... Тогда вы можете без труда Просто откройте изображение практически в любом языке программирования, который предлагает растровые манипулирования и сохранить каждый квадрат. Вот пример того, как это сделать с C #:

private Image Crop(Image pics, Rectangle area)
{
   var bitmap = new Bitmap(pics);
   return (Image)bitmap.Clone(area, bitmap.PixelFormat);
}

Все, что вам нужно сделать, это рассчитать каждый прямоугольник, а затем вызовите этот метод, который возвращает только площадь изображения, определенного прямоугольником. Что-то вроде (возможно, псевдо код, не скомпилировали код ниже):

// assuming that each sub image in the larger is 45x65
int cellwidth=45, cellheight=65;

for(int row=0;row<5;row++)
{
  for(int col=0;col<4;col++)
  {
    var rect = new Rectangle(
      row * cellwidth,
      col * cellheight,
      cellwidth,
      cellheight);
    var picture = Crop(bigPicture, rect);
    // then save the sub image with whatever naming convention you need
  }
}

Для ракетной части я печатаю код без тестирования, но это должно работать:

<?php
//source image
$srcImg = "full/path/of/source/image.jpg";
//output image
$outImg = "full/path/to/result/image.jpg";

//coordinates obtained from your calculation
$p1 = array('X'=>371, 'Y'=>156);
$p2 = array('X'=>468, 'Y'=>156);
$p3 = array('X'=>468, 'Y'=>272);
$p4 = array('X'=>371, 'Y'=>272);

//let's calculate the parametres
$srcX = $p1['X'];
$srcY = $p1['Y'];
$width = $p2['X'] - $p1['X'];
$height = $p4['Y'] - $p1['Y'];

//image processing
$srcImg = imagecreatefromjpeg($srcImg);
$dstImg = imagecreatetruecolor($width, $height);
imagecopy($dstImg, $srcImg, 0, 0, $srcX, $srcY, $width, $height);
imagejpeg($dstImg, $outImg, 100); // 100 for highest quality, 0 for lowest quality
imagedestroy($dstImg);
?>

Приведенный выше код предполагает, что ваше исходное изображение находится в формате JPEG, и координаты делают идеальный прямоугольник или квадрат.

Надеюсь, это поможет.

Это должно заставить вас по отдельности. Вот какой-то код для анализа INI.

<?php
$vals = parseIni('picasa.ini');
foreach($vals as $filename => $values) {
    $rects = getRects($values['faces']);
    foreach($rects as $rect) {
        printImageInfo($filename, $rect);
    }
}

/**
 * PHP's own parse_ini_file doesn't like the Picasa format.
 */
function parseIni($file)
{
    $index = 0;
    $vals = array();
    $f = fopen($file, 'r');
    while(!feof($f)) {
        $line = trim(fgets($f));
        if (preg_match('/^\[(.*?)\]$/', $line, $matches)) {
            $index = $matches[1];
            continue;
        }

        $parts = explode('=', $line, 2);
        if (count($parts) < 2) continue;
        $vals[$index][$parts[0]] = $parts[1];
    }

    fclose($f);
    return $vals;
}

function getRects($values)
{
    $values = explode(';', $values);
    $rects = array();
    foreach($values as $rect) {
        if (preg_match('/^rect64\(([^)]+)\)/', $rect, $matches)) {
            $rects[] = $matches[1];
        }
    }

    return $rects;
}

function printImageInfo($filename, $rect)
{
    $dim = getimagesize($filename);    
    $hex64=array();
    $hex64[]=substr($rect,0,4);
    $hex64[]=substr($rect,4,4);
    $hex64[]=substr($rect,8,4);
    $hex64[]=substr($rect,12,4);
    $width=$dim[0];
    $height=$dim[1];
    foreach($hex64 as $hex16){
        $dec=hexdec($hex16);
        $divide=65536;
        $mod=$dec%$divide;
        $result=$dec/$divide;
        $cordinate1=$result*$width;
        $cordinate2=$result*$height;
        echo "Remainder 1 : ".$mod." ; Result 1 :  ".$result."<br/>CO-ORDINATES : <B>".$cordinate1." ".$cordinate2."</B><br/>";
    }
}

Я разработал небольшое приложение в .NET, которая имеет именно то, что вы сказали, он производит файлы для граней. Проверьте это здесь: http://ceottaki.com/devprojects/getpicasafaces.

Исходный код также доступен.

Пока я не реализовал получение имени контактов из своего шестнадцатеричного кода, можно использовать API Google Contacts: http://code.google.com/apis/contacts/

С помощью этого API можно получить контакты по ID, и если ваши контакты синхронизируются между Picasa и контактами Google, шестнадцатеричный идентификатор одинаков.

Последняя часть полной контактной ссылки является шестнадцатеричным, используемым Picasa.

Надеюсь, это поможет.

Ура, Фелипе.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top