feat: optimize yoloface preprocess

This commit is contained in:
dev6699
2025-07-17 16:40:41 +08:00
parent 2697b5592d
commit 0ba849fe70
2 changed files with 36 additions and 42 deletions

View File

@@ -1,37 +1,23 @@
package model
import (
"bytes"
"encoding/binary"
"errors"
"image"
"image/color"
"io"
"math"
"unsafe"
"gocv.io/x/gocv"
)
func BytesToFloat32Slice(data []byte) ([]float32, error) {
t := []float32{}
// Create a buffer from the input data
buffer := bytes.NewReader(data)
for {
// Read the binary data from the buffer
var binaryValue uint32
err := binary.Read(buffer, binary.LittleEndian, &binaryValue)
if err != nil {
if err == io.EOF {
break
}
return nil, err
}
t = append(t, math.Float32frombits(binaryValue))
if len(data)%4 != 0 {
return nil, errors.New("byte slice length must be divisible by 4")
}
return t, nil
floatCount := len(data) / 4
floatSlice := unsafe.Slice((*float32)(unsafe.Pointer(&data[0])), floatCount)
return floatSlice, nil
}
// Argmax return the index of the maximum value in a slice
@@ -151,17 +137,20 @@ func MatSubtract(mat gocv.Mat, v float64) {
// ClipMat clips the values of a gocv.Mat within a specified range.
// mat need to be float32 type
func ClipMat(mat gocv.Mat, minVal, maxVal float32) {
for row := 0; row < mat.Rows(); row++ {
for col := 0; col < mat.Cols(); col++ {
value := mat.GetFloatAt(row, col)
if value < minVal {
value = minVal
} else if value > maxVal {
value = maxVal
}
mat.SetFloatAt(row, col, value)
}
}
scalarMin := gocv.NewMatWithSizeFromScalar(
gocv.NewScalar(float64(minVal), 0, 0, 0),
mat.Rows(), mat.Cols(), mat.Type(),
)
defer scalarMin.Close()
scalarMax := gocv.NewMatWithSizeFromScalar(
gocv.NewScalar(float64(maxVal), 0, 0, 0),
mat.Rows(), mat.Cols(), mat.Type(),
)
defer scalarMax.Close()
gocv.Max(mat, scalarMin, &mat)
gocv.Min(mat, scalarMax, &mat)
}
// Padding represents the padding values for the mask.

View File

@@ -64,17 +64,22 @@ func prepareDetectFrame(visionFrame gocv.Mat, faceDetectorSize Resolution) []flo
defer roi.Close()
visionFrame.CopyTo(&roi)
output := make([]float32, 3*faceDetectorHeight*faceDetectorWidth)
idx := 0
for y := 0; y < faceDetectorHeight; y++ {
for x := 0; x < faceDetectorWidth; x++ {
pixel := detectVisionFrame.GetVecbAt(y, x)
data, err := detectVisionFrame.DataPtrUint8()
if err != nil {
panic(err)
}
output[idx] = (float32(pixel[0]) - 127.5) / 128.0
output[faceDetectorHeight*faceDetectorWidth+idx] = (float32(pixel[1]) - 127.5) / 128.0
output[2*faceDetectorHeight*faceDetectorWidth+idx] = (float32(pixel[2]) - 127.5) / 128.0
idx++
}
output := make([]float32, 3*faceDetectorHeight*faceDetectorWidth)
hw := faceDetectorHeight * faceDetectorWidth
for i := 0; i < hw; i++ {
b := data[i*3]
g := data[i*3+1]
r := data[i*3+2]
output[i] = (float32(b) - 127.5) / 128.0
output[hw+i] = (float32(g) - 127.5) / 128.0
output[2*hw+i] = (float32(r) - 127.5) / 128.0
}
return output