129 lines
2.1 KiB
Go
129 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"git.giftfish.de/ston1th/webcam"
|
|
"image"
|
|
"image/color"
|
|
"image/jpeg"
|
|
"os"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const min = 3300
|
|
|
|
// noise
|
|
//const min = 3000
|
|
// minimum
|
|
//const min = 2570
|
|
|
|
var frame []byte
|
|
var img image.Image
|
|
|
|
func main() {
|
|
cam, err := webcam.Open("/dev/video0", time.Second*5)
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
defer cam.Close()
|
|
|
|
formats := cam.GetPixelFormats()
|
|
println("Available formats: ")
|
|
for k, value := range formats {
|
|
fmt.Fprintln(os.Stderr, k, value)
|
|
}
|
|
|
|
format := uint32(1196444237) // MJPEG
|
|
|
|
fmt.Fprintf(os.Stderr, "Supported frame sizes for format %s\n", formats[format])
|
|
fs := cam.GetFrameSizes(format)
|
|
|
|
for _, f := range fs {
|
|
fmt.Fprintln(os.Stderr, f)
|
|
}
|
|
//s := fs[6]
|
|
s := fs[2]
|
|
f, w, h, err := cam.SetImageFormat(format, s.MaxWidth, s.MaxHeight)
|
|
|
|
if err != nil {
|
|
panic(err.Error())
|
|
} else {
|
|
fmt.Fprintf(os.Stderr, "Resulting image format: %s (%dx%d)\n", formats[f], w, h)
|
|
}
|
|
|
|
fmt.Fprintf(os.Stderr, "Press Enter to start streaming\n")
|
|
fmt.Scanf("\n")
|
|
err = cam.StartStreaming()
|
|
if err != nil {
|
|
panic(err.Error())
|
|
}
|
|
|
|
for {
|
|
err = cam.WaitForFrame()
|
|
switch err.(type) {
|
|
case nil:
|
|
case webcam.TimeoutErr:
|
|
continue
|
|
default:
|
|
panic(err.Error())
|
|
}
|
|
img, err := cam.ReadJPEG()
|
|
if err == nil {
|
|
mark(img)
|
|
os.Stdout.Sync()
|
|
}
|
|
}
|
|
}
|
|
|
|
func check(c color.Color) bool {
|
|
r, g, b, _ := c.RGBA()
|
|
if r > min {
|
|
return true
|
|
}
|
|
if g > min {
|
|
return true
|
|
}
|
|
if b > min {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func set(img *image.RGBA, x, y int) {
|
|
m := 10
|
|
for i := x - m; i < x+m; i++ {
|
|
img.Set(i, y, color.White)
|
|
}
|
|
for i := y - m; i < y+m; i++ {
|
|
img.Set(x, i, color.White)
|
|
}
|
|
}
|
|
|
|
func mark(img image.Image) {
|
|
o := jpeg.Options{100}
|
|
r := img.Bounds()
|
|
n := image.NewRGBA(r)
|
|
var wg sync.WaitGroup
|
|
threads := 4
|
|
wx := 0
|
|
work := r.Max.X / threads
|
|
wmax := work
|
|
for i := 0; i < threads; i++ {
|
|
wg.Add(1)
|
|
go func(x, max int) {
|
|
for ; x < max; x++ {
|
|
for y := 0; y < r.Max.Y; y++ {
|
|
if check(img.At(x, y)) {
|
|
set(n, x, y)
|
|
}
|
|
}
|
|
}
|
|
wg.Done()
|
|
}(wx, wmax)
|
|
wx += work
|
|
wmax += work
|
|
}
|
|
wg.Wait()
|
|
jpeg.Encode(os.Stdout, n, &o)
|
|
}
|