OpenCvSharpを使用して、画像から顔を検出してみる。
顔があったらその周りを赤色の四角い枠で囲む。
顔検出には数千枚の画像ファイルから機械学習を行って、人間の顔とは?ってのを修めたデータが必要らしい…
でも、それをやるには時間がかかりすぎるので、Sampleに入っている学習済みのデータ「haarcascade_frontalface_alt.xml」を使用させてもらう。
利用させてもらっておいてどうかとは思うが、試したデータでは今一だった。
どうも余計なものまで顔と認識して検出してくる。もちろん、顔も検出してくれるからいいんだけどね。
いつものDLLと「haarcascade_frontalface_alt.xml」を同じフォルダーにコピーして、検出した元画像を「foo.jpg」として下のコードを実行する。
- [void][System.Reflection.Assembly]::LoadFrom((Join-Path $pwd OpenCvSharp.dll))
- # 元データ
- $iplImage = [OpenCvSharp.Cv]::LoadImage((Join-Path $pwd "foo.jpg"))
- $color = [OpenCvSharp.CvColor]::Red
- $scale = 1.04;
- $scaleFactor = 1.139;
- $minNeighbors = 2;
- $srcWidth = $iplImage.Width
- $srcHeight = $iplImage.Height
- $srcSize = New-Object OpenCvSharp.CvSize([int]$srcWidth, [int]$srcHeight)
- $srcIplImage = New-Object OpenCvSharp.IplImage( $srcSize, [OpenCvSharp.BitDepth]::U8, 1)
- $dstWidth = $iplImage.Width / $scale
- $dstHeight = $iplImage.Height / $scale
- $dstSize = New-Object OpenCvSharp.CvSize([int]$dstWidth, [int]$dstHeight)
- $dst1IplImage = New-Object OpenCvSharp.IplImage( $dstSize, [OpenCvSharp.BitDepth]::U8, 1)
- # 顔検出用の画像の生成
- [OpenCvSharp.Cv]::CvtColor($iplImage,$srcIplImage, [OpenCvSharp.ColorConversion]::BgraToGray)
- [OpenCvSharp.Cv]::Resize($srcIplImage, $dst1IplImage, [OpenCvSharp.Interpolation]::Linear)
- [OpenCvSharp.Cv]::EqualizeHist($dst1IplImage,$dst1IplImage)
- $cascade = [OpenCvSharp.CvHaarClassifierCascade]::FromFile((Join-Path $pwd "haarcascade_frontalface_alt.xml"))
- $storage = New-Object OpenCvSharp.CvMemStorage
- $storage.Clear()
- # 顔の検出
- $faces = [OpenCvSharp.Cv]::HaarDetectObjects($dst1IplImage, $cascade, $storage, $scaleFactor, $minNeighbors, 0, (New-Object OpenCvSharp.CvSize(30, 30)));
- # 検出された全ての顔位置に四角い枠で囲む
- for ($i = 0; $i -lt $faces.Total; $i++) {
- $r = $faces[$i].Rect
- $pt1 = New-Object OpenCvSharp.CvPoint($r.x, $r.y)
- $pt2 = new-object OpenCvSharp.CvPoint(($r.x + $r.Width),($r.y + $r.Height ))
- $iplImage.Rectangle($pt1, $pt2, $color, 3, 8, 0)
- }
- # 丸で囲いたい場合はこっち
- #for ($i = 0; $i -lt $faces.Total; $i++) {
- # $r = $faces[$i].Rect
- # $X = [OpenCvSharp.Cv]::Round(($r.X + $r.Width * 0.5) * $Scale)
- # $Y = [OpenCvSharp.Cv]::Round(($r.Y + $r.Height * 0.5) * $Scale)
- # $center = New-Object OpenCvSharp.CvPoint($X, $Y)
- # $radius = [OpenCvSharp.Cv]::Round(($r.Width + $r.Height) * 0.25 * $Scale)
- # $iplImage.Circle($center, $radius, $color, 3, [OpenCvSharp.LineType]::AntiAlias, 0)
- #}
- # 赤枠で囲ったデータを保存する
- $iplImage.SaveImage((Join-Path $pwd "bar.jpg"))
- $iplImage.Dispose()
- $srcIplImage.Dispose()
- $dst1IplImage.Dispose()
0 コメント:
コメントを投稿