传统的php裁剪类只能按位置裁剪。如按中间位置裁剪。这种裁剪方式可能会导致一个人被截成两段。为了解决这个问题,最近开发了一个php扩展(tclip),能自动识别人脸或者图像中其它重要区域,然后进行裁剪。裁剪效果如下: 原图: 如果按照从中间截取为 400 *
传统的php裁剪类只能按位置裁剪。如按中间位置裁剪。这种裁剪方式可能会导致一个人被截成两段。为了解决这个问题,最近开发了一个php扩展(tclip),能自动识别人脸或者图像中其它重要区域,然后进行裁剪。裁剪效果如下:
原图:
如果按照从中间截取为 400 * 225 大小大图片。效果如下:
使用tclip扩展裁剪图片效果如下:
在人脸识别的过程中,需要使用opencv中的cascadeclassifier加载一个xml的配置文档。因为文档比较大,导致加载时间比较长。为了提高裁剪的效率,决定在php扩展初始化的时候加载,并使用全局变量存储这个cascadeclassifier对象。这样就可以在每次裁剪的时候直接使用这个配置文件,而无需再加载。
开始,把php_tclip.h中的全局变量声明部分修改为如下:
zend_begin_module_globals(tclip) cascadeclassifier face_cascade; char *face_config_path;zend_end_module_globals(tclip)
结果报如下错误:
error: ‘cascadeclassifier’ does not name a type
看来这个类没有在头文件中声明。那就另辟蹊径,改为其它方式。把代码改为:
zend_begin_module_globals(tclip) void *face_cascade; char *face_config_path;zend_end_module_globals(tclip)
然后在tclip.c中进行了如下修改:
1.首先定义了一个全局变量。
static cascadeclassifier face_cascade;
2.修改php_minit_function(tclip)。代码如下:
php_minit_function(tclip){ /* if you have ini entries, uncomment these lines */ register_ini_entries(); string face_config_path = (tclip_g(face_config_path) == || tclip_g(face_config_path) == null)? /usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml :tclip_g(face_config_path); if( !face_cascade.load( face_config_path ) ){ php_error_docref(null tsrmls_cc, e_warning, can not load classifier file!%s, face_config_path.c_str()); return failure; } tclip_g(face_cascade) = &face_cascade; return success;}
调用全局对象的方式如下:
((cascadeclassifier *)tclip_g(face_cascade))->detectmultiscale( img_gray, faces, 1.1, 2, 0|cv_haar_scale_image, size(30, 30) );
注意,php扩展想线程安全,那就用相关宏来访问全局变量。如上面的tclip_g(face_cascade)。
相关参考资料 http://www.laruence.com/2009/04/28/719.html
原文地址:php扩展中如何定义线程安全的全局对象, 感谢原作者分享。