は 輝度(Y)と色差信号 (CbCr)で表現 type YCbCr struct { Y, Cb, Cr []uint8 YStride int CStride int SubsampleRatio YCbCrSubsampleRatio Rect Rectangle } Go Conference 2023 12
image.NewRGBA(b) for y := b.Min.Y; y < b.Max.Y; y += 1 { for x := b.Min.X; x < b.Max.X; x += 1 { c := color.RGBAModel.Convert(src.At(x, y)) dst.Set(x, y, c) } } } func RGBAToYCbCr(src *image.RGBA) *image.YCbCr { b := src.Bounds() dst := image.NewYCbCr(b, image.YCbCrSubsampleRatio420) for y := b.Min.Y; y < b.Max.Y; y += 1 { for x := b.Min.X; x < b.Max.X; x += 1 { c := src.RGBAAt(x, y) cy, cu, cv := color.RGBToYCbCr(c.R, c.G, c.B) dst.Y[dst.YOffset(x, y)] = cy dst.Cb[dst.COffset(x, y)] = cu dst.Cr[dst.COffset(x, y)] = cv } } } 14
Σ は for | は abs() に置き換えるイメージ) func SAD(dx, dy int) float64 { sum := 0.0 for x := 0; x < w; x += 1 { for y := 0; y < h; y += 1 { // 1px ずつ比較していって差分を蓄積 sum += Abs( Image(dx + x, dy + y) - Template(x, y) ) } } return sum } Go Conference 2023 19
w, h := t.Rect.Dx(), t.Rect.Dy() sum := 0.0 for x := 0; x < w; x += 1 { for y := 0; y < h; y += 1 { // grayscale 済みなので R を使う a := float64(s.RGBAAt(dx + x, dy + y).R) b := float64(t.RGBAAt(x, y).R) sum += math.Abs(a - b) } } return sum } func Detect(src *image.RGBA, tpl *image.RGBA) { var pt []image.Point for x := 0; x < w; x += 1 { for y := 0; y < h; y += 1 { if SAD(src, tpl, x, y) < 10 { pt = append(pt, image.Pt(x, y)) } } } } Go Conference 2023 20
return threshold < graycolor.R } func Binary(gray *image.RGBA) [][]uint64 { b := gray.Bounds() w, h := b.Dx(), b.Dy() dst := make([][]uint64, h) for y := 0; y < h; y += 1 { wc := (width - c) / 64 dst[y] = make([]uint64, w) for x := 0; x < wc; x += 1 { b := uint64(0) for i := 0; i < 64; i += 1 { if IsEdge(gray.RGBAAt(x, y)) { b |= 1 << (64 - i) } } dst[y][x] = b } } return dst } Go Conference 2023 22
を使うこと でビットが立っている数を出すこ とができる import "math/bits" func HammingDistance(a, b []uint64) int { sum := 0 for i := 0; i < cap(a); i += 1 { sum += bits.OnesCount64(a[i] ^ b[i]) } return sum } Go Conference 2023 23
検出のための前処理(エッジ処理) 1.28 ms 4. 検出するロジック 38 ms 5. ぼかし処理 520 ms 無駄な処理が多いのはあるが、これではリアルタイムに処理はできない。 このスライドだけでも for が何回出てきたか分からないくらいループしている 不要な処理を可能な限り削る必要がある Go Conference 2023 28
C側では uchar* C では uchar* で返すが、値は float32 例えば Cでは、こんな感じの定義 int PCM16Decibel(unsigned char* in, int size, unsigned char* out); in と out が []byte で受け取るような実装があった際に 都度変換するの大変 Go Conference 2023 55