feat: added arcface

This commit is contained in:
kweijack
2024-07-04 13:36:50 +00:00
parent cae3b4cc48
commit 47fceab295
8 changed files with 162 additions and 0 deletions
+12
View File
@@ -57,6 +57,18 @@ This repository contains a suite of face AI models designed for various applicat
<img src="docs/2dfan4.jpg" height=200>
### ArcFace for Feature Embedding
- Model Name: [arcface](model/arcface/arcface.go)
- Description: Generates feature embeddings for faces, useful for identity verification and facial recognition tasks.
- Download Link: [Download ArcFace Model](https://github.com/facefusion/facefusion-assets/releases/download/models/arcface_w600k_r50.onnx)
*Cosine distance of arcface embedding*
| Source\Target | <img src="docs/arcface_1.jpg" height=80 align=right> | <img src="docs/arcface_2.jpg" height=80 align=right> | <img src="docs/arcface_3.jpg" height=80 align=right> |
| :-----: | :-: | :---: | :-----: |
| <img src="docs/arcface_1.jpg" height=80 align=right> | 0.00 | 0.29 | 0.48 |
| <img src="docs/arcface_2.jpg" height=80 align=right> | 0.29 | 0.00 | 0.45 |
| <img src="docs/arcface_3.jpg" height=80 align=right> | 0.48 | 0.45 | 0.00 |
### Gender and Age Estimation
- Model Name: [gender_age](model/genderage/genderage.go)
- Description: Detects gender and estimates the age of detected faces.
Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

+40
View File
@@ -0,0 +1,40 @@
package arcface
import (
"github.com/dev6699/face/model"
"gocv.io/x/gocv"
)
type Model struct{}
type Input struct {
Img gocv.Mat
FaceLandmark5 []gocv.Point2f
}
type Output struct {
Embedding []float32
NormedEmbedding []float32
}
type TModel = model.Model[*Input, *Output]
var _ TModel = &Model{}
func NewFactory() func() TModel {
return func() TModel {
return New()
}
}
func New() *Model {
return &Model{}
}
func (m *Model) ModelName() string {
return "arcface_w600k_r50"
}
func (m *Model) ModelVersion() string {
return "1"
}
+55
View File
@@ -0,0 +1,55 @@
package arcface
import (
"math"
"github.com/dev6699/face/model"
)
func (m *Model) PostProcess(rawOutputContents [][]byte) (*Output, error) {
// "outputs": [
// {
// "name": "683",
// "datatype": "FP32",
// "shape": [
// 1,
// 512
// ]
// }
// ]
embedding, err := model.BytesToFloat32Slice(rawOutputContents[0])
if err != nil {
return nil, err
}
normedEmbedding := normalizeEmbedding(embedding)
return &Output{
Embedding: embedding,
NormedEmbedding: normedEmbedding,
}, nil
}
// Normalize the embedding
func normalizeEmbedding(embedding []float32) []float32 {
normalizeEmbedding := make([]float32, len(embedding))
norm := float32(l2Norm(embedding))
if norm == 0 {
normalizeEmbedding = append(normalizeEmbedding, embedding...)
return normalizeEmbedding // Avoid division by zero
}
for i, val := range embedding {
normalizeEmbedding[i] = (val / norm)
}
return normalizeEmbedding
}
// Compute the L2 norm of a vector
func l2Norm(vector []float32) float64 {
var sum float64
for _, val := range vector {
sum += float64(val * val)
}
return math.Sqrt(sum)
}
+44
View File
@@ -0,0 +1,44 @@
package arcface
import (
"github.com/dev6699/face/model"
"github.com/dev6699/face/protobuf"
"gocv.io/x/gocv"
)
func (m *Model) PreProcess(i *Input) ([]*protobuf.InferTensorContents, error) {
cropVisionFrame, affineMatrix := model.WarpFaceByFaceLandmark5(
i.Img,
i.FaceLandmark5,
arcface_112_v2,
model.Size{Width: 112, Height: 112},
)
defer cropVisionFrame.Close()
defer affineMatrix.Close()
d := []float32{}
cropVisionFrame.ConvertTo(&cropVisionFrame, gocv.MatTypeCV32F)
cropVisionFrame.DivideFloat(127.5)
model.MatSubtract(cropVisionFrame, 1.0)
rgbChannels := gocv.Split(cropVisionFrame)
b := rgbChannels[2]
defer b.Close()
bd, _ := b.DataPtrFloat32()
d = append(d, bd...)
g := rgbChannels[1]
defer g.Close()
gd, _ := g.DataPtrFloat32()
d = append(d, gd...)
r := rgbChannels[0]
defer r.Close()
rd, _ := r.DataPtrFloat32()
d = append(d, rd...)
contents := &protobuf.InferTensorContents{
Fp32Contents: d,
}
return []*protobuf.InferTensorContents{contents}, nil
}
+11
View File
@@ -0,0 +1,11 @@
package arcface
import "gocv.io/x/gocv"
var arcface_112_v2 = []gocv.Point2f{
{X: 0.34191607, Y: 0.46157411},
{X: 0.65653393, Y: 0.45983393},
{X: 0.50022500, Y: 0.64050536},
{X: 0.37097589, Y: 0.82469196},
{X: 0.63151696, Y: 0.82325089},
}