Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports Emgu.CV
Imports Emgu.CV.Structure
Imports Microsoft.Kinect
Imports system.ComponentModel
Imports CatFinder.ImageManipulationExtensionMethods

''' <summary>
''' Interaction logic for MainWindow.xaml
''' </summary>
''' <remarks></remarks>
Class MainWindow
    Private _kinectSensor As KinectSensor

    Private faceFileName As String = "haarcascade_frontalface_default.xml"

    Public Sub New()

        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        AddHandler Me.Unloaded, Sub()
                                    _kinectSensor.ColorStream.Disable()
                                End Sub
        AddHandler Me.Loaded, Sub()
                                  _kinectSensor = KinectSensor.KinectSensors(0)
                                  _kinectSensor.ColorStream.Enable()
                                  _kinectSensor.Start()

                                  Dim bw As New BackgroundWorker()
                                  AddHandler bw.RunWorkerCompleted, Sub(a, b)
                                                                        bw.RunWorkerAsync()
                                                                    End Sub
                                  AddHandler bw.DoWork, Sub()
                                                            Pulse()
                                                        End Sub
                                  bw.RunWorkerAsync()
                              End Sub
    End Sub

    Public Sub Pulse()
        Using face As New HaarCascade(faceFileName) 'EmguのBinフォルダからdllをCOPYしていないとエラーになる
            Dim frame As ColorImageFrame = _kinectSensor.ColorStream.OpenNextFrame(100)
            Dim image As Image(Of Rgb, Byte) = frame.ToOpenCVImage(Of Rgb, Byte)()
            Using gray As Image(Of Gray, Byte) = image.Convert(Of Gray, Byte)() 'Convert it to Grayscale
                'normalizes brightness and increases contrast of the image
                gray._EqualizeHist()

                'Detect the faces  from the gray scale image and store the locations as rectangle
                'The first dimensional is the channel
                'The second dimension is the index of the rectangle in the specific channel
                Dim facesDetected() As MCvAvgComp = face.Detect(
                   gray,
                   1.1,
                   10,
                   Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING,
                   New System.Drawing.Size(20, 20))

                Dim laughingMan As New Image(Of Rgb, Byte)("neko_02.png")
                For Each f As MCvAvgComp In facesDetected
                    'image.Draw(f.rect, new Rgb(System.Drawing.Color.Blue), 2)
                    Dim rect As New System.Drawing.Rectangle(f.rect.X - f.rect.Width / 2,
                                                             f.rect.Y - f.rect.Height / 2,
                                                             f.rect.Width * 2,
                                                             f.rect.Height * 2)

                    Dim newImage As Emgu.CV.Image(Of Rgb, Byte) =
                        laughingMan.Resize(rect.Width,
                                           rect.Height,
                                           Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR)

                    For i As Integer = 0 To rect.Height - 1
                        For j As Integer = 0 To rect.Width - 1
                            '完全ブルーは透過する
                            If (Not (newImage(i, j).Blue = 255 AndAlso newImage(i, j).Red = 0 AndAlso newImage(i, j).Green = 0)) Then
                                image(i + rect.Y, j + rect.X) = newImage(i, j)
                            End If
                        Next

                    Next
                Next

                Dispatcher.BeginInvoke(New Action(Sub()
                                                      rgbImage.Source = image.ToBitmapSource()
                                                  End Sub))
            End Using
        End Using
    End Sub
End Class
