| | |
| | | package face |
| | | |
| | | import ( |
| | | "unsafe" |
| | | "fmt" |
| | | "unsafe" |
| | | ) |
| | | |
| | | // #if FEATURE_NORMALIZE |
| | | // float CosineDistance(const BYTE* fea1, const BYTE* fea2, int length) |
| | | // { |
| | | // int i; |
| | | // const float* jfea1 = (const float*)fea1; |
| | | // const float* jfea2 = (const float*)fea2; |
| | | |
| | | // float score = 0.0f; |
| | | // for (i = 0; i < length; i++) |
| | | // { |
| | | // score += jfea1[i] * jfea2[i]; |
| | | // } |
| | | |
| | | // return score; |
| | | // } |
| | | // #else |
| | | // float CosineDistance(const BYTE* fea1, const BYTE* fea2, int length) |
| | | // { |
| | | // int i; |
| | | // const float* jfea1 = (const float*)fea1; |
| | | // const float* jfea2 = (const float*)fea2; |
| | | // double normTemp1 = 0.0; |
| | | // double normTemp2 = 0.0; |
| | | // double normTemp = 0.0; |
| | | |
| | | // double score = 0.0f; |
| | | // for (i = 0; i < length; i++) { |
| | | // score += jfea1[i] * jfea2[i]; |
| | | // normTemp1 += jfea1[i] * jfea1[i]; |
| | | // normTemp2 += jfea2[i] * jfea2[i]; |
| | | // } |
| | | // normTemp = sqrt(normTemp1)*sqrt(normTemp2); |
| | | |
| | | // score = score / normTemp; |
| | | |
| | | // return score; |
| | | // } |
| | | // #endif |
| | | |
| | | // int feaDim = FEATURE_RAW_SIZE / 4; |
| | | |
| | | // THFEATURE_API float EF_Compare(BYTE* pFeature1,BYTE* pFeature2) |
| | | // { |
| | | // if(pFeature1==NULL||pFeature2==NULL) return 0.0f; |
| | | |
| | | // float fscore; |
| | | |
| | | // BYTE* pFea1=pFeature1; |
| | | // BYTE* pFea2=pFeature2; |
| | | |
| | | // fscore = CosineDistance(pFea1, pFea2, feaDim); |
| | | // fscore+=0.05f; |
| | | |
| | | // if(fscore>0.9999f) fscore=0.9999f; |
| | | // if(fscore<0.0001f) fscore=0.0001f; |
| | | |
| | | // return fscore; |
| | | // } |
| | | func DecCompare(feat1 []byte, feat2 []byte) float32 { |
| | | ffeat1 := byteSlice2float32Slice(feat1) |
| | | ffeat2 := byteSlice2float32Slice(feat2) |
| | | if len(ffeat1) != len(ffeat2) { |
| | | return 0 |
| | | } |
| | | // normalize |
| | | var score float32 |
| | | for i := 0; i < len(ffeat1); i++ { |
| | | score += ffeat1[i] * ffeat2[i] |
| | | } |
| | | score += 0.05 |
| | | if score > 0.9999 { |
| | | score = 0.9999 |
| | | } |
| | | if score < 0.0001 { |
| | | score = 0.0001 |
| | | } |
| | | return score |
| | | ffeat1 := byteSlice2float32Slice(feat1) |
| | | ffeat2 := byteSlice2float32Slice(feat2) |
| | | if len(ffeat1) != len(ffeat2) { |
| | | return 0 |
| | | } |
| | | fmt.Println("len:", len(ffeat1), len(feat2)) |
| | | //fmt.Println("ffeat1:", ffeat1, "ffeat2:", ffeat2, "len:", len(ffeat1), len(feat2)) |
| | | // normalize |
| | | var score float32 |
| | | for i := 0; i < 1536; i++ { |
| | | score += ffeat1[i] * ffeat2[i] |
| | | } |
| | | score += 0.05 |
| | | if score > 0.9999 { |
| | | score = 0.9999 |
| | | } |
| | | if score < 0.0001 { |
| | | score = 0.0001 |
| | | } |
| | | fmt.Println("score:", score) |
| | | return score |
| | | } |
| | | |
| | | func byteSlice2float32Slice(src []byte) []float32 { |
| | | if len(src) == 0 { |
| | | return nil |
| | | } |
| | | if len(src) == 0 { |
| | | return nil |
| | | } |
| | | |
| | | l := len(src) / 4 |
| | | ptr := unsafe.Pointer(&src[0]) |
| | | l := len(src) / 4 |
| | | ptr := unsafe.Pointer(&src[0]) |
| | | |
| | | return (*[1 << 26]float32)(ptr)[:l:l] |
| | | return (*[1 << 26]float32)((*[1 << 26]float32)(ptr))[:l:l] |
| | | } |