| package detector |
|
|
| import ( |
| "image" |
|
|
| pigo "github.com/esimov/pigo/core" |
|
|
| "github.com/metatube-community/metatube-sdk-go/common/cluster" |
| "github.com/metatube-community/metatube-sdk-go/detector/internal/position" |
| ) |
|
|
| const ( |
| |
| |
| tolerance = 0.05 |
| ) |
|
|
| func computeFaceWeight(face pigo.Detection) float64 { |
| |
| return float64(face.Scale) * float64(face.Q) |
| } |
|
|
| func extractFaceVector(img image.Image, face pigo.Detection) position.Vector { |
| var ( |
| width = img.Bounds().Dx() |
| height = img.Bounds().Dy() |
| ) |
| return position.NewVector( |
| position.Position(float64(face.Col)/float64(width)), |
| position.Position(float64(face.Row)/float64(height)), |
| ) |
| } |
|
|
| func dominantAxisByRatio(img image.Image, ratio float64) int { |
| var ( |
| width = img.Bounds().Dx() |
| height = img.Bounds().Dy() |
| ) |
| if int(float64(height)*ratio) < width { |
| return 0 |
| } else { |
| return 1 |
| } |
| } |
|
|
| func clusterFaceVectors(img image.Image, faces []pigo.Detection, dims ...int) []cluster.Group[position.WeightedVector, float64] { |
| vecs := make([]position.WeightedVector, len(faces)) |
| for i, face := range faces { |
| vec := extractFaceVector(img, face) |
| vecs[i] = position.NewWeightedVector( |
| |
| |
| vec.Select(dims...), |
| computeFaceWeight(face), |
| ) |
| } |
| return cluster.GroupByDistance(vecs, tolerance) |
| } |
|
|
| func getDominantVector(groups []cluster.Group[position.WeightedVector, float64]) (position.Vector, bool) { |
| if len(groups) == 0 { |
| return position.Vector{}, false |
| } |
| |
| cluster.SortGroupsByWeight(groups) |
| |
| vec := position.WeightedAverageVector(groups[0].Items) |
| return vec, true |
| } |
|
|