图片搜索/匹配PHASH实现改进 |
发布: 2012-12-09 15:19 |
phash是一个图片特征抽取算法实现, 该算法相对还比较简单,特征值只是一个64位无符号整数。 在使用PHP扩展程序处理的时候,原版本的扩展只返回资源类型的值, 只能实时做对比处理,无法把它存储起来。 通过阅读它的PHP扩展,发现修改一下代码即能把资源转变为整数返回, 添加一个扩展函数,PHP_FUNCTION(phash_toint); 参数为使用phash_imagehash返回的资源类型值, 实现函数为, PHP_FUNCTION(phash_toint) { zval * h1_res = NULL; int h1_resid = -1; ulong64 * h1; zval * h2_res = NULL; int h2_resid = -1; ulong64 * h2; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &h1_res) == FAILURE) { return; } ZEND_FETCH_RESOURCE(h1, ulong64 *, &h1_res, h1_resid, "ph_image_hash", le_ph_image_hash); long long int ih1 = *h1; char rbuf[32] = {0}; sprintf(rbuf, "%lu", ih1); RETVAL_STRING(rbuf, true); } 这样可以把图片的特征值存储起来,如存储在关系数据库中,后面可以直接拿来使用。 另外,以使用mysql为例,通过编写一个mysql用户定义函数, 可以在查询的时候直接调用特征匹配算法,把匹配度在一定范围的结果返回, my_bool ham_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { return 0; } void ham_deinit(UDF_INIT *initid) { } long long ham(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) { ulonglong ih1 = *((ulonglong*) args->args[0]); ulonglong ih2 = *((ulonglong*) args->args[1]); ulonglong x = ih1 ^ ih2; // x = 11611742962838811245UL ^ 10221281696820229275UL; const ulonglong m1 = 0x5555555555555555ULL; const ulonglong m2 = 0x3333333333333333ULL; const ulonglong h01 = 0x0101010101010101ULL; const ulonglong m4 = 0x0f0f0f0f0f0f0f0fULL; x -= (x >> 1) & m1; x = (x & m2) + ((x >> 2) & m2); x = (x + (x >> 4)) & m4; return (x * h01)>>56; } 自定义函数 ham(h1, h2);的两个参数是需要计算的两个图片的特征值, 返回值为特征的相似度,越小越相似,为0的时候为完全相同。 通过编写mysql自定义函数的方式,把这个编译成一个插件,加载到mysql中, 如如下SQL, select * from t1 where ham(phash_value_field, 34567) < 10; 即可检索出匹配度小于10结果。 参考: phash主站,http://www.phash.org |
原文: http://qtchina.tk/?q=node/701 |
Powered by zexport
|