2014-05-09 39 views
1

我仍然試圖圍繞着Go語言,我剛剛遇到一些相當混亂的行爲。這裏是我的代碼工作版本:爲什麼我的程序在我將`opencv.NewWindow()`移動到子功能時立即終止?

注意,你會如果你要執行這些例子需要(在Ubuntu的軟件包libopencv-dev)到安裝OpenCV和走向的OpenCVgo 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生成器未關閉有關。

那麼給了什麼?我在想什麼,在這裏?

+0

似乎'WaitKey'不能按預期工作,否則程序不應該立即關閉,無論發生什麼事情。 (也許只有在窗口已經打開的情況下才會等待)?goroutine啓動工作的方式,當調用WaitKey時'DisplayFrames'可能還沒有開始運行。)您可以使用'select {}'來設置'main() '直到^ C或其他一些goroutine做'os.Exit'。 – twotwotwo

回答

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.WaitKey()將只阻塞如果opencv.NewWindow()被調用。正如您在goroutine中調用它,您需要添加同步以確保它已完成。

相關問題