ssa

Форк
0
/
RGB.go 
237 строк · 5.6 Кб
1
package tg
2

3
import (
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"
16
	pigo "github.com/esimov/pigo/core"
17
)
18

19
type Frame struct {
20
	FileName string
21
	Dets     []pigo.Detection
22
}
23

24
func ExtractRGB(Path, FileName string) (RGBs []RGB_float64, Err error) {
25

26
	MakeDir(Path + "in/")
27
	c := exec.Command(
28
		// ffmpeg -an -y -threads 0 -i in.mp4 -vf "select=not(mod(n\,1))" -vsync vfr in/%4d.png
29
		"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"
32
	c.Stderr = os.Stderr
33
	c.Run()
34
	entries, err := os.ReadDir(Path + "in/")
35
	if err != nil {
36
		log.Fatal(err)
37
	}
38
	p := NewPigs()
39
	Bar := pb.StartNew(len(entries))
40
	fileRGB, ErrOpenFile := os.OpenFile(Path+"RGB.txt",
41
		os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
42
	if ErrOpenFile != nil {
43
		log.Println(ErrOpenFile)
44
	}
45
	defer fileRGB.Close()
46
	// rez := ""
47
	RGBs = make([]RGB_float64, len(entries))
48
	for ientries := range entries {
49
		FilePathIn := Path + "in/" + entries[ientries].Name()
50
		Dets := p.getCoords(FilePathIn)
51
		sort.Slice(Dets, func(i, j int) bool { // Сортировка по вероятности
52
			return Dets[i].Q > Dets[j].Q
53
		})
54

55
		var R, G, B uint32
56
		var sizes uint32
57
		if len(Dets) > 0 {
58
			src, err := getImageFromFilePath(FilePathIn)
59
			if err != nil {
60
				panic(err.Error())
61
			}
62
			pix := Dets[0].Scale / 2
63
			yStart, yEnd := Dets[0].Row-pix, Dets[0].Row+pix
64
			xStart, xEnd := Dets[0].Col-pix, Dets[0].Col+pix
65

66
			for y := yStart; y < yEnd; y++ {
67
				for x := xStart; x < xEnd; x++ {
68
					rgb := src.At(x, y)
69
					r, g, b, _ := rgb.RGBA()
70
					_, cb, cr := color.RGBToYCbCr(uint8(r>>8), uint8(g>>8), uint8(b>>8))
71
					hsv := 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))))
73
					if cb >= 98 && cb <= 142 &&
74
						cr >= 135 && cr <= 177 &&
75
						hsv.H >= 0.01 && hsv.H <= 0.1 {
76
						// rgbImage2.Set(x, y, color.RGBA{R: 255, G: 255, B: 255, A: 255})
77
						R += (r >> 8)
78
						G += (g >> 8)
79
						B += (b >> 8)
80
						// fmt.Println(r>>8, g>>8, b>>8)
81
					}
82
				}
83
			}
84
			sizes = uint32((yEnd - yStart) * (xEnd - xStart))
85
		}
86
		RGBs[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

90
		if _, err := fileRGB.WriteString(fmt.Sprintf("%.8f;%.8f;%.8f\n", RGBs[ientries].R, RGBs[ientries].G, RGBs[ientries].B)); err != nil {
91
			log.Println(err)
92
		}
93

94
		Bar.Increment()
95
		//break
96
	}
97
	Bar.Finish()
98

99
	return RGBs, nil
100
}
101

102
/////////////////////////////
103

104
type Pigs struct {
105
	Classifier *pigo.Pigo
106
}
107

108
func NewPigs() *Pigs {
109
	// consumers.StartForwardStreamConsumer()
110
	// camtron.StartCam()
111
	cascadeFile, err := os.ReadFile("cascade/facefinder")
112
	if err != nil {
113
		log.Fatalf("Error reading the cascade file: %v", err)
114
	}
115

116
	pigo := 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.
119
	classifier, err := pigo.Unpack(cascadeFile)
120
	if err != nil {
121
		log.Fatalf("Error reading the cascade file: %s", err)
122
	}
123

124
	return &Pigs{
125
		Classifier: classifier,
126
	}
127
}
128

129
func (p Pigs) getCoords(filepath string) []pigo.Detection {
130

131
	src, err := pigo.GetImage(filepath)
132
	if err != nil {
133
		log.Fatalf("Cannot open the image file: %v", err)
134
	}
135

136
	pixels := pigo.RgbToGrayscale(src)
137
	cols, rows := src.Bounds().Max.X, src.Bounds().Max.Y
138

139
	cParams := pigo.CascadeParams{
140
		MinSize:     20,
141
		MaxSize:     1000,
142
		ShiftFactor: 0.1,
143
		ScaleFactor: 1.1,
144

145
		ImageParams: pigo.ImageParams{
146
			Pixels: pixels,
147
			Rows:   rows,
148
			Cols:   cols,
149
			Dim:    cols,
150
		},
151
	}
152

153
	angle := 0.0 // cascade rotation angle. 0.0 is 0 radians and 1.0 is 2*pi radians
154

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.
157
	dets := p.Classifier.RunCascade(cParams, angle)
158
	// fmt.Printf("%+v\n", dets)
159

160
	// Calculate the intersection over union (IoU) of two clusters.
161
	dets = p.Classifier.ClusterDetections(dets, 0.1)
162

163
	// fmt.Printf("%+v\n", dets)
164
	// fmt.Println()
165

166
	return dets
167
}
168

169
///////////////////////////
170

171
func getImageFromFilePath(filePath string) (draw.Image, error) {
172

173
	// read file
174
	f, err := os.Open(filePath)
175
	if err != nil {
176
		return nil, err
177
	}
178
	defer f.Close()
179

180
	// convert as image.Image
181
	orig, _, err := image.Decode(f)
182

183
	// convert as usable image
184
	b := orig.Bounds()
185
	img := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
186
	draw.Draw(img, img.Bounds(), orig, b.Min, draw.Src)
187

188
	return img, err
189
}
190

191
//////////////////////////////
192

193
type RGB struct {
194
	R uint8 // Red
195
	G uint8 // Green
196
	B uint8 // Blue
197
}
198
type RGB_float64 struct {
199
	R float64 // Red
200
	G float64 // Green
201
	B float64 // Blue
202
}
203
type HSV struct {
204
	H float64 // Hue
205
	S float64 // Saturation
206
	V float64 // Lightness
207
}
208

209
// RGB2HSV converts RGB color to HSV (HSB)
210
func RGB2HSV(c RGB) HSV {
211
	R, G, B := float64(c.R)/255.0, float64(c.G)/255.0, float64(c.B)/255.0
212
	max := math.Max(math.Max(R, G), B)
213
	min := math.Min(math.Min(R, G), B)
214
	h, s, v := 0.0, 0.0, max
215
	if max != min {
216
		d := max - min
217
		s = d / max
218
		h = calcHUE(max, R, G, B, d)
219
	}
220
	return HSV{h, s, v}
221
}
222
func calcHUE(max, r, g, b, d float64) float64 {
223
	var h float64
224
	switch max {
225
	case r:
226
		if g < b {
227
			h = (g-b)/d + 6.0
228
		} else {
229
			h = (g - b) / d
230
		}
231
	case g:
232
		h = (b-r)/d + 2.0
233
	case b:
234
		h = (r-g)/d + 4.0
235
	}
236
	return h / 6
237
}
238

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.