Automatic face detection using Picasa API to extract individual images

前端 未结 7 1167
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-13 01:15

(A similar question has been asked on superuser for answers related to applications. The question is posted here to gather programmable solutions for the same)

相关标签:
7条回答
  • 2020-12-13 01:35

    I've developed a little app in .NET that does exactly what you said, it produces the files for the faces. Check it out here: http://ceottaki.com/devprojects/getpicasafaces

    The source code is available as well.

    While I haven't implemented getting the name of the contacts from their hexadecimal code, it is possible using the Google Contacts API: http://code.google.com/apis/contacts/

    With that API it is possible to get contacts by ID, and if your contacts are synced between Picasa and Google Contacts, the hexadecimal ID is the same.

    The last part of a full contact link is the hexadecimal used by Picasa.

    I hope this helps.

    Cheers, Felipe.

    0 讨论(0)
  • 2020-12-13 01:36

    You can simplify the problem even further :-) if the scanned images will always be in a 5x4 grid ... then you can easily just open the image in just about any programming language that offers bitmap manipulation, and save each square. Here's an example of how to do this with C#:

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

    All you'd need to do is calculate each rectangle, and then call this method which returns just the area of the image defined by the rectangle. Something like (possibly pseudo code, haven't compiled the code below):

    // 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
      }
    }
    
    0 讨论(0)
  • 2020-12-13 01:40

    Your solution to the problem is overkill. Ignore the faces. What you have is a solid white background and a bunch of rectangular images on it. All you need to do is find the rectangle that encloses each image and crop.

    Start by running a filter over the original image that marks all non-background pixels. This will take some tuning because sometimes the background will have a touch of tint in it (dirt) or the photo will have some pixels that look like the background (really white teeth).

    Now you look for large areas with no background color in them. Crop those into rectangles.

    Since you are the one doing the scanning, why not make the background green? Green might be an easier color to filter, especially since the passport photos are taken on a white background.

    0 讨论(0)
  • 2020-12-13 01:49

    Look at OpenCV - one of the examples that comes with the distribution is for face detection.

    0 讨论(0)
  • 2020-12-13 01:49

    This should get you across the finish line. Here's some code to parse the 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/>";
        }
    }
    
    0 讨论(0)
  • 2020-12-13 01:51

    For the cropping part, I am typing the code without testing, but this should work:

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

    The above code assumes that your source image is in JPEG format and the coordinates make a perfect rectangle or square.

    Hope that helps.

    0 讨论(0)
提交回复
热议问题