OpenCVSharpを使用してWebカメラから動画をキャプチャーしながら輪郭検出をしてみる。
静止画と同じではつまらないので、円の中の4点を赤色にして、その4点の座標を緑の字でウィンドウ上に表示させてみる。
静止画と同じではつまらないので、円の中の4点を赤色にして、その4点の座標を緑の字でウィンドウ上に表示させてみる。
- [void][System.Reflection.Assembly]::LoadFrom((Join-Path $pwd OpenCvSharp.dll))
- $camera = [OpenCvSharp.CvCapture]::FromCamera(0)
- $window = New-Object OpenCvSharp.CvWindow("SampleCapture")
- $threshold = 128 # 白色か黒色かのしきい値
- $smooth = 5 # 値が大きいほどぼかしが強い
- $font = New-Object OpenCvSharp.CvFont([OpenCvSharp.FontFace]::HersheyComplex, 0.7, 0.7)
- $point1 = New-Object OpenCvSharp.CvPoint(10,20)
- $point25 = New-Object OpenCvSharp.CvPoint(10,45)
- $point50 = New-Object OpenCvSharp.CvPoint(10,70)
- $point75 = New-Object OpenCvSharp.CvPoint(10,95)
- $colorString = [OpenCvSharp.CvColor]::Green
- $colorPoint = [OpenCvSharp.CvColor]::Red
- $colorLine = [OpenCvSharp.CvColor]::Blue
- $size = New-Object OpenCvSharp.CvSize(15, 15)
- # この値が大きいほど輪郭が狭まる
- $tremCriteria = New-Object OpenCvSharp.CvTermCriteria(300)
- $alpha = [System.Single]0.45
- $beta = [System.Single]0.35
- $gamma = [System.Single]0.2
- $srcSize = New-Object OpenCvSharp.CvSize($camera.FrameWidth, $camera.FrameHeight)
- $srcIplImage = New-Object OpenCvSharp.IplImage( $srcSize, [OpenCvSharp.BitDepth]::U8, 1)
- $dstIplImage = New-Object OpenCvSharp.IplImage( $srcSize, [OpenCvSharp.BitDepth]::U8, 1)
- # ポイントを配列で初期化 全部ゼロで初期化される
- [OpenCvSharp.CvPoint[]]$contour = New-Object OpenCvSharp.CvPoint[](100)
- # ウィンドウの中心点を取得
- $center = New-Object OpenCvSharp.CvPoint(($srcSize.Width / 2), ($srcSize.Height / 2))
- while ( [OpenCvSharp.CvWindow]::WaitKey(10) -lt 0 ) {
- $iplImage = $camera.QueryFrame()
- # 中心点を元にポイントの初期値を設定
- for ($i = 0; $i -lt $contour.Length; $i++) {
- $x = [int]($center.X * [System.Math]::Cos(2 * [System.Math]::PI * $i / $contour.Length) + $center.X)
- $y = [int]($center.Y * [System.Math]::Sin(2 * [System.Math]::PI * $i / $contour.Length) + $center.Y)
- $p = New-Object OpenCvSharp.CvPoint($x, $y)
- $contour.Set($i, $p)
- }
- # グレースケールに変換
- [OpenCvSharp.Cv]::CvtColor($iplImage, $srcIplImage, [OpenCvSharp.ColorConversion]::BgraToGray)
- # ぼかす
- $srcIplImage.Smooth($srcIplImage, [OpenCvSharp.SmoothType]::Blur, $smooth)
- # 二値化
- $srcIplImage.Threshold($dstIplImage, $threshold, 255, [OpenCvSharp.ThresholdType]::Binary)
- # 領域検知
- $dstIplImage.SnakeImage($contour, $alpha, $beta, $gamma, $size, $tremCriteria, $true)
- # 領域中の4点の座標を取得
- $str1 = [String]::Format("1 : (x = {0}, y = {1})", $contour.Get(1).X, $contour.Get(1).Y)
- $str25 = [String]::Format("25 : (x = {0}, y = {1})", $contour.Get(25).X, $contour.Get(25).Y)
- $str50 = [String]::Format("50 : (x = {0}, y = {1})", $contour.Get(50).X, $contour.Get(50).Y)
- $str75 = [String]::Format("75 : (x = {0}, y = {1})", $contour.Get(75).X, $contour.Get(75).Y)
- # ポイントを線で結んで描写
- for ($i = 0; $i -lt ($contour.Length - 1); $i++) {
- # 選んだ4点だけ 赤 それ以外は 青
- if ($i -eq 1 -or $i -eq 25 -or $i -eq 50 -or $i -eq 75) {
- $iplImage.Line($contour[$i], $contour[($i + 1)], $colorPoint, 6)
- } else {
- $iplImage.Line($contour[$i], $contour[($i + 1)], $colorLine, 3)
- }
- }
- # 最初の点と最後の点を結ぶ
- $iplImage.Line($contour[($contour.Length -1)], $contour[0], $colorLine, 3)
- # 座標をウィンドウに描写
- $iplImage.PutText($str1, $point1, $font, $colorString)
- $iplImage.PutText($str25, $point25, $font, $colorString)
- $iplImage.PutText($str50, $point50, $font, $colorString)
- $iplImage.PutText($str75, $point75, $font, $colorString)
- $window.Image = $iplImage
- # 連続でループするとCPUをたくさん喰うので3秒間をあける
- Start-Sleep 3
- }
- $iplImage.Dispose()
- $srcIplImage.Dispose()
- $dstIplImage.Dispose()
- $window.Dispose()
- $camera.Dispose()
0 コメント:
コメントを投稿