1
我仍然試圖圍繞着Go語言,我剛剛遇到一些相當混亂的行爲。這裏是我的代碼工作版本:爲什麼我的程序在我將`opencv.NewWindow()`移動到子功能時立即終止?
注意,你會如果你要執行這些例子需要(在Ubuntu的軟件包libopencv-dev
)到安裝OpenCV和走向的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
同步。- OpenCV窗口實例綁定到
DisplayFrames
'調用堆棧的生命週期,該調用堆棧又與frames
生成器未關閉有關。
那麼給了什麼?我在想什麼,在這裏?
似乎'WaitKey'不能按預期工作,否則程序不應該立即關閉,無論發生什麼事情。 (也許只有在窗口已經打開的情況下才會等待)?goroutine啓動工作的方式,當調用WaitKey時'DisplayFrames'可能還沒有開始運行。)您可以使用'select {}'來設置'main() '直到^ C或其他一些goroutine做'os.Exit'。 – twotwotwo