PowerShellで静止画の顔検出をしてみる

| 2009年10月26日月曜日
OpenCvSharpを使用して、画像から顔を検出してみる。
顔があったらその周りを赤色の四角い枠で囲む。

顔検出には数千枚の画像ファイルから機械学習を行って、人間の顔とは?ってのを修めたデータが必要らしい…
でも、それをやるには時間がかかりすぎるので、Sampleに入っている学習済みのデータ「haarcascade_frontalface_alt.xml」を使用させてもらう。

利用させてもらっておいてどうかとは思うが、試したデータでは今一だった。
どうも余計なものまで顔と認識して検出してくる。もちろん、顔も検出してくれるからいいんだけどね。

いつものDLLと「haarcascade_frontalface_alt.xml」を同じフォルダーにコピーして、検出した元画像を「foo.jpg」として下のコードを実行する。
  1. [void][System.Reflection.Assembly]::LoadFrom((Join-Path $pwd OpenCvSharp.dll))
  2. # 元データ
  3. $iplImage = [OpenCvSharp.Cv]::LoadImage((Join-Path $pwd "foo.jpg"))
  4. $color = [OpenCvSharp.CvColor]::Red
  5. $scale = 1.04;
  6. $scaleFactor = 1.139;
  7. $minNeighbors = 2;
  8. $srcWidth = $iplImage.Width
  9. $srcHeight = $iplImage.Height
  10. $srcSize = New-Object OpenCvSharp.CvSize([int]$srcWidth, [int]$srcHeight)
  11. $srcIplImage = New-Object OpenCvSharp.IplImage( $srcSize, [OpenCvSharp.BitDepth]::U8, 1)
  12. $dstWidth = $iplImage.Width / $scale
  13. $dstHeight = $iplImage.Height / $scale
  14. $dstSize = New-Object OpenCvSharp.CvSize([int]$dstWidth, [int]$dstHeight)
  15. $dst1IplImage = New-Object OpenCvSharp.IplImage( $dstSize, [OpenCvSharp.BitDepth]::U8, 1)
  16. # 顔検出用の画像の生成
  17. [OpenCvSharp.Cv]::CvtColor($iplImage,$srcIplImage, [OpenCvSharp.ColorConversion]::BgraToGray)
  18. [OpenCvSharp.Cv]::Resize($srcIplImage, $dst1IplImage, [OpenCvSharp.Interpolation]::Linear)
  19. [OpenCvSharp.Cv]::EqualizeHist($dst1IplImage,$dst1IplImage)
  20. $cascade = [OpenCvSharp.CvHaarClassifierCascade]::FromFile((Join-Path $pwd "haarcascade_frontalface_alt.xml"))
  21. $storage = New-Object OpenCvSharp.CvMemStorage
  22. $storage.Clear()
  23. # 顔の検出
  24. $faces = [OpenCvSharp.Cv]::HaarDetectObjects($dst1IplImage, $cascade, $storage, $scaleFactor, $minNeighbors, 0, (New-Object OpenCvSharp.CvSize(30, 30)));
  25. # 検出された全ての顔位置に四角い枠で囲む
  26. for ($i = 0; $i -lt $faces.Total; $i++) {
  27. $r = $faces[$i].Rect
  28. $pt1 = New-Object OpenCvSharp.CvPoint($r.x, $r.y)
  29. $pt2 = new-object OpenCvSharp.CvPoint(($r.x + $r.Width),($r.y + $r.Height ))
  30. $iplImage.Rectangle($pt1, $pt2, $color, 3, 8, 0)
  31. }
  32. # 丸で囲いたい場合はこっち
  33. #for ($i = 0; $i -lt $faces.Total; $i++) {
  34. # $r = $faces[$i].Rect
  35. # $X = [OpenCvSharp.Cv]::Round(($r.X + $r.Width * 0.5) * $Scale)
  36. # $Y = [OpenCvSharp.Cv]::Round(($r.Y + $r.Height * 0.5) * $Scale)
  37. # $center = New-Object OpenCvSharp.CvPoint($X, $Y)
  38. # $radius = [OpenCvSharp.Cv]::Round(($r.Width + $r.Height) * 0.25 * $Scale)
  39. # $iplImage.Circle($center, $radius, $color, 3, [OpenCvSharp.LineType]::AntiAlias, 0)
  40. #}
  41. # 赤枠で囲ったデータを保存する
  42. $iplImage.SaveImage((Join-Path $pwd "bar.jpg"))
  43. $iplImage.Dispose()
  44. $srcIplImage.Dispose()
  45. $dst1IplImage.Dispose()

0 コメント: