我仍然试图围绕Go语言,我只是遇到了一些相当混乱的行为。这是我的代码的工作版本:
注意,您需要在Ubuntu中安装OpenCV (包libopencv-dev
)和go-opencv (go get github.com/lazywei/go-opencv/opencv
)你想要执行这些例子。
工作:
package main
import (
"fmt"
"github.com/lazywei/go-opencv/opencv"
)
func main() {
win := opencv.NewWindow("Go-OpenCV Webcam")
defer win.Destroy()
frames := GetFrameGenerator()
go DisplayFrames(win, frames)
opencv.WaitKey(0)
}
func GetFrameGenerator() chan *opencv.IplImage {
frames := make(chan *opencv.IplImage)
cap := opencv.NewCameraCapture(0)
if cap == nil {
panic("cannot open camera")
}
go func() {
defer cap.Release()
for {
if cap.GrabFrame() {
img := cap.RetrieveFrame(1)
if img != nil {
frames <- img
} else {
fmt.Println("Image ins nil")
}
}
}
}()
return frames
}
func DisplayFrames(win *opencv.Window, frames <-chan *opencv.IplImage) {
for fr := range frames {
win.ShowImage(fr)
}
}
不工作:
package main
import (
"fmt"
"github.com/lazywei/go-opencv/opencv"
)
func main() {
frames := GetFrameGenerator()
go DisplayFrames(frames)
opencv.WaitKey(0)
}
func GetFrameGenerator() chan *opencv.IplImage {
frames := make(chan *opencv.IplImage)
cap := opencv.NewCameraCapture(0)
if cap == nil {
panic("cannot open camera")
}
go func() {
defer cap.Release()
for {
if cap.GrabFrame() {
img := cap.RetrieveFrame(1)
if img != nil {
frames <- img
} else {
fmt.Println("Image ins nil")
}
}
}
}()
return frames
}
func DisplayFrames(frames <-chan *opencv.IplImage) {
win := opencv.NewWindow("Go-OpenCV Webcam")
defer win.Destroy()
for fr := range frames {
win.ShowImage(fr)
}
}
直观地说,似乎程序应该运行,直到它被强行停止,因为
opencv.WaitKey(0)
的调用应该只是坐在那里等待某种按键GetFrameGenerator
中的匿名goroutine应该继续消失,与每个帧上的DisplayFrames
同步。DisplayFrames
&#39;的生命周期相关联。调用堆栈,它又与frames
生成器未绑定绑定。那是什么给出的?我在这里错过了什么?
答案 0 :(得分:3)
我没有安装opencv所以我无法测试,但这样的事情应该可以解决问题:
package main
import (
"fmt"
"github.com/lazywei/go-opencv/opencv"
)
func main() {
frames := GetFrameGenerator()
ready := make(chan struct{})
defer close(ready)
go DisplayFrames(frames, ready)
<-ready
opencv.WaitKey(0)
}
func GetFrameGenerator() chan *opencv.IplImage {
frames := make(chan *opencv.IplImage)
cap := opencv.NewCameraCapture(0)
if cap == nil {
panic("cannot open camera")
}
go func() {
defer cap.Release()
for {
if cap.GrabFrame() {
img := cap.RetrieveFrame(1)
if img != nil {
frames <- img
} else {
fmt.Println("Image ins nil")
}
}
}
}()
return frames
}
func DisplayFrames(frames <-chan *opencv.IplImage, ready <-chan struct{}) {
win := opencv.NewWindow("Go-OpenCV Webcam")
defer win.Destroy()
ready <- struct{}{}
for fr := range frames {
win.ShowImage(fr)
}
}
只有在调用opencv.NewWindow()时,opencv.WaitKey()才会阻止。正如您在goroutine中调用它一样,您需要添加同步以确保它已完成。