Pregunta

(Una pregunta similar se ha preguntado el superusuario de respuestas relacionadas con las aplicaciones. La cuestión está publicada aquí para reunir las soluciones programables para el mismo)

En mi lugar de trabajo, fotografías tamaño pasaporte se exploran juntos, y luego cortado en cuadros individuales y guardado con los números de archivo únicos. Actualmente utilizamos Paint.net a manualmente seleccionar, cortar y guardar las imágenes.

muestra de exploración Documento Picasa Captura: (De: Imagen de búsqueda de google múltiples fuentes, FairUse)

picasa pantalla

Para por ejemplo. En Picasa 3.8, Al hacer clic en Ver> Las personas, todas las caras se muestran y se me pide que nombrarlos, ¿Puedo guardar estas imágenes individuales automáticamente con los nombres como diferentes imágenes?

Actualización

Todo lo que queremos hacer es convertir la imagen de arriba a una sola imagen.

En la imagen de arriba, he mostrado cómo Picasa 3.8 detecta las imágenes y me impulsa a nombrarlos. No necesito detección de rostros de reconocimiento facial, simplemente necesito. Picasa detecta las imágenes individuales y ellos en el lado derecho. Estas imágenes individuales son lo que necesito. Picasa crea un archivo .ini que ahorra los valores hex que contiene las coordenadas de las caras individuales.

Estas caras individuales son lo que yo estoy interesado en si puedo tener las coordenadas, puedo recortar las imágenes necesarias de la imagen.

SAMPLE.jpg

sample.jpg

contenido 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

* El archivo ini parece estar salvando las coordenadas de las etiquetas de cara como rect64(534a06d429ae627),dff6163dfd9d4e41 para cada etiqueta. Citando de usuario Ayuda de Picasa Sitio Technonath dice

  

@oedious escribió: - Esto va a ser   algo técnica, por lo que aferrarse.   * El número encerrado en rect64 () es un número hexadecimal de 64 bits.   * Romper que hasta en cuatro números de 16 bits.   * Dividir cada por el número de 16 bits sin signo máximo (65535) y tendrá   cuatro números entre 0 y 1.   * Los cuatro restantes números que dan las coordenadas relativas para la cara   rectángulo: (izquierda, arriba, derecha, abajo).   * Si usted quiere terminar con coordenadas absolutas, múltiple y la dejó   derecho por el ancho de la imagen y la parte superior   y parte inferior por la altura de la imagen.

La cita anterior habla sobre el número encerrado en rect64 () ¿qué pasa con el número fuera del paréntesis después de la coma?

He hecho una pregunta relacionada. Las respuestas de los cuales pueden ayudar a usted también. conseguir cuatro números de 16 bits de un valor hexadecimal de 64 bits

  

Nota: El   detalles ini son los mismos que picasa   generada para la imagen particular.

     

Además, la cuestión se ha actualizado varias veces y pueden no ser lo suficientemente claro.

Hay algunas respuestas en el href="http://www.google.com/support/forum/p/Picasa/thread?tid=36ae553a7b49088e&hl=en" rel="nofollow noreferrer"> Ayuda de Picasa sitio , donde me hice la misma pregunta Una de las respuestas de ese hilo para obtener las coordenadas en base a los valores hex desde el archivo ini. El siguiente código está en C # desde esac desde el sitio de ayuda. ¿Puedo hacer lo mismo en 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);
} 

código PHP tratando de converso de 64 bits a números entre 1 y 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/>";
}
?>

La salida

  

El resto 1: 49.551; Resultado 1:   0.75608825683594 Las coordenadas: 371.99542236328 396.94633483887 Resto 1: 19598; Resultado 1:   0.29904174804688 Las coordenadas: 147.12854003906 156.99691772461 Resto 1: 62471; Resultado 1:   0.95323181152344 Las coordenadas: 468.99005126953 500,4467010498 Resto 1: 34078; Resultado 1:   0.51998901367188 Las coordenadas: 255.83459472656 272,99423217773

Así que tengo las coordenadas también y tiene @Nirmal muestran cómo recortar los . Ahora próximos pasos serían para analizar picasa.ini de los códigos hexadecimales y nombres de archivos e integrar el código. Picasa no proporciona actualmente los códigos hexadecimales a través de una API (o ¿verdad? ). Si ese fuera el caso, las cosas habrían sido mejor.

Así que nos acercamos a una solución. Gracias a todos, me gustaría poder otorgar la recompensa a todo el mundo (no puedo, pero no el miedo y mirar hacia fuera para un alza en su representante!)

¿Fue útil?

Solución

Para responder a la pregunta picasa, ver esta respuesta en los foros de Picasa:
http://www.google.com/support/forum / p / Picasa / hilo? tid = 36ae553a7b49088e & hl = es

  

@oedious escribió: - Esto va a ser   algo técnica, por lo que aferrarse.   * El número encerrado en rect64 () es un número hexadecimal de 64 bits.   * Romper que hasta en cuatro números de 16 bits.   * Dividir cada por el número de 16 bits sin signo máximo (65535) y tendrá   cuatro números entre 0 y 1.   * Los cuatro restantes números que dan las coordenadas relativas para la cara   rectángulo: (izquierda, arriba, derecha, abajo).   * Si usted quiere terminar con coordenadas absolutas, múltiple y la dejó   derecho por el ancho de la imagen y la parte superior   y parte inferior por la altura de la imagen.

Otros consejos

Look en OpenCV - uno de los ejemplos que viene con la distribución es para la detección de la cara <. / p>

Su solución al problema es un exceso. Ignorar las caras. Lo que tenemos es un fondo blanco sólido y un montón de imágenes rectangulares en él. Todo lo que necesita hacer es encontrar el rectángulo que encierra cada imagen y cultivos.

Comience por ejecutar un filtro sobre la imagen original que marca todos los píxeles no de fondo. Esto tomará algún ajuste, porque a veces el fondo tendrá un toque de tinte en ella (suciedad) o la foto tendrá algunos píxeles que se parecen al fondo (en realidad dientes blancos).

Ahora se mira para grandes zonas sin color de fondo en ellos. Recortar los en rectángulos.

Dado que usted es el que hace el escaneo, por qué no hacer el fondo verde? Verde podría ser un color más fácil de filtrar, sobre todo porque las fotos de pasaporte se toman sobre un fondo blanco.

Se puede simplificar aún más el problema :-) si las imágenes escaneadas siempre estarán en una cuadrícula de 5x4 ... entonces usted puede fácilmente acaba de abrir la imagen en casi cualquier lenguaje de programación que ofrece la manipulación de mapa de bits, y guardar cada cuadrado. Aquí está un ejemplo de cómo hacer esto con C #:

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

Todo lo que se necesita hacer es calcular cada rectángulo, y luego llamar a este método que devuelve sólo el área de la imagen definida por el rectángulo. Algo así como (posiblemente pseudo código, no han compilado el código de abajo):

// 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
  }
}

Para la parte de recorte, estoy escribiendo el código sin pruebas, pero esto debería funcionar:

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

El código anterior supone que la imagen de origen está en formato JPEG y las coordenadas hacer un rectángulo o cuadrado perfecto.

Espero que ayude.

Esto debe obtener a través de la línea de meta. Aquí hay algo de código para analizar el 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/>";
    }
}

he desarrollado una pequeña aplicación en .NET que hace exactamente lo que ha dicho, que produce los archivos de las caras. Échale un vistazo aquí: http://ceottaki.com/devprojects/getpicasafaces

El código fuente está disponible también.

Si bien no he implementado obtener el nombre de los contactos de su código hexadecimal, es posible utilizar la API de contactos Google: http://code.google.com/apis/contacts/

Con esa API, es posible obtener los contactos por ID, y si los contactos se sincronizan entre Picasa y Google Contacts, el ID hexadecimal es el mismo.

La última parte de un enlace de contacto completo es el hexadecimal utilizado por Picasa.

Espero que esto ayude.

Cheers, Felipe.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top