使用 Picasa API 自动进行人脸检测以提取单个图像
(已向超级用户提出类似的问题,以获取与应用程序相关的答案。该问题发布在这里是为了收集相同的可编程解决方案)
在我的工作场所,护照尺寸的照片被扫描在一起,然后剪切成单独的图片并以唯一的文件编号保存。目前我们使用Paint.net来手动选择、剪切和保存图片。
扫描文档 Picasa 屏幕截图示例: (来自:谷歌图像搜索多个来源,公平使用)
例如。在 Picasa 3.8 中,单击“查看”>“人,所有的面孔都显示出来,并要求我说出他们的名字,我可以将这些单独的图片自动保存为不同的图片吗?
已更新
我想要做的就是将上面的图片转换为单张图片。
在上图中,我展示了 Picasa 3.8 如何检测图像并提示我给它们命名。我不需要人脸识别,我只需要人脸检测。 Picasa 检测单个图像并将其显示在 RHS 上。这些单独的图像正是我所需要的。 Picasa 创建一个 .ini 文件,用于保存包含各个面的坐标的十六进制值。
这些单独的面孔是我感兴趣的。如果我可以有坐标,我可以从图片中裁剪所需的图像。
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() 中包含的数字,那么逗号后面括号外的数字呢?
我已经问过一个相关的问题。其中的答案也可能对您有帮助。 从 64 位十六进制值获取四个 16 位数字
注意: ini 详细信息与 picasa 相同 为特定图像生成。
而且问题已更新多次,可能不够清楚。
Picasa 帮助网站<中有一些回复/a>,我问了同样的问题 该线程的答案之一是根据 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.94633483887 余数 1:19598;结果1: 0.29904174804688 坐标:147.12854003906 156.99691772461 余数 1:62471;结果1: 0.95323181152344 坐标:468.99005126953 500.4467010498 余数 1:34078;结果1: 0.51998901367188 坐标:255.83459472656 272.99423217773
所以我也有坐标,@Nirmal有展示了如何裁剪它们。现在,下一步是解析 picasa.ini 的十六进制代码和文件名并集成代码。 Picasa 目前不通过 api 提供十六进制代码(或者是吗?)。如果真是这样的话,事情就更好了。
所以我们即将找到解决方案。谢谢大家,我希望我能把赏金奖励给每个人(我不能,但不要害怕,注意你的代表的激增!)
(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)
At my work place, passport sized photographs are scanned together, then cut up into individual pictures and saved with unique file numbers. Currently we use Paint.net to manually select, cut and save the pictures.
Sample Scanned Document Picasa Screenshot:
(from: google image search multiple sources, fairuse)
For eg. In Picasa 3.8, On clicking View > People, all the faces are shown and I am asked to name them, can I save these individual pictures automatically with the names as different pictures?
Updated
All I want to do is convert the picture above to individual pictures.
In the image above, I have shown how Picasa 3.8 detects the images and prompts me to name them. I do not need face recognition, I simply need face detection. Picasa detects the individual images and shows them on the RHS. These individual images are what I need. Picasa creates a .ini file which saves the hex values which contains the co-ordinates of the individual faces.
These individual faces are what I am interested in If I can have the co-ordinates, I can crop the required images from the picture.
SAMPLE.jpg
ini contents
[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
*The ini file seems to be saving the co-ordinates of the face tags as rect64(534a06d429ae627),dff6163dfd9d4e41
for each tag.
Quoting from Picasa Help Site user Technonath says
@oedious wrote:- This is going to be
somewhat technical, so hang on.
* The number encased in rect64() is a 64-bit hexadecimal number.
* Break that up into four 16-bit numbers.
* Divide each by the maximum unsigned 16-bit number (65535) and you'll have
four numbers between 0 and 1.
* The four numbers remaining give you relative coordinates for the face
rectangle: (left, top, right, bottom).
* If you want to end up with absolute coordinates, multiple the left and
right by the image width and the top
and bottom by the image height.
The above quote talks about the number encased in rect64() what about the number outside the parentheses after the comma?
I have asked a related question. Answers of which may help you too.
Get four 16bit numbers from a 64bit hex value
Note: The
ini details are the same which picasa
generated for the particular image.Plus the question has been updated multiple times and may not be clear enough.
There are some responses at the Picasa Help site, where I asked the same question
One of the answers from that thread to get co-ordinates based on the hex values from the ini file. The following code is in C# from esac from the help site. Can I do the same in 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 code trying to convert 64bit to numbers between 1 and 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/>";
}
?>
The output
Remainder 1 : 49551 ; Result 1 :
0.75608825683594 CO-ORDINATES : 371.99542236328 396.94633483887 Remainder 1 : 19598 ; Result 1 :
0.29904174804688 CO-ORDINATES : 147.12854003906 156.99691772461 Remainder 1 : 62471 ; Result 1 :
0.95323181152344 CO-ORDINATES : 468.99005126953 500.4467010498 Remainder 1 : 34078 ; Result 1 :
0.51998901367188 CO-ORDINATES : 255.83459472656 272.99423217773
So I have the co-ordinates too and @Nirmal has shown how to crop them. Now next steps would be to parse picasa.ini for the hex codes and file names and integrate the code. Picasa doesn't currently provide the hex codes via a api(or Do they?). If that were the case, things would have been better.
So we are nearing a solution. Thank you all, I wish I could award the bounty to everyone(I cannot, but fear not and look out for a spike in your rep!)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
查看 OpenCV - 发行版附带的示例之一是用于面部检测。
Look at OpenCV - one of the examples that comes with the distribution is for face detection.
你对问题的解决方案太过分了。忽略面孔。你所拥有的是纯白色背景和上面的一堆矩形图像。您需要做的就是找到包围每个图像和裁剪的矩形。
首先对标记所有非背景像素的原始图像运行过滤器。这需要一些调整,因为有时背景会有一点色调(污垢),或者照片会有一些看起来像背景的像素(真正的白牙齿)。
现在您要寻找没有背景颜色的大区域。将它们裁剪成矩形。
既然你是进行扫描的人,为什么不将背景设置为绿色呢?绿色可能是更容易过滤的颜色,特别是因为护照照片是在白色背景上拍摄的。
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.
要回答 picasa 问题,请参阅 picasa 论坛上的此回复:
http://www.google.com/support /forum/p/Picasa/thread?tid=36ae553a7b49088e&hl=zh-CN
To answer the picasa question, see this response on the picasa forums:
http://www.google.com/support/forum/p/Picasa/thread?tid=36ae553a7b49088e&hl=en
您可以进一步简化问题:-) 如果扫描的图像始终位于 5x4 网格中...那么您可以轻松使用任何提供位图操作的编程语言打开图像,并保存每个方块。下面是如何使用 C# 执行此操作的示例:
您需要做的就是计算每个矩形,然后调用此方法,该方法仅返回矩形定义的图像区域。像这样的东西(可能是伪代码,还没有编译下面的代码):
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#:
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):
对于裁剪部分,我在没有测试的情况下键入代码,但这应该可以工作:
上面的代码假设您的源图像采用 JPEG 格式,并且坐标形成完美的矩形或正方形。
希望有帮助。
For the cropping part, I am typing the code without testing, but this should work:
The above code assumes that your source image is in JPEG format and the coordinates make a perfect rectangle or square.
Hope that helps.
这应该能让你冲过终点线。这是一些解析 INI 的代码。
This should get you across the finish line. Here's some code to parse the INI.
我在 .NET 中开发了一个小应用程序,它完全按照您所说的操作,它生成面部文件。在这里查看:http://ceottaki.com/devprojects/getpicasafaces
源代码也可用。
虽然我还没有实现从联系人的十六进制代码中获取联系人的姓名,但可以使用 Google Contacts API:http://code.google.com/apis/contacts/
使用该 API,可以按 ID 获取联系人,如果您的联系人在 Picasa 和 Google 通讯录之间同步,则十六进制 ID 是相同的。
完整联系链接的最后一部分是 Picasa 使用的十六进制。
我希望这有帮助。
干杯,
费利佩.
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.