ssa
1package tg2
3import (4"fmt"5"image"6"image/color"7"image/draw"8_ "image/jpeg"9"log"10"math"11"os"12"os/exec"13"sort"14
15"github.com/cheggaaa/pb"16pigo "github.com/esimov/pigo/core"17)
18
19type Frame struct {20FileName string21Dets []pigo.Detection22}
23
24func ExtractRGB(Path, FileName string) (RGBs []RGB_float64, Err error) {25
26MakeDir(Path + "in/")27c := exec.Command(28// ffmpeg -an -y -threads 0 -i in.mp4 -vf "select=not(mod(n\,1))" -vsync vfr in/%4d.png29"ffmpeg", "-an", "-y", "-threads", "0", "-i", Path+FileName, "-vf", `select=not(mod(n\,1))`, "-vsync", "vfr", Path+"in/%4d.png",30//"ffmpeg", "-i", Path+FileName, "-r", "15", Path+"in/%4d.png",31) // "P1LC1-edited2.mp4" "P1LC1-edited.avi" "face.mp4"32c.Stderr = os.Stderr33c.Run()34entries, err := os.ReadDir(Path + "in/")35if err != nil {36log.Fatal(err)37}38p := NewPigs()39Bar := pb.StartNew(len(entries))40fileRGB, ErrOpenFile := os.OpenFile(Path+"RGB.txt",41os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)42if ErrOpenFile != nil {43log.Println(ErrOpenFile)44}45defer fileRGB.Close()46// rez := ""47RGBs = make([]RGB_float64, len(entries))48for ientries := range entries {49FilePathIn := Path + "in/" + entries[ientries].Name()50Dets := p.getCoords(FilePathIn)51sort.Slice(Dets, func(i, j int) bool { // Сортировка по вероятности52return Dets[i].Q > Dets[j].Q53})54
55var R, G, B uint3256var sizes uint3257if len(Dets) > 0 {58src, err := getImageFromFilePath(FilePathIn)59if err != nil {60panic(err.Error())61}62pix := Dets[0].Scale / 263yStart, yEnd := Dets[0].Row-pix, Dets[0].Row+pix64xStart, xEnd := Dets[0].Col-pix, Dets[0].Col+pix65
66for y := yStart; y < yEnd; y++ {67for x := xStart; x < xEnd; x++ {68rgb := src.At(x, y)69r, g, b, _ := rgb.RGBA()70_, cb, cr := color.RGBToYCbCr(uint8(r>>8), uint8(g>>8), uint8(b>>8))71hsv := RGB2HSV(RGB{R: uint8(r), G: uint8(g), B: uint8(b)})72// var hsvS float64 = math.Acos((float64(r-g) + float64(r-b)) / (2 * math.Sqrt(math.Pow(float64(r-g), 2)*float64(r-b)*float64(g-b))))73if cb >= 98 && cb <= 142 &&74cr >= 135 && cr <= 177 &&75hsv.H >= 0.01 && hsv.H <= 0.1 {76// rgbImage2.Set(x, y, color.RGBA{R: 255, G: 255, B: 255, A: 255})77R += (r >> 8)78G += (g >> 8)79B += (b >> 8)80// fmt.Println(r>>8, g>>8, b>>8)81}82}83}84sizes = uint32((yEnd - yStart) * (xEnd - xStart))85}86RGBs[ientries] = RGB_float64{R: float64(R) / float64(sizes), G: float64(G) / float64(sizes), B: float64(B) / float64(sizes)}87
88// fmt.Println(FilePathIn, RGBs[ientries])89
90if _, err := fileRGB.WriteString(fmt.Sprintf("%.8f;%.8f;%.8f\n", RGBs[ientries].R, RGBs[ientries].G, RGBs[ientries].B)); err != nil {91log.Println(err)92}93
94Bar.Increment()95//break96}97Bar.Finish()98
99return RGBs, nil100}
101
102/////////////////////////////
103
104type Pigs struct {105Classifier *pigo.Pigo106}
107
108func NewPigs() *Pigs {109// consumers.StartForwardStreamConsumer()110// camtron.StartCam()111cascadeFile, err := os.ReadFile("cascade/facefinder")112if err != nil {113log.Fatalf("Error reading the cascade file: %v", err)114}115
116pigo := pigo.NewPigo()117// Unpack the binary file. This will return the number of cascade trees,118// the tree depth, the threshold and the prediction from tree's leaf nodes.119classifier, err := pigo.Unpack(cascadeFile)120if err != nil {121log.Fatalf("Error reading the cascade file: %s", err)122}123
124return &Pigs{125Classifier: classifier,126}127}
128
129func (p Pigs) getCoords(filepath string) []pigo.Detection {130
131src, err := pigo.GetImage(filepath)132if err != nil {133log.Fatalf("Cannot open the image file: %v", err)134}135
136pixels := pigo.RgbToGrayscale(src)137cols, rows := src.Bounds().Max.X, src.Bounds().Max.Y138
139cParams := pigo.CascadeParams{140MinSize: 20,141MaxSize: 1000,142ShiftFactor: 0.1,143ScaleFactor: 1.1,144
145ImageParams: pigo.ImageParams{146Pixels: pixels,147Rows: rows,148Cols: cols,149Dim: cols,150},151}152
153angle := 0.0 // cascade rotation angle. 0.0 is 0 radians and 1.0 is 2*pi radians154
155// Run the classifier over the obtained leaf nodes and return the detection results.156// The result contains quadruplets representing the row, column, scale and detection score.157dets := p.Classifier.RunCascade(cParams, angle)158// fmt.Printf("%+v\n", dets)159
160// Calculate the intersection over union (IoU) of two clusters.161dets = p.Classifier.ClusterDetections(dets, 0.1)162
163// fmt.Printf("%+v\n", dets)164// fmt.Println()165
166return dets167}
168
169///////////////////////////
170
171func getImageFromFilePath(filePath string) (draw.Image, error) {172
173// read file174f, err := os.Open(filePath)175if err != nil {176return nil, err177}178defer f.Close()179
180// convert as image.Image181orig, _, err := image.Decode(f)182
183// convert as usable image184b := orig.Bounds()185img := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))186draw.Draw(img, img.Bounds(), orig, b.Min, draw.Src)187
188return img, err189}
190
191//////////////////////////////
192
193type RGB struct {194R uint8 // Red195G uint8 // Green196B uint8 // Blue197}
198type RGB_float64 struct {199R float64 // Red200G float64 // Green201B float64 // Blue202}
203type HSV struct {204H float64 // Hue205S float64 // Saturation206V float64 // Lightness207}
208
209// RGB2HSV converts RGB color to HSV (HSB)
210func RGB2HSV(c RGB) HSV {211R, G, B := float64(c.R)/255.0, float64(c.G)/255.0, float64(c.B)/255.0212max := math.Max(math.Max(R, G), B)213min := math.Min(math.Min(R, G), B)214h, s, v := 0.0, 0.0, max215if max != min {216d := max - min217s = d / max218h = calcHUE(max, R, G, B, d)219}220return HSV{h, s, v}221}
222func calcHUE(max, r, g, b, d float64) float64 {223var h float64224switch max {225case r:226if g < b {227h = (g-b)/d + 6.0228} else {229h = (g - b) / d230}231case g:232h = (b-r)/d + 2.0233case b:234h = (r-g)/d + 4.0235}236return h / 6237}
238