Intereting Posts

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

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

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

Пример сканированного документа Скриншот Picasa: (из: поиск изображений Google по нескольким источникам, fairuse)

скриншот picasa

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

обновленный

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

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

Меня интересуют отдельные лица. Если у меня есть координаты, я могу обрезать нужные изображения с картинки.

sample.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 Technonath говорит

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

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

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

Примечание. Детали ini – это то же самое, что и picasa для определенного изображения.

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

На сайте справки Picasa есть несколько ответов, на которых я задал один и тот же вопрос. Один из ответов из этого потока, чтобы получить координаты на основе шестнадцатеричных значений из 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 CO-ORDINATES: 371.99542236328 396.94633483887 Остаток 1: 19598; Результат 1: 0.29904174804688 CO-ORDINATES: 147.12854003906 156.99691772461 Остаток 1: 62471; Результат 1: 0,95323181152344 CO-ORDINATES: 468.99005126953 500.4467010498 Остаток 1: 34078; Результат 1: 0.51998901367188 CO-ORDINATES: 255.83459472656 272.99423217773

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

Поэтому мы приближаемся к решению. Спасибо всем, мне жаль, что я не смогу присудить награду всем (я не могу, но не боюсь и не смотрю на всплеск в вашем репутации!)

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

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

Посмотрите на OpenCV – один из примеров, который поставляется с дистрибутивом, предназначен для обнаружения лиц.

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

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

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

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

Вы можете еще больше упростить эту проблему 🙂 если отсканированные изображения всегда будут в сетке 5×4 … тогда вы можете легко просто открыть изображение практически на любом языке программирования, который предлагает растровое манипулирование, и сохранить каждый квадрат. Вот пример того, как это сделать с 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: http://code.google.com/apis/contacts/

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

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

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

Привет, Фелипе.