ただ建築が好きな走るエンジニア、

日系某メーカーを辞めて外資系に転職。資格、建築デザイン、転職と来て今はひたすらす走ってます。2020別大2:49:13。

誰に似てるか?(OpenCV MatchTemplateを試す)

2014-07-29 23:11:27 | 電気

いつもとちょっと違う話題です。

昨晩一番下の二女がいきなり40度近い高熱を出し、
今朝も状態改善しなかったので、
病院に連れて行くのを口実に
会社を休んでしまいました。

買い物や昼食の準備など何となく義務を果たすと
あとは薬を飲んですやすや眠る娘の横で空白の時間。

ちょっとプログラミングをしてみることにしました。

実はRaspberry Piを買ってから
長男とロボットを作ってみたくなり、
モーター制御や画像認識など少しずつ...

で、今日できてしまったのはこれ。



Visual Studio 2012 VB.NET
OpenCV 2.4.5(OpenCVsharp)
&
Vaio内蔵カメラを使い、

Cv.MatchTemplateというテンプレート比較を利用した
顔認識のプログラムです。

テンプレートに子ども三人の顔を並べ誰に一番似ているか?

意外な結果が...

元気になった二女を含め夏休みの子ども達と少し盛り上がりました。

ちなみにマッチングを高めるには
テンプレートの顔は目鼻口のなるべく最小単位に絞ることや照明
が重要ということが分かりました。

備忘録でソースコードも。


Imports OpenCvSharp
Imports System.Net.Mail

Public Class Form1

    'initialize

    Dim CameraStatus As Boolean
    Dim Mcapture As CvCapture = Cv.CreateCameraCapture(0)
    Dim frame As IplImage
    Dim c As Integer

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click

        CameraStatus = False

    End Sub

    'Save the captured image

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

        Dim str As String
        str = "C:\dev\scrshot.bmp"
        Cv.SaveImage(str, frame)

    End Sub

    'Send Mail

    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

        Try

            Dim msg As New System.Net.Mail.MailMessage()
            Dim ToAdd As String

            ToAdd = TextBox1.Text

            msg.From = New System.Net.Mail.MailAddress("xxxxxxxx@xxx.xxxxx.xx.xx")
            msg.To.Add(New System.Net.Mail.MailAddress(ToAdd))
            msg.Subject = "scrshot"
            msg.Body = "This is screen shot photograph" + vbCrLf + vbCrLf + "from xxxx."
            Dim attach1 As New System.Net.Mail.Attachment("C:\dev\scrshot.bmp")
            msg.Attachments.Add(attach1)
            Dim sc As New System.Net.Mail.SmtpClient()

            sc.Credentials = New System.Net.NetworkCredential("xxxxxxxx@xxx.xxxxx.xx.xx""xxxxxxxx")

            sc.Host = "xxxxx.xxx.xxxxx.xx.xx"
            sc.Port = xxx
            sc.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network
            sc.Send(msg)
            sc.Dispose()

            MsgBox("mail send")

        Catch ex As Exception
            MsgBox(ex.ToString)

        End Try

    End Sub

    'Procedure before exit

    Private Sub Form1_Closing(ByVal sender As ObjectByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.FormClosing

        If CameraStatus = True Then
            MsgBox("Please push 'CameraOff' before exit")
            e.Cancel = True
        End If

    End Sub

    'Template matching

    Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click

        Dim TempFileName(2As String
        Dim tempImage(2As IplImage
        Dim sz(2As CvSize
        Dim result(2As IplImage

        Dim g As Graphics = PictureBox1.CreateGraphics
        Dim canvas As New Bitmap(PictureBox1.Width, PictureBox1.Height)
        Dim p(2As Pen

        p(0) = Pens.Blue
        p(1) = Pens.Red
        p(2) = Pens.Yellow

        For i As Integer = 0 To 2

            TempFileName(i) = "C:\dev\Template" & i.ToString & ".bmp"
            tempImage(i) = Cv.LoadImage(TempFileName(i))

            sz(i) = Cv.Size(320 - tempImage(i).Width + 1240 - tempImage(i).Height + 1)
            result(i) = Cv.CreateImage(sz(i), BitDepth.F32, 1)

            DirectCast(Me.Controls("PictureBox" & (i + 2).ToString), PictureBox).SizeMode = PictureBoxSizeMode.CenterImage
            DirectCast(Me.Controls("PictureBox" & (i + 2).ToString), PictureBox).Image = tempImage(i).ToBitmap

        Next

        'Get image size

        Cv.SetCaptureProperty(Mcapture, CvConst.CV_CAP_PROP_FRAME_WIDTH, 320)
        Cv.SetCaptureProperty(Mcapture, CvConst.CV_CAP_PROP_FRAME_HEIGHT, 240)

        Dim minVal(2As Double
        Dim maxVal(2As Double
        Dim minLoc(2As CvPoint
        Dim maxLoc(2As CvPoint

        CameraStatus = True
        Do While CameraStatus

            frame = Cv.QueryFrame(Mcapture)
            Cv.ShowImage("Capture", frame)
            PictureBox1.Image = frame.ToBitmap()

            For i As Integer = 0 To 2

                Cv.MatchTemplate(frame, tempImage(i), result(i), MatchTemplateMethod.CCoeffNormed)
                Cv.MinMaxLoc(result(i), minVal(i), maxVal(i), minLoc(i), maxLoc(i))

                g.DrawRectangle(p(i), maxLoc(i).X, maxLoc(i).Y, tempImage(i).Width, tempImage(i).Height)

                DirectCast(Me.Controls("TextBox" & (i * 8 + 3).ToString), TextBox).Text = maxVal(i).ToString("0.00")
                DirectCast(Me.Controls("TextBox" & (i * 8 + 4).ToString), TextBox).Text = maxLoc(i).X.ToString
                DirectCast(Me.Controls("TextBox" & (i * 8 + 5).ToString), TextBox).Text = maxLoc(i).Y.ToString
                DirectCast(Me.Controls("TextBox" & (i * 8 + 8).ToString), TextBox).Text = tempImage(i).Width.ToString
                DirectCast(Me.Controls("TextBox" & (i * 8 + 9).ToString), TextBox).Text = tempImage(i).Height.ToString

            Next

            c = Cv.WaitKey(50)

        Loop

    End Sub

End Class

 

 



Comments (3)