Open3

GoCVを使ってみる

PotewoPotewo

環境

パソコン

  • Ryzen5 2600
  • メインメモリ16GB
  • Ubuntu 20.04

カメラ

  • Logicool C920n

目的

最終的にはグリーンバックを使わずに人の背景を切り抜ける仮想カメラをGo言語で作りたい。
背景を事前に撮影しておき、差分をとることで背景を消したい。
できればマルチプラットフォームに対応したい。

このスクラップについて

基本的に自分用のメモです。
Go初心者のため、より良い書き方やより良いやり方などがありましたら是非コメント等で教えていただけると嬉しいです。

PotewoPotewo

main.go

package main

import (
	"gocv.io/x/gocv"
)

func main() {
	webcam, _ := gocv.OpenVideoCapture(0)
	webcam.Set(gocv.VideoCaptureFPS, 30)
	defer webcam.Close()
	window := gocv.NewWindow("Test")
	defer window.Close()
	img := gocv.NewMat()
	defer img.Close()

	for {
		webcam.Read(&img)
		window.IMShow(img)
		window.WaitKey(1)
	}
}

ウェブカメラから画像を取得し、ウィンドウに表示するプログラム。
以下のような警告がでた。

[ WARN:0] global /tmp/opencv/opencv-4.5.2/modules/videoio/src/cap_gstreamer.cpp (1081) open OpenCV | GStreamer warning: Cannot query video position: status=0, value=-1, duration=-1

ただ今のところ問題になっていないので無視する。

フレームレート

webcam.Set(gocv.VideoCaptureFPS, 30)を入れないとフレームレートがとても低くなり、画面がぐにゃぐにゃする。

PotewoPotewo
package main

import (
	"gocv.io/x/gocv"
	"image"
)

func main() {
	webcam, _ := gocv.OpenVideoCapture(0)
	webcam.Set(gocv.VideoCaptureFPS, 30)
	defer webcam.Close()
	window := gocv.NewWindow("Test")
	threshTrackbar := window.CreateTrackbar("thresh", 255)
	defer window.Close()
	output := gocv.NewMat()
	defer output.Close()
	current := gocv.NewMat()
	defer current.Close()
	diff := gocv.NewMat()
	defer diff.Close()

	kernel := gocv.GetStructuringElement(gocv.MorphRect, image.Pt(5, 5))
	dkernel := gocv.GetStructuringElement(gocv.MorphRect, image.Pt(20, 20))

	bg := gocv.NewMat()
	for i := 0; i < 10; i++ {
		defer bg.Close()
		webcam.Read(&bg)
		window2 := gocv.NewWindow("bg")
		window2.IMShow(bg)
		window2.WaitKey(1)
	}

	for {
		webcam.Read(&current)
		gocv.AbsDiff(current, bg, &output)
		gocv.CvtColor(output, &output, gocv.ColorBGRToGray)
		gocv.Threshold(output, &output, float32(threshTrackbar.GetPos()), 255, gocv.ThresholdBinary)
		gocv.Erode(output, &output, kernel)
		gocv.Dilate(output, &output, kernel)
		gocv.MorphologyEx(output, &output, gocv.MorphGradient, dkernel)
		window.IMShow(output)
		window.WaitKey(1)
	}
}

今のところマスクを作るのはなんとかできそう。
スライダーを表示して閾値を調整できるようにしてる。
背景と最新のカメラの画像の差の絶対値をとり、収縮したあと膨張させてノイズを取り除き、膨張させてから収縮させることで体の部分のみを塗りつぶす。
ノイズはそこそこ取り除けているものの塗りつぶしは塗りつぶしきれておらず、改良が必要。