Dies ist Teil 2 der kleinen Code-Snippet-Reihe, die sich mit der Programmierung von Kinect for Windows mit VB.NET befasst. Teil 1 demonstriert, wie der Color Image Stream mit VB.NET dargestellt wird. Dieser zweite Teil erweitert das in Teil 1 vorgestellte Projekt und demonstriert, wie mit VB.NET der Depth Data Stream in einer WPF-Anwendung dargestellt wird.
Auf geht's.
Im folgenden wird der vollständige Quellcode der bisherigen Beispiel-Anwendung dargestellt. Die WPF-Anwendung zeigt im gegenwärtigen Status der Entwicklung des Projekts den Color Stream und den Depth Stream eines Kinect for Windows-Sensors.
Hier ist der Quellcode von MainWindow.xaml:
1 <Window x:Class="MainWindow"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Kinect for Windows Test App 01" Height="600" Width="800" WindowState="Maximized">
5 <Grid ShowGridLines="True">
6 <Grid.ColumnDefinitions>
7 <ColumnDefinition />
8 <ColumnDefinition Width="auto"/>
9 </Grid.ColumnDefinitions>
10 <Grid Grid.Column="1">
11 <Grid.RowDefinitions>
12 <RowDefinition />
13 <RowDefinition />
14 </Grid.RowDefinitions>
15 <Image x:Name="imVideoStream"
16 Width="640"
17 Height="480"
18 Grid.Row="0" />
19 <Image x:Name="imDepthStream"
20 Width="640"
21 Height="480"
22 Grid.Row="1" />
23 </Grid>
24 </Grid>
25 </Window>
26
Und hier ist der Quellcode von MainWindow.xaml.vb:
1 Imports Microsoft.Kinect
2
3 Class MainWindow
4
5 Private kinectSensor As KinectSensor
6
7 Private Shared ReadOnly Bgr32BytesPerPixel As Integer =
8 CInt(Math.Floor((PixelFormats.Bgr32.BitsPerPixel + 7) / 8))
9
10
11 Public Sub New()
12
13 InitializeComponent()
14
15 kinectSensor = (From sensorToCheck In kinectSensor.KinectSensors
16 Where sensorToCheck.Status = KinectStatus.Connected
17 Select sensorToCheck).FirstOrDefault()
18
19 If kinectSensor IsNot Nothing Then
20
21 kinectSensor.ColorStream.Enable(
22 ColorImageFormat.RgbResolution640x480Fps30)
23
24 kinectSensor.DepthStream.Enable(
25 DepthImageFormat.Resolution640x480Fps30)
26
27 kinectSensor.Start()
28
29 kinectSensor.DepthStream.Range = DepthRange.Near
30
31 AddHandler kinectSensor.ColorFrameReady,
32 AddressOf kisColorFrameReady
33
34 AddHandler kinectSensor.DepthFrameReady,
35 AddressOf kisDepthFrameReady
36
37 End If
38
39 End Sub
40
41
42 #Region " COLOR DATA STREAM "
43
44
45 Private pixelData As Byte()
46
47 Private outputImage As WriteableBitmap
48
49
50 Private Sub kisColorFrameReady(
51 sender As Object,
52 e As ColorImageFrameReadyEventArgs)
53
54 Using imageFrame As ColorImageFrame = e.OpenColorImageFrame()
55
56 If imageFrame IsNot Nothing Then
57
58 Me.pixelData = New Byte(imageFrame.PixelDataLength - 1) {}
59
60 imageFrame.CopyPixelDataTo(Me.pixelData)
61
62 imVideoStream.Visibility = Visibility.Visible
63
64 Me.outputImage = New WriteableBitmap(
65 imageFrame.Width,
66 imageFrame.Height,
67 96,
68 96,
69 PixelFormats.Bgr32,
70 Nothing)
71
72 Me.imVideoStream.Source = Me.outputImage
73
74 Me.outputImage.WritePixels(New Int32Rect(
75 0,
76 0,
77 imageFrame.Width,
78 imageFrame.Height),
79 Me.pixelData,
80 imageFrame.Width * Bgr32BytesPerPixel,
81 0)
82
83 End If
84
85 End Using
86
87 End Sub
88
89
90 #End Region
91
92
93 #Region " DEPTH DATA STREAM "
94
95
96 Private depthPixelData As Short()
97 Private depthFrame32 As Byte()
98 Private outputBitmap As WriteableBitmap
99
100 Private Shared ReadOnly IntensityShiftByPlayerR As Integer() =
101 {1, 2, 0, 2, 0, 0, 2, 0}
102 Private Shared ReadOnly IntensityShiftByPlayerG As Integer() =
103 {1, 2, 2, 0, 2, 0, 0, 1}
104 Private Shared ReadOnly IntensityShiftByPlayerB As Integer() =
105 {1, 0, 2, 2, 0, 2, 0, 2}
106
107 Private Const RedIndex As Integer = 2
108 Private Const GreenIndex As Integer = 1
109 Private Const BlueIndex As Integer = 0
110
111
112 Private Sub kisDepthFrameReady(sender As Object,
113 e As DepthImageFrameReadyEventArgs)
114
115 Using imageFrame As DepthImageFrame = e.OpenDepthImageFrame()
116
117 If imageFrame IsNot Nothing Then
118
119 Me.depthPixelData = New Short(imageFrame.PixelDataLength - 1) {}
120 Me.depthFrame32 = New Byte(
121 imageFrame.Width * imageFrame.Height * Bgr32BytesPerPixel - 1) {}
122
123 imageFrame.CopyPixelDataTo(Me.depthPixelData)
124
125 Dim convertedDepthBits As Byte() = Me.ConvertDepthFrame(
126 Me.depthPixelData, DirectCast(sender, KinectSensor).DepthStream)
127
128 Me.outputBitmap = New WriteableBitmap(
129 imageFrame.Width, imageFrame.Height, 96, 96, PixelFormats.Bgr32, Nothing)
130
131 Me.imDepthStream.Source = Me.outputBitmap
132
133 Me.outputBitmap.WritePixels(New Int32Rect(0,
134 0,
135 imageFrame.Width,
136 imageFrame.Height),
137 convertedDepthBits,
138 imageFrame.Width * Bgr32BytesPerPixel,
139 0)
140
141 End If
142
143 End Using
144
145 End Sub
146
147
148 Private Function ConvertDepthFrame(depthFrame As Short(),
149 depthStream As DepthImageStream) _
150 As Byte()
151
152 Dim tooNearDepth As Integer = depthStream.TooNearDepth
153 Dim tooFarDepth As Integer = depthStream.TooFarDepth
154 Dim unknownDepth As Integer = depthStream.UnknownDepth
155
156 Dim i16 As Integer = 0, i32 As Integer = 0
157 While i16 < depthFrame.Length AndAlso i32 < Me.depthFrame32.Length
158 Dim player As Integer =
159 depthFrame(i16) And DepthImageFrame.PlayerIndexBitmask
160 Dim realDepth As Integer =
161 depthFrame(i16) >> DepthImageFrame.PlayerIndexBitmaskWidth
162
163 ' transform 13-bit depth information into an 8-bit intensity appropriate
164 ' for display (we disregard information in most significant bit)
165 Dim intensity As Byte = (Not (realDepth >> 4)) And 255
166
167 If player = 0 AndAlso realDepth = 0 Then
168 ' white
169 Me.depthFrame32(i32 + RedIndex) = 255
170 Me.depthFrame32(i32 + GreenIndex) = 255
171 Me.depthFrame32(i32 + BlueIndex) = 255
172 ElseIf player = 0 AndAlso realDepth = tooFarDepth Then
173 ' dark purple
174 Me.depthFrame32(i32 + RedIndex) = 66
175 Me.depthFrame32(i32 + GreenIndex) = 0
176 Me.depthFrame32(i32 + BlueIndex) = 66
177 ElseIf player = 0 AndAlso realDepth = unknownDepth Then
178 ' dark brown
179 Me.depthFrame32(i32 + RedIndex) = 66
180 Me.depthFrame32(i32 + GreenIndex) = 66
181 Me.depthFrame32(i32 + BlueIndex) = 33
182 Else
183 ' tint the intensity by dividing by per-player values
184 Me.depthFrame32(i32 + RedIndex) =
185 CByte(intensity >> IntensityShiftByPlayerR(player))
186 Me.depthFrame32(i32 + GreenIndex) =
187 CByte(intensity >> IntensityShiftByPlayerG(player))
188 Me.depthFrame32(i32 + BlueIndex) =
189 CByte(intensity >> IntensityShiftByPlayerB(player))
190 End If
191 i16 += 1
192 i32 += 4
193 End While
194
195 Return Me.depthFrame32
196
197 End Function
198
199
200 #End Region
201
202
203 Private Sub MainWindow_Closing(sender As Object,
204 e As System.ComponentModel.CancelEventArgs) _
205 Handles Me.Closing
206
207 kinectSensor.Stop()
208
209 End Sub
210
211
212 End Class
213
An dieser Stelle möchte ich auf diesen Thread aus den Kinect-Forums hinweisen, der mir bei der Übersetzung einer bestimmten Code-Zeile von C# nach VB.NET geholfen hat.
Diese Serie wird in loser Reihenfolge fortgesetzt.
Have fun!
Keine Kommentare:
Kommentar veröffentlichen