OpenCV 是一个用于计算机视觉处理的代码库,面世已有 20 多年了。大学时期,我曾在个人的 C++ 和 Python 项目中使用过它,因为这些编程语言对它有很好的支持。不过随着我开始学习并使用 Go 语言,我开始好奇 Go 语言能否使用 OpenCV 。网上有一些关于如何使用 Go 语言调用 OpenCV 的例子和教程,但我发现它们都太过黑科技和复杂了。还好我发现了一个名为 hybridgroup 小组的伙计们写的封装库,它很容易使用,而且文档也很全。这里我要向你们展示如何使用 gocv,并且创建一个简单的 Haar Cascades 面部探测器。

准备工作

  • Go
  • OpenCV (下文附有安装链接)
  • 一个网络摄像头

安装地址

实例一

在第一个例子中,让我们尝试打开一个窗口,并显示从你的摄像头获取到的视频流。

首先引入我们需要的库。

import (
   “log”
   “gocv.io/x/gocv”
)

然后使用 VideoCaptureDevice 方法创建一个 VideoCapture 对象。VideoCaptureDevice 方法能让你从摄像头中获取一个视频流。该方法需要一个表示设备 ID 的整型参数。

webcam, err := gocv.VideoCaptureDevice(0)
if err != nil {
    log.Fatalf(“error opening web cam: %v”, err)
}
defer webcam.Close()

我们需要创建一个窗口来展示视频流。可以使用 NewWindow 方法完成这个任务。

window := gocv.NewWindow(“webcamwindow”)
defer window.Close()

现在到了有趣的时候。

由于视频是一个持续不断的图像流,我们将不得不使用一个无限循环持续不断地从摄像头读取数据。为此我们将使用 VideoCapture 类型的 Read 方法。它需要一个 Mat 类型 (我们在上文创建的矩阵)入参,同时返回一个布尔值表示 VideoCapture 是否成功读取到了帧数据。

for {
     if ok := webcam.Read(&img); !ok || img.Empty() {
        log.Println(“Unable to read from the webcam”)
        continue
     }
.
.
.
}

最后我们把图像帧显示在创建的窗口中,等待 50ms 后再处理下一帧。

window.IMShow(img)
window.WaitKey(50)

当运行程序时,我们可以看到一个窗口会弹出,里面显示着你的摄像头中的视频流。

package main

import (
	"log"

	"gocv.io/x/gocv"
)

func main() {
	webcam, err := gocv.VideoCaptureDevice(0)
	if err != nil {
    log.Fatalf("error opening device: %v", err)
	}
	defer webcam.Close()

	img := gocv.NewMat()
	defer img.Close()

	window := gocv.NewWindow("webcamwindow")
	defer window.Close()

	for {
		if ok := webcam.Read(&img); !ok || img.Empty() {
			log.Println("Unable to read from the webcam")
			continue
		}

		window.IMShow(img)
		window.WaitKey(50)
	}
}

实例二

此例中,我们将在上一个例子的基础上使用 Haar Cascades 进行人脸侦测。

不过首先。。什么是 Haar Cascades ?

你可以从 opencv 的代码库中下载预先训练好的 Haar-Cascades 。此例中我们将使用 Haar-Cascade 帮助我们识别人的面部。

首先我们创建一个分类器并且将预先训练好的 Haar-Cascade 文件给到它。这个例子中我已经下载了 opencv_haarcascade_frontalface_default.xml 文件放到了我们的程序所在的目录。