Initial commit

This commit is contained in:
marek
2015-10-15 17:07:34 +02:00
parent da44352544
commit 9ebff446fa
239 changed files with 375645 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
+429
View File
@@ -0,0 +1,429 @@
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
// License: MIT Software License See LICENSE.txt for the full license.
// If you use this software in your research, then please use the following citation:
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
// @INPROCEEDINGS{Kowalski15,
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
// booktitle={3D Vision (3DV), 2015 International Conference on},
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
// year={2015},
// }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.ComponentModel;
namespace KinectServer
{
public delegate void SocketListChangedHandler(List<KinectSocket> list);
public class KinectServer
{
Socket oServerSocket;
bool bServerRunning = false;
KinectSettings oSettings;
object oClientSocketLock = new object();
object oFrameRequestLock = new object();
List<KinectSocket> lClientSockets = new List<KinectSocket>();
public event SocketListChangedHandler eSocketListChanged;
public int nClientCount
{
get
{
int nClients;
lock (oClientSocketLock)
{
nClients = lClientSockets.Count;
}
return nClients;
}
}
public List<AffineTransform> lCameraPoses
{
get
{
List<AffineTransform> cameraPoses = new List<AffineTransform>();
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
cameraPoses.Add(lClientSockets[i].oCameraPose);
}
}
return cameraPoses;
}
}
public List<AffineTransform> lWorldTransforms
{
get
{
List<AffineTransform> worldTransforms = new List<AffineTransform>();
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
worldTransforms.Add(lClientSockets[i].oWorldTransform);
}
}
return worldTransforms;
}
set
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lClientSockets[i].oWorldTransform = value[i];
}
}
}
}
public bool bAllCalibrated
{
get
{
bool allCalibrated = true;
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
if (!lClientSockets[i].bCalibrated)
{
allCalibrated = false;
break;
}
}
}
return allCalibrated;
}
}
public KinectServer(KinectSettings settings)
{
this.oSettings = settings;
}
private void SocketListChanged()
{
if (eSocketListChanged != null)
{
eSocketListChanged(lClientSockets);
}
}
public void StartServer()
{
if (!bServerRunning)
{
oServerSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
oServerSocket.Blocking = false;
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 48001);
oServerSocket.Bind(endPoint);
oServerSocket.Listen(10);
bServerRunning = true;
Thread listeningThread = new Thread(this.ListeningWorker);
listeningThread.Start();
Thread receivingThread = new Thread(this.ReceivingWorker);
receivingThread.Start();
}
}
public void StopServer()
{
if (bServerRunning)
{
bServerRunning = false;
oServerSocket.Close();
lock (oClientSocketLock)
lClientSockets.Clear();
}
}
public void CaptureSynchronizedFrame()
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
lClientSockets[i].CaptureFrame();
}
//Wait till frames captured
bool allGathered = false;
while (!allGathered)
{
allGathered = true;
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
if (!lClientSockets[i].bFrameCaptured)
{
allGathered = false;
break;
}
}
}
}
}
public void Calibrate()
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lClientSockets[i].Calibrate();
}
}
}
public void SendSettings()
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lClientSockets[i].SendSettings(oSettings);
}
}
}
public void SendCalibrationData()
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lClientSockets[i].SendCalibrationData();
}
}
}
public void GetStoredFrame(List<List<byte>> lFramesRGB, List<List<Single>> lFramesVerts)
{
lFramesRGB.Clear();
lFramesVerts.Clear();
lock (oFrameRequestLock)
{
//Request frames
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
lClientSockets[i].RequestStoredFrame();
}
//Wait till frames received
bool allGathered = false;
while (!allGathered)
{
allGathered = true;
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
if (!lClientSockets[i].bStoredFrameReceived)
{
allGathered = false;
break;
}
}
}
}
//Store received frames
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lFramesRGB.Add(new List<byte>(lClientSockets[i].lFrameRGB));
lFramesVerts.Add(new List<Single>(lClientSockets[i].lFrameVerts));
}
}
}
}
public void GetLatestFrame(List<List<byte>> lFramesRGB, List<List<Single>> lFramesVerts)
{
lFramesRGB.Clear();
lFramesVerts.Clear();
lock (oFrameRequestLock)
{
//Request frames
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
lClientSockets[i].RequestLastFrame();
}
//Wait till frames received
bool allGathered = false;
while (!allGathered)
{
allGathered = true;
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
if (!lClientSockets[i].bLatestFrameReceived)
{
allGathered = false;
break;
}
}
}
}
//Store received frames
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lFramesRGB.Add(new List<byte>(lClientSockets[i].lFrameRGB));
lFramesVerts.Add(new List<Single>(lClientSockets[i].lFrameVerts));
}
}
}
}
public void ClearStoredFrames()
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lClientSockets[i].ClearStoredFrames();
}
}
}
private void ListeningWorker()
{
while (bServerRunning)
{
try
{
Socket newClient = oServerSocket.Accept();
//we do not want to add new clients while a frame is being requested
lock (oFrameRequestLock)
{
lock (oClientSocketLock)
{
lClientSockets.Add(new KinectSocket(newClient));
lClientSockets[lClientSockets.Count - 1].SendSettings(oSettings);
lClientSockets[lClientSockets.Count - 1].eChanged += new SocketChangedHandler(SocketListChanged);
if (eSocketListChanged != null)
{
eSocketListChanged(lClientSockets);
}
}
}
}
catch (SocketException)
{
}
System.Threading.Thread.Sleep(100);
}
if (eSocketListChanged != null)
{
eSocketListChanged(lClientSockets);
}
}
private void ReceivingWorker()
{
System.Timers.Timer checkConnectionTimer = new System.Timers.Timer();
checkConnectionTimer.Interval = 1000;
checkConnectionTimer.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e)
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
if (!lClientSockets[i].SocketConnected())
{
lClientSockets.RemoveAt(i);
if (eSocketListChanged != null)
{
eSocketListChanged(lClientSockets);
}
continue;
}
}
}
};
checkConnectionTimer.Start();
while (bServerRunning)
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
byte[] buffer = lClientSockets[i].Receive(1);
while (buffer.Length != 0)
{
if (buffer[0] == 0)
{
lClientSockets[i].bFrameCaptured = true;
}
else if (buffer[0] == 1)
{
lClientSockets[i].ReceiveCalibrationData();
}
//stored frame
else if (buffer[0] == 2)
{
lClientSockets[i].ReceiveFrame();
lClientSockets[i].bStoredFrameReceived = true;
}
//last frame
else if (buffer[0] == 3)
{
lClientSockets[i].ReceiveFrame();
lClientSockets[i].bLatestFrameReceived = true;
}
buffer = lClientSockets[i].Receive(1);
}
}
}
Thread.Sleep(10);
}
checkConnectionTimer.Stop();
}
}
}
+93
View File
@@ -0,0 +1,93 @@
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
// License: MIT Software License See LICENSE.txt for the full license.
// If you use this software in your research, then please use the following citation:
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
// @INPROCEEDINGS{Kowalski15,
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
// booktitle={3D Vision (3DV), 2015 International Conference on},
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
// year={2015},
// }
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KinectServer
{
[Serializable]
public class KinectSettings
{
public float[] aMinBounds = new float[3];
public float[] aMaxBounds = new float[3];
public bool bFilter = false;
public int nFilterNeighbors = 10;
public float fFilterThreshold = 0.1f;
public BindingList<MarkerPose> lMarkerPoses = new BindingList<MarkerPose>();
public int nNumICPIterations = 10;
public int nMaxNumRefineIters = 10;
public bool bMergeScansForSave = false;
public KinectSettings()
{
aMinBounds[0] = -5f;
aMinBounds[1] = -5f;
aMinBounds[2] = -5f;
aMaxBounds[0] = 5f;
aMaxBounds[1] = 5f;
aMaxBounds[2] = 5f;
}
public List<byte> ToByteList()
{
List<byte> lData = new List<byte>();
byte[] bTemp = new byte[sizeof(float) * 3];
Buffer.BlockCopy(aMinBounds, 0, bTemp, 0, sizeof(float) * 3);
lData.AddRange(bTemp);
Buffer.BlockCopy(aMaxBounds, 0, bTemp, 0, sizeof(float) * 3);
lData.AddRange(bTemp);
if (bFilter)
lData.Add(1);
else
lData.Add(0);
bTemp = BitConverter.GetBytes(nFilterNeighbors);
lData.AddRange(bTemp);
bTemp = BitConverter.GetBytes(fFilterThreshold);
lData.AddRange(bTemp);
bTemp = BitConverter.GetBytes(lMarkerPoses.Count);
lData.AddRange(bTemp);
for (int i = 0; i < lMarkerPoses.Count; i++)
{
bTemp = new byte[sizeof(float) * 9];
Buffer.BlockCopy(lMarkerPoses[i].pose.R, 0, bTemp, 0, sizeof(float) * 9);
lData.AddRange(bTemp);
bTemp = new byte[sizeof(float) * 3];
Buffer.BlockCopy(lMarkerPoses[i].pose.t, 0, bTemp, 0, sizeof(float) * 3);
lData.AddRange(bTemp);
bTemp = BitConverter.GetBytes(lMarkerPoses[i].id);
lData.AddRange(bTemp);
}
return lData;
}
}
}
+246
View File
@@ -0,0 +1,246 @@
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
// License: MIT Software License See LICENSE.txt for the full license.
// If you use this software in your research, then please use the following citation:
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
// @INPROCEEDINGS{Kowalski15,
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
// booktitle={3D Vision (3DV), 2015 International Conference on},
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
// year={2015},
// }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
namespace KinectServer
{
public delegate void SocketChangedHandler();
public class KinectSocket
{
Socket oSocket;
byte[] byteToSend = new byte[1];
public bool bFrameCaptured = false;
public bool bLatestFrameReceived = false;
public bool bStoredFrameReceived = false;
public bool bCalibrated = false;
//The pose of the sensor in the scene (used by the OpenGLWindow to show the sensor)
public AffineTransform oCameraPose = new AffineTransform();
//The transform that maps the vertices in the sensor coordinate system to the world corrdinate system.
public AffineTransform oWorldTransform = new AffineTransform();
public string sSocketState;
public List<byte> lFrameRGB = new List<byte>();
public List<Single> lFrameVerts = new List<Single>();
public event SocketChangedHandler eChanged;
public KinectSocket(Socket clientSocket)
{
oSocket = clientSocket;
sSocketState = oSocket.RemoteEndPoint.ToString() + " Calibrated = false";
}
public void CaptureFrame()
{
bFrameCaptured = false;
byteToSend[0] = 0;
SendByte();
}
public void Calibrate()
{
bCalibrated = false;
sSocketState = oSocket.RemoteEndPoint.ToString() + " Calibrated = false";
byteToSend[0] = 1;
SendByte();
UpdateSocketState();
}
public void SendSettings(KinectSettings settings)
{
List<byte> lData = settings.ToByteList();
byte[] bTemp = BitConverter.GetBytes(lData.Count);
lData.InsertRange(0, bTemp);
lData.Insert(0, 2);
if (SocketConnected())
oSocket.Send(lData.ToArray());
}
public void RequestStoredFrame()
{
byteToSend[0] = 3;
SendByte();
bStoredFrameReceived = false;
}
public void RequestLastFrame()
{
byteToSend[0] = 4;
SendByte();
bLatestFrameReceived = false;
}
public void SendCalibrationData()
{
int size = 1 + 2 * (9 + 3) * sizeof(float);
byte[] data = new byte[size];
int i = 0;
data[i] = 5;
i++;
Buffer.BlockCopy(oWorldTransform.R, 0, data, i, 9 * sizeof(float));
i += 9 * sizeof(float);
Buffer.BlockCopy(oWorldTransform.t, 0, data, i, 3 * sizeof(float));
i += 3 * sizeof(float);
Buffer.BlockCopy(oCameraPose.R, 0, data, i, 9 * sizeof(float));
i += 9 * sizeof(float);
Buffer.BlockCopy(oCameraPose.t, 0, data, i, 3 * sizeof(float));
i += 3 * sizeof(float);
if (SocketConnected())
oSocket.Send(data);
}
public void ClearStoredFrames()
{
byteToSend[0] = 6;
SendByte();
}
public void ReceiveCalibrationData()
{
bCalibrated = true;
byte[] buffer = Receive(sizeof(int) * 1);
//currently not used
int markerId = BitConverter.ToInt32(buffer, 0);
buffer = Receive(sizeof(float) * 9);
Buffer.BlockCopy(buffer, 0, oWorldTransform.R, 0, sizeof(float) * 9);
buffer = Receive(sizeof(float) * 3);
Buffer.BlockCopy(buffer, 0, oWorldTransform.t, 0, sizeof(float) * 3);
buffer = Receive(sizeof(float) * 9);
Buffer.BlockCopy(buffer, 0, oCameraPose.R, 0, sizeof(float) * 9);
buffer = Receive(sizeof(float) * 3);
Buffer.BlockCopy(buffer, 0, oCameraPose.t, 0, sizeof(float) * 3);
UpdateSocketState();
}
public void ReceiveFrame()
{
lFrameRGB.Clear();
lFrameVerts.Clear();
int nToRead;
byte[] buffer = new byte[1024];
while (oSocket.Available == 0)
{
if (!SocketConnected())
return;
}
oSocket.Receive(buffer, 4, SocketFlags.None);
//string result = System.Text.Encoding.UTF8.GetString(buffer);
//n_to_read = Int32.Parse(result);
nToRead = BitConverter.ToInt32(buffer, 0);
if (nToRead == 0)
return;
buffer = new byte[nToRead];
int nAlreadyRead = 0;
while (nAlreadyRead != nToRead)
{
while (oSocket.Available == 0)
{
if (!SocketConnected())
return;
}
nAlreadyRead += oSocket.Receive(buffer, nAlreadyRead, nToRead - nAlreadyRead, SocketFlags.None);
}
int point_size = 3 + 3 * 4;
int n_vertices = nToRead / point_size;
for (int i = 0; i < n_vertices; i++)
{
for (int j = 0; j < 3; j++)
{
lFrameRGB.Add(buffer[i * point_size + j]);
lFrameVerts.Add(BitConverter.ToSingle(buffer, i * point_size + j * 4 + 3));
}
}
}
public byte[] Receive(int nBytes)
{
byte[] buffer;
if (oSocket.Available != 0)
{
buffer = new byte[Math.Min(nBytes, oSocket.Available)];
oSocket.Receive(buffer, nBytes, SocketFlags.None);
}
else
buffer = new byte[0];
return buffer;
}
public bool SocketConnected()
{
bool part1 = oSocket.Poll(1000, SelectMode.SelectRead);
bool part2 = (oSocket.Available == 0);
if (part1 && part2)
{
return false;
}
else
{
return true;
}
}
private void SendByte()
{
oSocket.Send(byteToSend);
}
public void UpdateSocketState()
{
if (bCalibrated)
sSocketState = oSocket.RemoteEndPoint.ToString() + " Calibrated = true";
else
sSocketState = oSocket.RemoteEndPoint.ToString() + " Calibrated = false";
if (eChanged != null)
eChanged();
}
}
}
+105
View File
@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{78422B2C-0EF1-4A28-A40E-2A7C4A9204B1}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>KinectServer</RootNamespace>
<AssemblyName>LiveScanServer</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="OpenTK, Version=1.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL" />
<Reference Include="OpenTK.Compatibility, Version=1.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL" />
<Reference Include="OpenTK.GLControl, Version=1.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainWindowForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainWindowForm.Designer.cs">
<DependentUpon>MainWindowForm.cs</DependentUpon>
</Compile>
<Compile Include="KinectServer.cs" />
<Compile Include="KinectSettings.cs" />
<Compile Include="KinectSocket.cs" />
<Compile Include="OpenGLWindow.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SettingsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="SettingsForm.Designer.cs">
<DependentUpon>SettingsForm.cs</DependentUpon>
</Compile>
<Compile Include="Utils.cs" />
<EmbeddedResource Include="MainWindowForm.resx">
<DependentUpon>MainWindowForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="SettingsForm.resx">
<DependentUpon>SettingsForm.cs</DependentUpon>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+225
View File
@@ -0,0 +1,225 @@
namespace KinectServer
{
partial class MainWindowForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btStart = new System.Windows.Forms.Button();
this.btCalibrate = new System.Windows.Forms.Button();
this.btRecord = new System.Windows.Forms.Button();
this.lClientListBox = new System.Windows.Forms.ListBox();
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.recordingWorker = new System.ComponentModel.BackgroundWorker();
this.txtSeqName = new System.Windows.Forms.TextBox();
this.btRefineCalib = new System.Windows.Forms.Button();
this.OpenGLWorker = new System.ComponentModel.BackgroundWorker();
this.savingWorker = new System.ComponentModel.BackgroundWorker();
this.updateWorker = new System.ComponentModel.BackgroundWorker();
this.btShowLive = new System.Windows.Forms.Button();
this.btSettings = new System.Windows.Forms.Button();
this.refineWorker = new System.ComponentModel.BackgroundWorker();
this.lbSeqName = new System.Windows.Forms.Label();
this.statusStrip1.SuspendLayout();
this.SuspendLayout();
//
// btStart
//
this.btStart.Location = new System.Drawing.Point(12, 12);
this.btStart.Name = "btStart";
this.btStart.Size = new System.Drawing.Size(95, 23);
this.btStart.TabIndex = 0;
this.btStart.Text = "Start server";
this.btStart.UseVisualStyleBackColor = true;
this.btStart.Click += new System.EventHandler(this.btStart_Click);
//
// btCalibrate
//
this.btCalibrate.Location = new System.Drawing.Point(12, 70);
this.btCalibrate.Name = "btCalibrate";
this.btCalibrate.Size = new System.Drawing.Size(95, 23);
this.btCalibrate.TabIndex = 2;
this.btCalibrate.Text = "Calibrate";
this.btCalibrate.UseVisualStyleBackColor = true;
this.btCalibrate.Click += new System.EventHandler(this.btCalibrate_Click);
//
// btRecord
//
this.btRecord.Location = new System.Drawing.Point(12, 126);
this.btRecord.Name = "btRecord";
this.btRecord.Size = new System.Drawing.Size(95, 23);
this.btRecord.TabIndex = 4;
this.btRecord.Text = "Start recording";
this.btRecord.UseVisualStyleBackColor = true;
this.btRecord.Click += new System.EventHandler(this.btRecord_Click);
//
// lClientListBox
//
this.lClientListBox.FormattingEnabled = true;
this.lClientListBox.Location = new System.Drawing.Point(113, 12);
this.lClientListBox.Name = "lClientListBox";
this.lClientListBox.Size = new System.Drawing.Size(219, 108);
this.lClientListBox.TabIndex = 5;
//
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.statusLabel});
this.statusStrip1.Location = new System.Drawing.Point(0, 187);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(344, 22);
this.statusStrip1.TabIndex = 6;
this.statusStrip1.Text = "statusStrip1";
//
// statusLabel
//
this.statusLabel.Name = "statusLabel";
this.statusLabel.Size = new System.Drawing.Size(0, 17);
//
// recordingWorker
//
this.recordingWorker.WorkerSupportsCancellation = true;
this.recordingWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.recordingWorker_DoWork);
this.recordingWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.recordingWorker_RunWorkerCompleted);
//
// txtSeqName
//
this.txtSeqName.Location = new System.Drawing.Point(113, 155);
this.txtSeqName.MaxLength = 40;
this.txtSeqName.Name = "txtSeqName";
this.txtSeqName.Size = new System.Drawing.Size(106, 20);
this.txtSeqName.TabIndex = 7;
this.txtSeqName.Text = "noname";
//
// btRefineCalib
//
this.btRefineCalib.Location = new System.Drawing.Point(12, 97);
this.btRefineCalib.Name = "btRefineCalib";
this.btRefineCalib.Size = new System.Drawing.Size(95, 23);
this.btRefineCalib.TabIndex = 11;
this.btRefineCalib.Text = "Refine calib";
this.btRefineCalib.UseVisualStyleBackColor = true;
this.btRefineCalib.Click += new System.EventHandler(this.btRefineCalib_Click);
//
// OpenGLWorker
//
this.OpenGLWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.OpenGLWorker_DoWork);
this.OpenGLWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.OpenGLWorker_RunWorkerCompleted);
//
// savingWorker
//
this.savingWorker.WorkerSupportsCancellation = true;
this.savingWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.savingWorker_DoWork);
this.savingWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.savingWorker_RunWorkerCompleted);
//
// updateWorker
//
this.updateWorker.WorkerSupportsCancellation = true;
this.updateWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.updateWorker_DoWork);
//
// btShowLive
//
this.btShowLive.Location = new System.Drawing.Point(12, 154);
this.btShowLive.Name = "btShowLive";
this.btShowLive.Size = new System.Drawing.Size(95, 23);
this.btShowLive.TabIndex = 12;
this.btShowLive.Text = "Show live";
this.btShowLive.UseVisualStyleBackColor = true;
this.btShowLive.Click += new System.EventHandler(this.btShowLive_Click);
//
// btSettings
//
this.btSettings.Location = new System.Drawing.Point(12, 41);
this.btSettings.Name = "btSettings";
this.btSettings.Size = new System.Drawing.Size(95, 23);
this.btSettings.TabIndex = 13;
this.btSettings.Text = "Settings";
this.btSettings.UseVisualStyleBackColor = true;
this.btSettings.Click += new System.EventHandler(this.btSettings_Click);
//
// refineWorker
//
this.refineWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.refineWorker_DoWork);
this.refineWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.refineWorker_RunWorkerCompleted);
//
// lbSeqName
//
this.lbSeqName.AutoSize = true;
this.lbSeqName.Location = new System.Drawing.Point(113, 136);
this.lbSeqName.Name = "lbSeqName";
this.lbSeqName.Size = new System.Drawing.Size(88, 13);
this.lbSeqName.TabIndex = 14;
this.lbSeqName.Text = "Sequence name:";
//
// MainWindowForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(344, 209);
this.Controls.Add(this.lbSeqName);
this.Controls.Add(this.btSettings);
this.Controls.Add(this.btShowLive);
this.Controls.Add(this.btRefineCalib);
this.Controls.Add(this.txtSeqName);
this.Controls.Add(this.statusStrip1);
this.Controls.Add(this.lClientListBox);
this.Controls.Add(this.btRecord);
this.Controls.Add(this.btCalibrate);
this.Controls.Add(this.btStart);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "MainWindowForm";
this.Text = "LiveScanServer";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btStart;
private System.Windows.Forms.Button btCalibrate;
private System.Windows.Forms.Button btRecord;
private System.Windows.Forms.ListBox lClientListBox;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.ComponentModel.BackgroundWorker recordingWorker;
private System.Windows.Forms.TextBox txtSeqName;
private System.Windows.Forms.Button btRefineCalib;
private System.ComponentModel.BackgroundWorker OpenGLWorker;
private System.ComponentModel.BackgroundWorker savingWorker;
private System.ComponentModel.BackgroundWorker updateWorker;
private System.Windows.Forms.Button btShowLive;
private System.Windows.Forms.Button btSettings;
private System.ComponentModel.BackgroundWorker refineWorker;
private System.Windows.Forms.ToolStripStatusLabel statusLabel;
private System.Windows.Forms.Label lbSeqName;
}
}
+524
View File
@@ -0,0 +1,524 @@
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
// License: MIT Software License See LICENSE.txt for the full license.
// If you use this software in your research, then please use the following citation:
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
// @INPROCEEDINGS{Kowalski15,
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
// booktitle={3D Vision (3DV), 2015 International Conference on},
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
// year={2015},
// }
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Globalization;
using System.Runtime.Serialization;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Timers;
namespace KinectServer
{
public partial class MainWindowForm : Form
{
[DllImport("ICP.dll")]
static extern float ICP(IntPtr verts1, IntPtr verts2, int nVerts1, int nVerts2, float[] R, float[] t, int maxIter = 200);
KinectServer oServer;
//Those three variables are shared with the OpenGLWindow class and are used to exchange data with it.
//Vertices from all of the sensors
List<float> lAllVertices = new List<float>();
//Color data from all of the sensors
List<byte> lAllColors = new List<byte>();
//Sensor poses from all of the sensors
List<AffineTransform> lAllCameraPoses = new List<AffineTransform>();
bool bServerRunning = false;
bool bRecording = false;
bool bSaving = false;
//Live view open or not
bool bLiveViewRunning = false;
System.Timers.Timer oStatusBarTimer = new System.Timers.Timer();
KinectSettings oSettings = new KinectSettings();
//The live view window class
OpenGLWindow oOpenGLWindow;
public MainWindowForm()
{
//This tries to read the settings from "settings.bin", if it failes the settings stay at default values.
try
{
IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
Stream stream = new FileStream("settings.bin", FileMode.Open, FileAccess.Read);
oSettings = (KinectSettings)formatter.Deserialize(stream);
stream.Close();
}
catch(Exception)
{
}
oServer = new KinectServer(oSettings);
oServer.eSocketListChanged += new SocketListChangedHandler(UpdateListView);
InitializeComponent();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//The current settings are saved to a files.
IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
Stream stream = new FileStream("settings.bin", FileMode.Create, FileAccess.Write);
formatter.Serialize(stream, oSettings);
stream.Close();
oServer.StopServer();
}
//Starts the server
private void btStart_Click(object sender, EventArgs e)
{
bServerRunning = !bServerRunning;
if (bServerRunning)
{
oServer.StartServer();
btStart.Text = "Stop server";
}
else
{
oServer.StopServer();
btStart.Text = "Start server";
}
}
//Opens the settings form
private void btSettings_Click(object sender, EventArgs e)
{
SettingsForm form = new SettingsForm();
form.oSettings = oSettings;
form.oServer = oServer;
form.Show();
}
//Performs recording which is synchronized frame capture.
//The frames are downloaded from the clients and saved once recording is finished.
private void recordingWorker_DoWork(object sender, DoWorkEventArgs e)
{
oServer.ClearStoredFrames();
int nCaptured = 0;
BackgroundWorker worker = (BackgroundWorker)sender;
while (!worker.CancellationPending)
{
oServer.CaptureSynchronizedFrame();
nCaptured++;
SetStatusBarOnTimer("Captured frame " + (nCaptured).ToString() + ".", 5000);
}
}
private void recordingWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//After recording has been terminated it is time to begin saving the frames.
//Saving is downloading the frames from clients and saving them locally.
bSaving = true;
btRecord.Text = "Stop saving";
btRecord.Enabled = true;
savingWorker.RunWorkerAsync();
}
//Opens the live view window
private void OpenGLWorker_DoWork(object sender, DoWorkEventArgs e)
{
bLiveViewRunning = true;
oOpenGLWindow = new OpenGLWindow();
//The variables below are shared between this class and the OpenGLWindow.
lock (lAllVertices)
{
oOpenGLWindow.vertices = lAllVertices;
oOpenGLWindow.colors = lAllColors;
oOpenGLWindow.cameraPoses = lAllCameraPoses;
oOpenGLWindow.settings = oSettings;
}
oOpenGLWindow.Run();
}
private void OpenGLWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
bLiveViewRunning = false;
updateWorker.CancelAsync();
}
private void savingWorker_DoWork(object sender, DoWorkEventArgs e)
{
int nFrames = 0;
string outDir = "out" + "\\" + txtSeqName.Text + "\\";
DirectoryInfo di = Directory.CreateDirectory(outDir);
BackgroundWorker worker = (BackgroundWorker)sender;
//This loop is running till it is either cancelled (using the btRecord button), or till there are no more stored frames.
while (!worker.CancellationPending)
{
List<List<byte>> lFrameRGBAllDevices = new List<List<byte>>();
List<List<float>> lFrameVertsAllDevices = new List<List<float>>();
oServer.GetStoredFrame(lFrameRGBAllDevices, lFrameVertsAllDevices);
nFrames++;
int nVerticesTotal = 0;
for (int i = 0; i < lFrameRGBAllDevices.Count; i++)
{
nVerticesTotal += lFrameVertsAllDevices[i].Count;
}
//This indicates that there are no more stored frames.
if (nVerticesTotal == 0)
break;
List<byte> lFrameRGB = new List<byte>();
List<Single> lFrameVerts = new List<Single>();
SetStatusBarOnTimer("Saving frame " + (nFrames).ToString() + ".", 5000);
for (int i = 0; i < lFrameRGBAllDevices.Count; i++)
{
lFrameRGB.AddRange(lFrameRGBAllDevices[i]);
lFrameVerts.AddRange(lFrameVertsAllDevices[i]);
//This is ran if the frames from each client are to be placed in separate files.
if (!oSettings.bMergeScansForSave)
{
string outputFilename = outDir + "\\" + nFrames.ToString().PadLeft(5, '0') + i.ToString() + ".ply";
saveToPly(outputFilename, lFrameVertsAllDevices[i], lFrameRGBAllDevices[i]);
}
}
//This is ran if the frames from all clients are to be placed in a single file.
if (oSettings.bMergeScansForSave)
{
string outputFilename = outDir + "\\" + nFrames.ToString().PadLeft(5, '0') + ".ply";
saveToPly(outputFilename, lFrameVerts, lFrameRGB);
}
}
}
private void savingWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
oServer.ClearStoredFrames();
bSaving = false;
//If the live view window was open, we need to restart the UpdateWorker.
if (bLiveViewRunning)
RestartUpdateWorker();
btRecord.Enabled = true;
btRecord.Text = "Start recording";
btRefineCalib.Enabled = true;
btCalibrate.Enabled = true;
}
//Continually requests frames that will be displayed in the live view window.
private void updateWorker_DoWork(object sender, DoWorkEventArgs e)
{
List<List<byte>> lFramesRGB = new List<List<byte>>();
List<List<Single>> lFramesVerts = new List<List<Single>>();
BackgroundWorker worker = (BackgroundWorker)sender;
while (!worker.CancellationPending)
{
Thread.Sleep(1);
oServer.GetLatestFrame(lFramesRGB, lFramesVerts);
//Update the vertex and color lists that are common between this class and the OpenGLWindow.
lock (lAllVertices)
{
lAllVertices.Clear();
lAllColors.Clear();
lAllCameraPoses.Clear();
for (int i = 0; i < lFramesRGB.Count; i++)
{
lAllVertices.AddRange(lFramesVerts[i]);
lAllColors.AddRange(lFramesRGB[i]);
lAllCameraPoses.Add(oServer.lCameraPoses[i]);
}
}
//Notes the fact that a new frame was downloaded, this is used to estimate the FPS.
if (oOpenGLWindow != null)
oOpenGLWindow.CloudUpdateTick();
}
}
//Performs the ICP based pose refinement.
private void refineWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (oServer.bAllCalibrated == false)
{
SetStatusBarOnTimer("Not all of the devices are calibrated.", 5000);
return;
}
//Download a frame from each client.
List<List<float>> lAllFrameVertices = new List<List<float>>();
List<List<byte>> lAllFrameColors = new List<List<byte>>();
oServer.GetLatestFrame(lAllFrameColors, lAllFrameVertices);
//Initialize containers for the poses.
List<float[]> Rs = new List<float[]>();
List<float[]> Ts = new List<float[]>();
for (int i = 0; i < lAllFrameVertices.Count; i++)
{
float[] tempR = new float[9];
float[] tempT = new float[3];
for (int j = 0; j < 3; j++)
{
tempT[j] = 0;
tempR[j + j * 3] = 1;
}
Rs.Add(tempR);
Ts.Add(tempT);
}
//Use ICP to refine the sensor poses.
//This part is explained in more detail in our article (name on top of this file).
float error = 1;
float oldError = 1;
bool firstPass = true;
int iter = 0;
while (true)
{
if (iter > oSettings.nMaxNumRefineIters)
break;
error = 0;
for (int i = 0; i < lAllFrameVertices.Count; i++)
{
List<float> otherFramesVertices = new List<float>();
for (int j = 0; j < lAllFrameVertices.Count; j++)
{
if (j == i)
continue;
otherFramesVertices.AddRange(lAllFrameVertices[j]);
}
float[] verts1 = otherFramesVertices.ToArray();
float[] verts2 = lAllFrameVertices[i].ToArray();
IntPtr pVerts1 = Marshal.AllocHGlobal(otherFramesVertices.Count * sizeof(float));
IntPtr pVerts2 = Marshal.AllocHGlobal(lAllFrameVertices[i].Count * sizeof(float));
Marshal.Copy(verts1, 0, pVerts1, verts1.Length);
Marshal.Copy(verts2, 0, pVerts2, verts2.Length);
error += ICP(pVerts1, pVerts2, otherFramesVertices.Count / 3, lAllFrameVertices[i].Count / 3, Rs[i], Ts[i], oSettings.nNumICPIterations);
Marshal.Copy(pVerts2, verts2, 0, verts2.Length);
lAllFrameVertices[i].Clear();
lAllFrameVertices[i].AddRange(verts2);
}
if (firstPass)
{
firstPass = false;
}
else
{
if (Math.Abs(oldError - error) / error < 0.01)
break;
}
oldError = error;
iter++;
}
//Update the calibration data in client machines.
List<AffineTransform> worldTransforms = oServer.lWorldTransforms;
for (int i = 0; i < worldTransforms.Count; i++)
{
float[] tempT = new float[3];
float[,] tempR = new float[3, 3];
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
tempT[j] += Ts[i][k] * worldTransforms[i].R[k, j];
}
worldTransforms[i].t[j] += tempT[j];
}
for (int j = 0; j < 3; j++)
{
for (int k = 0; k < 3; k++)
{
for (int l = 0; l < 3; l++)
{
tempR[j, k] += Rs[i][l * 3 + j] * worldTransforms[i].R[l, k];
}
worldTransforms[i].R[j, k] = tempR[j, k];
}
}
}
oServer.lWorldTransforms = worldTransforms;
oServer.SendCalibrationData();
}
private void refineWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Re-enable all of the buttons after refinement.
btRefineCalib.Enabled = true;
btCalibrate.Enabled = true;
btRecord.Enabled = true;
}
//This is used for: starting/stopping the recording worker, stopping the saving worker
private void btRecord_Click(object sender, EventArgs e)
{
if (oServer.nClientCount < 1)
{
SetStatusBarOnTimer("At least one client needs to be connected for recording.", 5000);
return;
}
//If we are saving frames right now, this button stops saving.
if (bSaving)
{
btRecord.Enabled = false;
savingWorker.CancelAsync();
return;
}
bRecording = !bRecording;
if (bRecording)
{
//Stop the update worker to reduce the network usage (provides better synchronization).
updateWorker.CancelAsync();
recordingWorker.RunWorkerAsync();
btRecord.Text = "Stop recording";
btRefineCalib.Enabled = false;
btCalibrate.Enabled = false;
}
else
{
btRecord.Enabled = false;
recordingWorker.CancelAsync();
}
}
private void btCalibrate_Click(object sender, EventArgs e)
{
oServer.Calibrate();
}
private void btRefineCalib_Click(object sender, EventArgs e)
{
if (oServer.nClientCount < 2)
{
SetStatusBarOnTimer("To refine calibration you need at least 2 connected devices.", 5000);
return;
}
btRefineCalib.Enabled = false;
btCalibrate.Enabled = false;
btRecord.Enabled = false;
refineWorker.RunWorkerAsync();
}
private void saveToPly(string filename, List<Single> vertices, List<byte> colors)
{
int nVertices = vertices.Count / 3;
System.IO.StreamWriter file = new System.IO.StreamWriter(filename);
//PLY file header is written here.
file.WriteLine("ply\nformat ascii 1.0");
file.WriteLine("element vertex " + nVertices.ToString());
file.WriteLine("property float x\nproperty float y\nproperty float z\nproperty uchar red\nproperty uchar green\nproperty uchar blue\nend_header");
//Vertex and color data are written here.
for (int j = 0; j < vertices.Count / 3; j++)
{
string s = "";
for (int k = 0; k < 3; k++) s += vertices[j * 3 + k].ToString(CultureInfo.InvariantCulture) + " ";
for (int k = 0; k < 3; k++) s += colors[j * 3 + k].ToString(CultureInfo.InvariantCulture) + " ";
file.WriteLine(s);
}
file.Close();
}
void RestartUpdateWorker()
{
if (!updateWorker.IsBusy)
updateWorker.RunWorkerAsync();
}
private void btShowLive_Click(object sender, EventArgs e)
{
RestartUpdateWorker();
//Opens the live view window if it is not open yet.
if (!OpenGLWorker.IsBusy)
OpenGLWorker.RunWorkerAsync();
}
private void SetStatusBarOnTimer(string message, int milliseconds)
{
statusLabel.Text = message;
oStatusBarTimer.Stop();
oStatusBarTimer = new System.Timers.Timer();
oStatusBarTimer.Interval = milliseconds;
oStatusBarTimer.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e)
{
oStatusBarTimer.Stop();
statusLabel.Text = "";
};
oStatusBarTimer.Start();
}
//Updates the ListBox contaning the connected clients, called by events inside KinectServer.
private void UpdateListView(List<KinectSocket> socketList)
{
List<string> listBoxItems = new List<string>();
for (int i = 0; i < socketList.Count; i++)
listBoxItems.Add(socketList[i].sSocketState);
lClientListBox.DataSource = listBoxItems;
}
}
}
+138
View File
@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>155, 17</value>
</metadata>
<metadata name="recordingWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>435, 17</value>
</metadata>
<metadata name="OpenGLWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>579, 17</value>
</metadata>
<metadata name="savingWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>702, 19</value>
</metadata>
<metadata name="updateWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>828, 19</value>
</metadata>
<metadata name="refineWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>958, 19</value>
</metadata>
</root>
+560
View File
@@ -0,0 +1,560 @@
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
// License: MIT Software License See LICENSE.txt for the full license.
// If you use this software in your research, then please use the following citation:
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
// @INPROCEEDINGS{Kowalski15,
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
// booktitle={3D Vision (3DV), 2015 International Conference on},
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
// year={2015},
// }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Globalization;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Input;
enum ECameraMode
{
CAMERA_NONE, CAMERA_TRACK, CAMERA_DOLLY, CAMERA_ORBIT
}
namespace KinectServer
{
class OpenGLWindow : GameWindow
{
int PointCount;
int LineCount;
VertexC4ubV3f[] VBO;
float PointSize = 0.0f;
ECameraMode CameraMode = ECameraMode.CAMERA_NONE;
static float KEYBOARD_MOVE_SPEED = 0.01f;
static float MOUSE_ORBIT_SPEED = 0.30f; // 0 = SLOWEST, 1 = FASTEST
static float MOUSE_DOLLY_SPEED = 0.2f; // same as above...but much more sensitive
static float MOUSE_TRACK_SPEED = 0.003f; // same as above...but much more sensitive
float g_heading;
float g_pitch;
float dx = 0.0f;
float dy = 0.0f;
Vector2 MousePrevious = new Vector2();
Vector2 MouseCurrent = new Vector2();
float[] cameraPosition = new float[3];
float[] targetPosition = new float[3];
public List<float> vertices = new List<float>();
public List<byte> colors = new List<byte>();
public List<AffineTransform> cameraPoses = new List<AffineTransform>();
public KinectSettings settings = new KinectSettings();
DateTime tFPSUpdateTimer = DateTime.Now;
int nTickCounter = 0;
// this struct is used for drawing
struct VertexC4ubV3f
{
public byte R, G, B, A;
public Vector3 Position;
public static int SizeInBytes = 16;
}
uint VBOHandle;
/// <summary>Creates a 800x600 window with the specified title.</summary>
public OpenGLWindow()
: base(800, 600)
{
this.VSync = VSyncMode.Off;
MouseUp += new EventHandler<MouseButtonEventArgs>(OnMouseButtonUp);
MouseDown += new EventHandler<MouseButtonEventArgs>(OnMouseButtonDown);
MouseMove += new EventHandler<MouseMoveEventArgs>(OnMouseMove);
MouseWheel += new EventHandler<MouseWheelEventArgs>(OnMouseWheelChanged);
KeyDown += new EventHandler<KeyboardKeyEventArgs>(OnKeyDown);
cameraPosition[0] = 0;
cameraPosition[1] = 0;
cameraPosition[2] = 1.0f;
targetPosition[0] = 0;
targetPosition[1] = 0;
targetPosition[2] = 0;
}
public void CloudUpdateTick()
{
nTickCounter++;
}
void OnKeyDown(object sender, KeyboardKeyEventArgs e)
{
// e.Key
}
/// <summary>Load resources here.</summary>
/// <param name="e">Not used.</param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Version version = new Version(GL.GetString(StringName.Version).Substring(0, 3));
Version target = new Version(1, 5);
if (version < target)
{
throw new NotSupportedException(String.Format(
"OpenGL {0} is required (you only have {1}).", target, version));
}
GL.ClearColor(.1f, 0f, .1f, 0f);
GL.Enable(EnableCap.DepthTest);
// Setup parameters for Points
GL.PointSize(PointSize);
GL.Enable(EnableCap.PointSmooth);
GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest);
// Setup VBO state
GL.EnableClientState(EnableCap.ColorArray);
GL.EnableClientState(EnableCap.VertexArray);
GL.GenBuffers(1, out VBOHandle);
// Since there's only 1 VBO in the app, might aswell setup here.
GL.BindBuffer(BufferTarget.ArrayBuffer, VBOHandle);
GL.ColorPointer(4, ColorPointerType.UnsignedByte, VertexC4ubV3f.SizeInBytes, (IntPtr)0);
GL.VertexPointer(3, VertexPointerType.Float, VertexC4ubV3f.SizeInBytes, (IntPtr)(4 * sizeof(byte)));
PointCount = 0;
LineCount = 12;
VBO = new VertexC4ubV3f[PointCount + 2 * LineCount];
}
protected override void OnUnload(EventArgs e)
{
GL.DeleteBuffers(1, ref VBOHandle);
}
/// <summary>
/// Called when your window is resized. Set your viewport here. It is also
/// a good place to set up your projection matrix (which probably changes
/// along when the aspect ratio of your window).
/// </summary>
/// <param name="e">Contains information on the new Width and Size of the GameWindow.</param>
protected override void OnResize(EventArgs e)
{
GL.Viewport(0, 0, Width, Height);
GL.MatrixMode(MatrixMode.Projection);
Matrix4 p = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Width / (float)Height, 0.1f, 50.0f);
GL.LoadMatrix(ref p);
GL.MatrixMode(MatrixMode.Modelview);
Matrix4 mv = Matrix4.LookAt(Vector3.UnitZ, Vector3.Zero, Vector3.UnitY);
GL.LoadMatrix(ref mv);
}
void OnMouseWheelChanged(object sender, MouseWheelEventArgs e)
{
dy = e.Delta * MOUSE_DOLLY_SPEED;
cameraPosition[2] -= dy;
//if (cameraPosition[2] < 0)
// cameraPosition[2] = 0;
}
void OnMouseMove(object sender, MouseMoveEventArgs e)
{
MouseCurrent.X = e.Mouse.X;
MouseCurrent.Y = e.Mouse.Y;
// Now use mouse_delta to move the camera
switch (CameraMode)
{
case ECameraMode.CAMERA_TRACK:
dx = MouseCurrent.X - MousePrevious.X;
dx *= MOUSE_TRACK_SPEED;
dy = MouseCurrent.Y - MousePrevious.Y;
dy *= MOUSE_TRACK_SPEED;
cameraPosition[0] -= dx;
cameraPosition[1] += dy;
//targetPosition[0] -= dx;
//targetPosition[1] += dy;
break;
case ECameraMode.CAMERA_DOLLY:
dy = MouseCurrent.Y - MousePrevious.Y;
dy *= MOUSE_DOLLY_SPEED;
cameraPosition[2] -= dy;
// if (cameraPosition[2] < 0)
// cameraPosition[2] = 0;
break;
case ECameraMode.CAMERA_ORBIT:
dx = MouseCurrent.X - MousePrevious.X;
dx *= MOUSE_ORBIT_SPEED;
dy = MouseCurrent.Y - MousePrevious.Y;
dy *= MOUSE_ORBIT_SPEED;
g_heading += dx;
g_pitch += dy;
break;
}
MousePrevious.X = MouseCurrent.X;
MousePrevious.Y = MouseCurrent.Y;
}
void OnMouseButtonUp(object sender, MouseButtonEventArgs e)
{
CameraMode = ECameraMode.CAMERA_NONE;
}
void OnMouseButtonDown(object sender, MouseButtonEventArgs e)
{
switch (e.Button)
{
case MouseButton.Left:
CameraMode = ECameraMode.CAMERA_ORBIT;
break;
case MouseButton.Middle:
CameraMode = ECameraMode.CAMERA_DOLLY;
break;
case MouseButton.Right:
CameraMode = ECameraMode.CAMERA_TRACK;
break;
}
MousePrevious.X = Mouse.X;
MousePrevious.Y = Mouse.Y;
}
protected override void OnUpdateFrame(FrameEventArgs e)
{
if ((DateTime.Now - tFPSUpdateTimer).Seconds >= 1)
{
double FPS = nTickCounter / (DateTime.Now - tFPSUpdateTimer).TotalSeconds;
this.Title = "FPS: " + string.Format("{0:F}", FPS);
tFPSUpdateTimer = DateTime.Now;
nTickCounter = 0;
}
var keyboard = OpenTK.Input.Keyboard.GetState();
if (keyboard[Key.Escape])
{
Exit();
}
if (keyboard[Key.Plus])
{
PointSize += 0.1f;
GL.PointSize(PointSize);
}
if (keyboard[Key.Minus])
{
if (PointSize != 0)
PointSize -= 0.1f;
GL.PointSize(PointSize);
}
if (keyboard[Key.W])
cameraPosition[2] -= KEYBOARD_MOVE_SPEED;
if (keyboard[Key.A])
cameraPosition[0] -= KEYBOARD_MOVE_SPEED;
if (keyboard[Key.S])
cameraPosition[2] += KEYBOARD_MOVE_SPEED;
if (keyboard[Key.D])
cameraPosition[0] += KEYBOARD_MOVE_SPEED;
lock (vertices)
{
lock (settings)
{
PointCount = vertices.Count / 3;
//bounding box
LineCount = 12;
//markers
LineCount += settings.lMarkerPoses.Count * 3;
//cameras
LineCount += cameraPoses.Count * 3;
VBO = new VertexC4ubV3f[PointCount + 2 * LineCount];
for (int i = 0; i < PointCount; i++)
{
VBO[i].R = (byte)colors[i * 3];
VBO[i].G = (byte)colors[i * 3 + 1];
VBO[i].B = (byte)colors[i * 3 + 2];
VBO[i].A = 255;
VBO[i].Position.X = vertices[i * 3];
VBO[i].Position.Y = vertices[i * 3 + 1];
VBO[i].Position.Z = vertices[i * 3 + 2];
}
int iCurLineCount = 0;
iCurLineCount += AddBoundingBox(PointCount + 2 * iCurLineCount);
for (int i = 0; i < settings.lMarkerPoses.Count; i++)
{
iCurLineCount += AddMarker(PointCount + 2 * iCurLineCount, settings.lMarkerPoses[i].pose);
}
for (int i = 0; i < cameraPoses.Count; i++)
{
iCurLineCount += AddCamera(PointCount + 2 * iCurLineCount, cameraPoses[i]);
}
}
}
}
/// <summary>
/// Called when it is time to render the next frame. Add your rendering code here.
/// </summary>
/// <param name="e">Contains timing information.</param>
protected override void OnRenderFrame(FrameEventArgs e)
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.PushMatrix();
GL.MatrixMode(MatrixMode.Modelview);
GL.Translate(-cameraPosition[0], -cameraPosition[1], -cameraPosition[2]);
GL.Rotate(g_pitch, 1.0f, 0.0f, 0.0f);
GL.Rotate(g_heading, 0.0f, 1.0f, 0.0f);
// Tell OpenGL to discard old VBO when done drawing it and reserve memory _now_ for a new buffer.
// without this, GL would wait until draw operations on old VBO are complete before writing to it
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(VertexC4ubV3f.SizeInBytes * (PointCount + 2 * LineCount)), IntPtr.Zero, BufferUsageHint.StreamDraw);
// Fill newly allocated buffer
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(VertexC4ubV3f.SizeInBytes * (PointCount + 2 * LineCount)), VBO, BufferUsageHint.StreamDraw);
GL.DrawArrays(BeginMode.Points, 0, PointCount);
GL.DrawArrays(BeginMode.Lines, PointCount, 2 * LineCount);
GL.PopMatrix();
SwapBuffers();
}
private int AddBoundingBox(int startIdx)
{
int nLinesBeingAdded = 12;
//2 points per line
int nPointsToAdd = 2 * nLinesBeingAdded;
for (int i = startIdx; i < startIdx + nPointsToAdd; i++)
{
VBO[i].R = 255;
VBO[i].G = 255;
VBO[i].B = 0;
VBO[i].A = 0;
}
int n = 0;
//bottom vertices
//first vertex
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMinBounds[2]);
n += 2;
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2]);
n += 2;
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
settings.aMinBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2]);
n += 2;
//second vertex
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2]);
n += 2;
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMinBounds[2],
settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2]);
n += 2;
//third vertex
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2],
settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2]);
n += 2;
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2],
settings.aMinBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2]);
n += 2;
//fourth vertex
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMinBounds[1], settings.aMaxBounds[2],
settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2]);
n += 2;
//top vertices
//fifth vertex
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2],
settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2]);
n += 2;
AddLine(startIdx + n, settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2],
settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2]);
n += 2;
//sixth vertex
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2],
settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMinBounds[2]);
n += 2;
AddLine(startIdx + n, settings.aMaxBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2],
settings.aMinBounds[0], settings.aMaxBounds[1], settings.aMaxBounds[2]);
n += 2;
return nLinesBeingAdded;
}
private int AddMarker(int startIdx, AffineTransform pose)
{
int nLinesBeingAdded = 3;
//2 points per line
int nPointsToAdd = 2 * nLinesBeingAdded;
for (int i = startIdx; i < startIdx + nPointsToAdd; i++)
{
VBO[i].R = 255;
VBO[i].G = 0;
VBO[i].B = 0;
VBO[i].A = 0;
}
int n = 0;
float x0 = pose.t[0];
float y0 = pose.t[1];
float z0 = pose.t[2];
float x1 = 0.1f;
float y1 = 0.1f;
float z1 = 0.1f;
float x2 = pose.R[0, 0] * x1;
float y2 = pose.R[1, 0] * x1;
float z2 = pose.R[2, 0] * x1;
x2 += pose.t[0];
y2 += pose.t[1];
z2 += pose.t[2];
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
n += 2;
x2 = pose.R[0, 1] * y1;
y2 = pose.R[1, 1] * y1;
z2 = pose.R[2, 1] * y1;
x2 += pose.t[0];
y2 += pose.t[1];
z2 += pose.t[2];
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
n += 2;
x2 = pose.R[0, 2] * z1;
y2 = pose.R[1, 2] * z1;
z2 = pose.R[2, 2] * z1;
x2 += pose.t[0];
y2 += pose.t[1];
z2 += pose.t[2];
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
n += 2;
return nLinesBeingAdded;
}
private int AddCamera(int startIdx, AffineTransform pose)
{
int nLinesBeingAdded = 3;
//2 points per line
int nPointsToAdd = 2 * nLinesBeingAdded;
for (int i = startIdx; i < startIdx + nPointsToAdd; i++)
{
VBO[i].R = 0;
VBO[i].G = 255;
VBO[i].B = 0;
VBO[i].A = 0;
}
int n = 0;
float x0 = pose.t[0];
float y0 = pose.t[1];
float z0 = pose.t[2];
float x1 = 0.1f;
float y1 = 0.1f;
float z1 = 0.1f;
float x2 = pose.R[0, 0] * x1;
float y2 = pose.R[1, 0] * x1;
float z2 = pose.R[2, 0] * x1;
x2 += pose.t[0];
y2 += pose.t[1];
z2 += pose.t[2];
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
n += 2;
x2 = pose.R[0, 1] * y1;
y2 = pose.R[1, 1] * y1;
z2 = pose.R[2, 1] * y1;
x2 += pose.t[0];
y2 += pose.t[1];
z2 += pose.t[2];
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
n += 2;
x2 = pose.R[0, 2] * z1;
y2 = pose.R[1, 2] * z1;
z2 = pose.R[2, 2] * z1;
x2 += pose.t[0];
y2 += pose.t[1];
z2 += pose.t[2];
AddLine(startIdx + n, x0, y0, z0, x2, y2, z2);
n += 2;
return nLinesBeingAdded;
}
private void AddLine(int startIdx, float x0, float y0, float z0,
float x1, float y1, float z1)
{
VBO[startIdx].Position.X = x0;
VBO[startIdx].Position.Y = y0;
VBO[startIdx].Position.Z = z0;
VBO[startIdx + 1].Position.X = x1;
VBO[startIdx + 1].Position.Y = y1;
VBO[startIdx + 1].Position.Z = z1;
}
}
}
+22
View File
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace KinectServer
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainWindowForm());
}
}
}
+36
View File
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("KinectServer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("KinectServer")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c781e249-f1ed-41af-89ab-4dbc1dde8bfd")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
+71
View File
@@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34014
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace KinectServer.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("KinectServer.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}
+117
View File
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+30
View File
@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34014
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace KinectServer.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}
@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
+569
View File
@@ -0,0 +1,569 @@
namespace KinectServer
{
partial class SettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lbMerge = new System.Windows.Forms.Label();
this.chMerge = new System.Windows.Forms.CheckBox();
this.lbICPIters = new System.Windows.Forms.Label();
this.txtICPIters = new System.Windows.Forms.TextBox();
this.grClient = new System.Windows.Forms.GroupBox();
this.grMarkers = new System.Windows.Forms.GroupBox();
this.lbX2 = new System.Windows.Forms.Label();
this.btRemove = new System.Windows.Forms.Button();
this.txtOrientationZ = new System.Windows.Forms.TextBox();
this.txtId = new System.Windows.Forms.TextBox();
this.lbY2 = new System.Windows.Forms.Label();
this.txtOrientationY = new System.Windows.Forms.TextBox();
this.lbId = new System.Windows.Forms.Label();
this.lbZ2 = new System.Windows.Forms.Label();
this.txtOrientationX = new System.Windows.Forms.TextBox();
this.btAdd = new System.Windows.Forms.Button();
this.lbTranslation = new System.Windows.Forms.Label();
this.lbOrientation = new System.Windows.Forms.Label();
this.txtTranslationZ = new System.Windows.Forms.TextBox();
this.txtTranslationX = new System.Windows.Forms.TextBox();
this.lisMarkers = new System.Windows.Forms.ListBox();
this.txtTranslationY = new System.Windows.Forms.TextBox();
this.grBounding = new System.Windows.Forms.GroupBox();
this.lbMin = new System.Windows.Forms.Label();
this.txtMaxZ = new System.Windows.Forms.TextBox();
this.txtMaxY = new System.Windows.Forms.TextBox();
this.txtMinX = new System.Windows.Forms.TextBox();
this.txtMaxX = new System.Windows.Forms.TextBox();
this.txtMinY = new System.Windows.Forms.TextBox();
this.lbMax = new System.Windows.Forms.Label();
this.txtMinZ = new System.Windows.Forms.TextBox();
this.lbZ = new System.Windows.Forms.Label();
this.lbY = new System.Windows.Forms.Label();
this.lbX = new System.Windows.Forms.Label();
this.grFiltering = new System.Windows.Forms.GroupBox();
this.txtFilterNeighbors = new System.Windows.Forms.TextBox();
this.chFilter = new System.Windows.Forms.CheckBox();
this.lbFilterNeighbors = new System.Windows.Forms.Label();
this.lbFilterDistance = new System.Windows.Forms.Label();
this.txtFilterDistance = new System.Windows.Forms.TextBox();
this.grServer = new System.Windows.Forms.GroupBox();
this.txtRefinIters = new System.Windows.Forms.TextBox();
this.lbOuterIters = new System.Windows.Forms.Label();
this.grClient.SuspendLayout();
this.grMarkers.SuspendLayout();
this.grBounding.SuspendLayout();
this.grFiltering.SuspendLayout();
this.grServer.SuspendLayout();
this.SuspendLayout();
//
// lbMerge
//
this.lbMerge.AutoSize = true;
this.lbMerge.Location = new System.Drawing.Point(6, 49);
this.lbMerge.Name = "lbMerge";
this.lbMerge.Size = new System.Drawing.Size(69, 13);
this.lbMerge.TabIndex = 22;
this.lbMerge.Text = "Scan saving:";
//
// chMerge
//
this.chMerge.AutoSize = true;
this.chMerge.Location = new System.Drawing.Point(91, 48);
this.chMerge.Name = "chMerge";
this.chMerge.Size = new System.Drawing.Size(86, 17);
this.chMerge.TabIndex = 23;
this.chMerge.Text = "merge scans";
this.chMerge.UseVisualStyleBackColor = true;
this.chMerge.CheckedChanged += new System.EventHandler(this.chMerge_CheckedChanged);
//
// lbICPIters
//
this.lbICPIters.AutoSize = true;
this.lbICPIters.Location = new System.Drawing.Point(6, 26);
this.lbICPIters.Name = "lbICPIters";
this.lbICPIters.Size = new System.Drawing.Size(86, 13);
this.lbICPIters.TabIndex = 24;
this.lbICPIters.Text = "Num of ICP iters:";
//
// txtICPIters
//
this.txtICPIters.Location = new System.Drawing.Point(91, 23);
this.txtICPIters.Name = "txtICPIters";
this.txtICPIters.Size = new System.Drawing.Size(38, 20);
this.txtICPIters.TabIndex = 25;
this.txtICPIters.TextChanged += new System.EventHandler(this.txtICPIters_TextChanged);
//
// grClient
//
this.grClient.Controls.Add(this.grMarkers);
this.grClient.Controls.Add(this.grBounding);
this.grClient.Controls.Add(this.grFiltering);
this.grClient.Location = new System.Drawing.Point(12, 12);
this.grClient.Name = "grClient";
this.grClient.Size = new System.Drawing.Size(632, 212);
this.grClient.TabIndex = 43;
this.grClient.TabStop = false;
this.grClient.Text = "KinectClient settings";
//
// grMarkers
//
this.grMarkers.Controls.Add(this.lbX2);
this.grMarkers.Controls.Add(this.btRemove);
this.grMarkers.Controls.Add(this.txtOrientationZ);
this.grMarkers.Controls.Add(this.txtId);
this.grMarkers.Controls.Add(this.lbY2);
this.grMarkers.Controls.Add(this.txtOrientationY);
this.grMarkers.Controls.Add(this.lbId);
this.grMarkers.Controls.Add(this.lbZ2);
this.grMarkers.Controls.Add(this.txtOrientationX);
this.grMarkers.Controls.Add(this.btAdd);
this.grMarkers.Controls.Add(this.lbTranslation);
this.grMarkers.Controls.Add(this.lbOrientation);
this.grMarkers.Controls.Add(this.txtTranslationZ);
this.grMarkers.Controls.Add(this.txtTranslationX);
this.grMarkers.Controls.Add(this.lisMarkers);
this.grMarkers.Controls.Add(this.txtTranslationY);
this.grMarkers.Location = new System.Drawing.Point(271, 19);
this.grMarkers.Name = "grMarkers";
this.grMarkers.Size = new System.Drawing.Size(353, 185);
this.grMarkers.TabIndex = 45;
this.grMarkers.TabStop = false;
this.grMarkers.Text = "Calibration markers";
//
// lbX2
//
this.lbX2.AutoSize = true;
this.lbX2.Location = new System.Drawing.Point(230, 19);
this.lbX2.Name = "lbX2";
this.lbX2.Size = new System.Drawing.Size(14, 13);
this.lbX2.TabIndex = 49;
this.lbX2.Text = "X";
//
// btRemove
//
this.btRemove.Location = new System.Drawing.Point(233, 127);
this.btRemove.Name = "btRemove";
this.btRemove.Size = new System.Drawing.Size(92, 23);
this.btRemove.TabIndex = 59;
this.btRemove.Text = "Remove marker";
this.btRemove.UseVisualStyleBackColor = true;
this.btRemove.Click += new System.EventHandler(this.btRemove_Click);
//
// txtOrientationZ
//
this.txtOrientationZ.Location = new System.Drawing.Point(305, 38);
this.txtOrientationZ.Name = "txtOrientationZ";
this.txtOrientationZ.Size = new System.Drawing.Size(38, 20);
this.txtOrientationZ.TabIndex = 48;
this.txtOrientationZ.TextChanged += new System.EventHandler(this.txtOrientationZ_TextChanged);
//
// txtId
//
this.txtId.Location = new System.Drawing.Point(217, 93);
this.txtId.Name = "txtId";
this.txtId.Size = new System.Drawing.Size(38, 20);
this.txtId.TabIndex = 58;
this.txtId.TextChanged += new System.EventHandler(this.txtId_TextChanged);
//
// lbY2
//
this.lbY2.AutoSize = true;
this.lbY2.Location = new System.Drawing.Point(274, 19);
this.lbY2.Name = "lbY2";
this.lbY2.Size = new System.Drawing.Size(14, 13);
this.lbY2.TabIndex = 50;
this.lbY2.Text = "Y";
//
// txtOrientationY
//
this.txtOrientationY.Location = new System.Drawing.Point(261, 38);
this.txtOrientationY.Name = "txtOrientationY";
this.txtOrientationY.Size = new System.Drawing.Size(38, 20);
this.txtOrientationY.TabIndex = 47;
this.txtOrientationY.TextChanged += new System.EventHandler(this.txtOrientationY_TextChanged);
//
// lbId
//
this.lbId.AutoSize = true;
this.lbId.Location = new System.Drawing.Point(132, 96);
this.lbId.Name = "lbId";
this.lbId.Size = new System.Drawing.Size(54, 13);
this.lbId.TabIndex = 57;
this.lbId.Text = "Marker id:";
//
// lbZ2
//
this.lbZ2.AutoSize = true;
this.lbZ2.Location = new System.Drawing.Point(317, 19);
this.lbZ2.Name = "lbZ2";
this.lbZ2.Size = new System.Drawing.Size(14, 13);
this.lbZ2.TabIndex = 51;
this.lbZ2.Text = "Z";
//
// txtOrientationX
//
this.txtOrientationX.Location = new System.Drawing.Point(217, 38);
this.txtOrientationX.Name = "txtOrientationX";
this.txtOrientationX.Size = new System.Drawing.Size(38, 20);
this.txtOrientationX.TabIndex = 46;
this.txtOrientationX.TextChanged += new System.EventHandler(this.txtOrientationX_TextChanged);
//
// btAdd
//
this.btAdd.Location = new System.Drawing.Point(135, 127);
this.btAdd.Name = "btAdd";
this.btAdd.Size = new System.Drawing.Size(92, 23);
this.btAdd.TabIndex = 56;
this.btAdd.Text = "Add marker";
this.btAdd.UseVisualStyleBackColor = true;
this.btAdd.Click += new System.EventHandler(this.btAdd_Click);
//
// lbTranslation
//
this.lbTranslation.AutoSize = true;
this.lbTranslation.Location = new System.Drawing.Point(132, 68);
this.lbTranslation.Name = "lbTranslation";
this.lbTranslation.Size = new System.Drawing.Size(62, 13);
this.lbTranslation.TabIndex = 52;
this.lbTranslation.Text = "Translation:";
//
// lbOrientation
//
this.lbOrientation.AutoSize = true;
this.lbOrientation.Location = new System.Drawing.Point(132, 41);
this.lbOrientation.Name = "lbOrientation";
this.lbOrientation.Size = new System.Drawing.Size(61, 13);
this.lbOrientation.TabIndex = 45;
this.lbOrientation.Text = "Orientation:";
//
// txtTranslationZ
//
this.txtTranslationZ.Location = new System.Drawing.Point(305, 65);
this.txtTranslationZ.Name = "txtTranslationZ";
this.txtTranslationZ.Size = new System.Drawing.Size(38, 20);
this.txtTranslationZ.TabIndex = 55;
this.txtTranslationZ.TextChanged += new System.EventHandler(this.txtTranslationZ_TextChanged);
//
// txtTranslationX
//
this.txtTranslationX.Location = new System.Drawing.Point(217, 65);
this.txtTranslationX.Name = "txtTranslationX";
this.txtTranslationX.Size = new System.Drawing.Size(38, 20);
this.txtTranslationX.TabIndex = 53;
this.txtTranslationX.TextChanged += new System.EventHandler(this.txtTranslationX_TextChanged);
//
// lisMarkers
//
this.lisMarkers.FormattingEnabled = true;
this.lisMarkers.Location = new System.Drawing.Point(6, 41);
this.lisMarkers.Name = "lisMarkers";
this.lisMarkers.Size = new System.Drawing.Size(120, 108);
this.lisMarkers.TabIndex = 43;
//
// txtTranslationY
//
this.txtTranslationY.Location = new System.Drawing.Point(261, 65);
this.txtTranslationY.Name = "txtTranslationY";
this.txtTranslationY.Size = new System.Drawing.Size(38, 20);
this.txtTranslationY.TabIndex = 54;
this.txtTranslationY.TextChanged += new System.EventHandler(this.txtTranslationY_TextChanged);
//
// grBounding
//
this.grBounding.Controls.Add(this.lbMin);
this.grBounding.Controls.Add(this.txtMaxZ);
this.grBounding.Controls.Add(this.txtMaxY);
this.grBounding.Controls.Add(this.txtMinX);
this.grBounding.Controls.Add(this.txtMaxX);
this.grBounding.Controls.Add(this.txtMinY);
this.grBounding.Controls.Add(this.lbMax);
this.grBounding.Controls.Add(this.txtMinZ);
this.grBounding.Controls.Add(this.lbZ);
this.grBounding.Controls.Add(this.lbY);
this.grBounding.Controls.Add(this.lbX);
this.grBounding.Location = new System.Drawing.Point(9, 19);
this.grBounding.Name = "grBounding";
this.grBounding.Size = new System.Drawing.Size(249, 91);
this.grBounding.TabIndex = 46;
this.grBounding.TabStop = false;
this.grBounding.Text = "Bounding box";
//
// lbMin
//
this.lbMin.AutoSize = true;
this.lbMin.Location = new System.Drawing.Point(8, 38);
this.lbMin.Name = "lbMin";
this.lbMin.Size = new System.Drawing.Size(65, 13);
this.lbMin.TabIndex = 13;
this.lbMin.Text = "Min bounds:";
//
// txtMaxZ
//
this.txtMaxZ.Location = new System.Drawing.Point(181, 62);
this.txtMaxZ.Name = "txtMaxZ";
this.txtMaxZ.Size = new System.Drawing.Size(38, 20);
this.txtMaxZ.TabIndex = 23;
this.txtMaxZ.TextChanged += new System.EventHandler(this.txtMaxZ_TextChanged);
//
// txtMaxY
//
this.txtMaxY.Location = new System.Drawing.Point(137, 62);
this.txtMaxY.Name = "txtMaxY";
this.txtMaxY.Size = new System.Drawing.Size(38, 20);
this.txtMaxY.TabIndex = 22;
this.txtMaxY.TextChanged += new System.EventHandler(this.txtMaxY_TextChanged);
//
// txtMinX
//
this.txtMinX.Location = new System.Drawing.Point(93, 35);
this.txtMinX.Name = "txtMinX";
this.txtMinX.Size = new System.Drawing.Size(38, 20);
this.txtMinX.TabIndex = 14;
this.txtMinX.TextChanged += new System.EventHandler(this.txtMinX_TextChanged);
//
// txtMaxX
//
this.txtMaxX.Location = new System.Drawing.Point(93, 62);
this.txtMaxX.Name = "txtMaxX";
this.txtMaxX.Size = new System.Drawing.Size(38, 20);
this.txtMaxX.TabIndex = 21;
this.txtMaxX.TextChanged += new System.EventHandler(this.txtMaxX_TextChanged);
//
// txtMinY
//
this.txtMinY.Location = new System.Drawing.Point(137, 35);
this.txtMinY.Name = "txtMinY";
this.txtMinY.Size = new System.Drawing.Size(38, 20);
this.txtMinY.TabIndex = 15;
this.txtMinY.TextChanged += new System.EventHandler(this.txtMinY_TextChanged);
//
// lbMax
//
this.lbMax.AutoSize = true;
this.lbMax.Location = new System.Drawing.Point(8, 65);
this.lbMax.Name = "lbMax";
this.lbMax.Size = new System.Drawing.Size(68, 13);
this.lbMax.TabIndex = 20;
this.lbMax.Text = "Max bounds:";
//
// txtMinZ
//
this.txtMinZ.Location = new System.Drawing.Point(181, 35);
this.txtMinZ.Name = "txtMinZ";
this.txtMinZ.Size = new System.Drawing.Size(38, 20);
this.txtMinZ.TabIndex = 16;
this.txtMinZ.TextChanged += new System.EventHandler(this.txtMinZ_TextChanged);
//
// lbZ
//
this.lbZ.AutoSize = true;
this.lbZ.Location = new System.Drawing.Point(193, 16);
this.lbZ.Name = "lbZ";
this.lbZ.Size = new System.Drawing.Size(14, 13);
this.lbZ.TabIndex = 19;
this.lbZ.Text = "Z";
//
// lbY
//
this.lbY.AutoSize = true;
this.lbY.Location = new System.Drawing.Point(150, 16);
this.lbY.Name = "lbY";
this.lbY.Size = new System.Drawing.Size(14, 13);
this.lbY.TabIndex = 18;
this.lbY.Text = "Y";
//
// lbX
//
this.lbX.AutoSize = true;
this.lbX.Location = new System.Drawing.Point(106, 16);
this.lbX.Name = "lbX";
this.lbX.Size = new System.Drawing.Size(14, 13);
this.lbX.TabIndex = 17;
this.lbX.Text = "X";
//
// grFiltering
//
this.grFiltering.Controls.Add(this.txtFilterNeighbors);
this.grFiltering.Controls.Add(this.chFilter);
this.grFiltering.Controls.Add(this.lbFilterNeighbors);
this.grFiltering.Controls.Add(this.lbFilterDistance);
this.grFiltering.Controls.Add(this.txtFilterDistance);
this.grFiltering.Location = new System.Drawing.Point(9, 116);
this.grFiltering.Name = "grFiltering";
this.grFiltering.Size = new System.Drawing.Size(249, 88);
this.grFiltering.TabIndex = 45;
this.grFiltering.TabStop = false;
this.grFiltering.Text = "Filtering";
//
// txtFilterNeighbors
//
this.txtFilterNeighbors.Location = new System.Drawing.Point(93, 39);
this.txtFilterNeighbors.Name = "txtFilterNeighbors";
this.txtFilterNeighbors.Size = new System.Drawing.Size(38, 20);
this.txtFilterNeighbors.TabIndex = 20;
this.txtFilterNeighbors.TextChanged += new System.EventHandler(this.txtFilterNeighbors_TextChanged);
//
// chFilter
//
this.chFilter.AutoSize = true;
this.chFilter.Location = new System.Drawing.Point(93, 16);
this.chFilter.Name = "chFilter";
this.chFilter.Size = new System.Drawing.Size(100, 17);
this.chFilter.TabIndex = 18;
this.chFilter.Text = "filtering enabled";
this.chFilter.UseVisualStyleBackColor = true;
this.chFilter.CheckedChanged += new System.EventHandler(this.chFilter_CheckedChanged);
//
// lbFilterNeighbors
//
this.lbFilterNeighbors.AutoSize = true;
this.lbFilterNeighbors.Location = new System.Drawing.Point(8, 42);
this.lbFilterNeighbors.Name = "lbFilterNeighbors";
this.lbFilterNeighbors.Size = new System.Drawing.Size(67, 13);
this.lbFilterNeighbors.TabIndex = 19;
this.lbFilterNeighbors.Text = "N neighbors:";
//
// lbFilterDistance
//
this.lbFilterDistance.AutoSize = true;
this.lbFilterDistance.Location = new System.Drawing.Point(8, 68);
this.lbFilterDistance.Name = "lbFilterDistance";
this.lbFilterDistance.Size = new System.Drawing.Size(73, 13);
this.lbFilterDistance.TabIndex = 21;
this.lbFilterDistance.Text = "Max distance:";
//
// txtFilterDistance
//
this.txtFilterDistance.Location = new System.Drawing.Point(93, 65);
this.txtFilterDistance.Name = "txtFilterDistance";
this.txtFilterDistance.Size = new System.Drawing.Size(38, 20);
this.txtFilterDistance.TabIndex = 22;
this.txtFilterDistance.TextChanged += new System.EventHandler(this.txtFilterDistance_TextChanged);
//
// grServer
//
this.grServer.Controls.Add(this.txtRefinIters);
this.grServer.Controls.Add(this.lbOuterIters);
this.grServer.Controls.Add(this.lbMerge);
this.grServer.Controls.Add(this.txtICPIters);
this.grServer.Controls.Add(this.chMerge);
this.grServer.Controls.Add(this.lbICPIters);
this.grServer.Location = new System.Drawing.Point(12, 230);
this.grServer.Name = "grServer";
this.grServer.Size = new System.Drawing.Size(632, 78);
this.grServer.TabIndex = 44;
this.grServer.TabStop = false;
this.grServer.Text = "KinectServer settings";
//
// txtRefinIters
//
this.txtRefinIters.Location = new System.Drawing.Point(271, 23);
this.txtRefinIters.Name = "txtRefinIters";
this.txtRefinIters.Size = new System.Drawing.Size(38, 20);
this.txtRefinIters.TabIndex = 27;
this.txtRefinIters.TextChanged += new System.EventHandler(this.txtRefinIters_TextChanged);
//
// lbOuterIters
//
this.lbOuterIters.AutoSize = true;
this.lbOuterIters.Location = new System.Drawing.Point(135, 26);
this.lbOuterIters.Name = "lbOuterIters";
this.lbOuterIters.Size = new System.Drawing.Size(139, 13);
this.lbOuterIters.TabIndex = 26;
this.lbOuterIters.Text = "Max num of refinement iters:";
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(656, 319);
this.Controls.Add(this.grServer);
this.Controls.Add(this.grClient);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "SettingsForm";
this.Text = "Settings";
this.Load += new System.EventHandler(this.SettingsForm_Load);
this.grClient.ResumeLayout(false);
this.grMarkers.ResumeLayout(false);
this.grMarkers.PerformLayout();
this.grBounding.ResumeLayout(false);
this.grBounding.PerformLayout();
this.grFiltering.ResumeLayout(false);
this.grFiltering.PerformLayout();
this.grServer.ResumeLayout(false);
this.grServer.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label lbMerge;
private System.Windows.Forms.CheckBox chMerge;
private System.Windows.Forms.Label lbICPIters;
private System.Windows.Forms.TextBox txtICPIters;
private System.Windows.Forms.GroupBox grClient;
private System.Windows.Forms.GroupBox grServer;
private System.Windows.Forms.TextBox txtRefinIters;
private System.Windows.Forms.Label lbOuterIters;
private System.Windows.Forms.GroupBox grFiltering;
private System.Windows.Forms.TextBox txtFilterNeighbors;
private System.Windows.Forms.CheckBox chFilter;
private System.Windows.Forms.Label lbFilterNeighbors;
private System.Windows.Forms.Label lbFilterDistance;
private System.Windows.Forms.TextBox txtFilterDistance;
private System.Windows.Forms.GroupBox grMarkers;
private System.Windows.Forms.Label lbX2;
private System.Windows.Forms.Button btRemove;
private System.Windows.Forms.TextBox txtOrientationZ;
private System.Windows.Forms.TextBox txtId;
private System.Windows.Forms.Label lbY2;
private System.Windows.Forms.TextBox txtOrientationY;
private System.Windows.Forms.Label lbId;
private System.Windows.Forms.Label lbZ2;
private System.Windows.Forms.TextBox txtOrientationX;
private System.Windows.Forms.Button btAdd;
private System.Windows.Forms.Label lbTranslation;
private System.Windows.Forms.Label lbOrientation;
private System.Windows.Forms.TextBox txtTranslationZ;
private System.Windows.Forms.TextBox txtTranslationX;
private System.Windows.Forms.ListBox lisMarkers;
private System.Windows.Forms.TextBox txtTranslationY;
private System.Windows.Forms.GroupBox grBounding;
private System.Windows.Forms.Label lbMin;
private System.Windows.Forms.TextBox txtMaxZ;
private System.Windows.Forms.TextBox txtMaxY;
private System.Windows.Forms.TextBox txtMinX;
private System.Windows.Forms.TextBox txtMaxX;
private System.Windows.Forms.TextBox txtMinY;
private System.Windows.Forms.Label lbMax;
private System.Windows.Forms.TextBox txtMinZ;
private System.Windows.Forms.Label lbZ;
private System.Windows.Forms.Label lbY;
private System.Windows.Forms.Label lbX;
}
}
+285
View File
@@ -0,0 +1,285 @@
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
// License: MIT Software License See LICENSE.txt for the full license.
// If you use this software in your research, then please use the following citation:
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
// @INPROCEEDINGS{Kowalski15,
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
// booktitle={3D Vision (3DV), 2015 International Conference on},
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
// year={2015},
// }
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Globalization;
namespace KinectServer
{
public partial class SettingsForm : Form
{
public KinectSettings oSettings;
public KinectServer oServer;
public SettingsForm()
{
InitializeComponent();
}
private void SettingsForm_Load(object sender, EventArgs e)
{
txtMinX.Text = oSettings.aMinBounds[0].ToString(CultureInfo.InvariantCulture);
txtMinY.Text = oSettings.aMinBounds[1].ToString(CultureInfo.InvariantCulture);
txtMinZ.Text = oSettings.aMinBounds[2].ToString(CultureInfo.InvariantCulture);
txtMaxX.Text = oSettings.aMaxBounds[0].ToString(CultureInfo.InvariantCulture);
txtMaxY.Text = oSettings.aMaxBounds[1].ToString(CultureInfo.InvariantCulture);
txtMaxZ.Text = oSettings.aMaxBounds[2].ToString(CultureInfo.InvariantCulture);
chFilter.Checked = oSettings.bFilter;
txtFilterNeighbors.Text = oSettings.nFilterNeighbors.ToString();
txtFilterDistance.Text = oSettings.fFilterThreshold.ToString(CultureInfo.InvariantCulture);
lisMarkers.DataSource = oSettings.lMarkerPoses;
chMerge.Checked = oSettings.bMergeScansForSave;
txtICPIters.Text = oSettings.nNumICPIterations.ToString();
txtRefinIters.Text = oSettings.nMaxNumRefineIters.ToString();
}
void UpdateClients()
{
oServer.SendSettings();
}
void UpdateMarkerFields()
{
if (lisMarkers.SelectedIndex >= 0)
{
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
float X, Y, Z;
pose.GetOrientation(out X, out Y, out Z);
txtOrientationX.Text = X.ToString(CultureInfo.InvariantCulture);
txtOrientationY.Text = Y.ToString(CultureInfo.InvariantCulture);
txtOrientationZ.Text = Z.ToString(CultureInfo.InvariantCulture);
txtTranslationX.Text = pose.pose.t[0].ToString(CultureInfo.InvariantCulture);
txtTranslationY.Text = pose.pose.t[1].ToString(CultureInfo.InvariantCulture);
txtTranslationZ.Text = pose.pose.t[2].ToString(CultureInfo.InvariantCulture);
txtId.Text = pose.id.ToString(CultureInfo.InvariantCulture);
}
else
{
txtOrientationX.Text = "";
txtOrientationY.Text = "";
txtOrientationZ.Text = "";
txtTranslationX.Text = "";
txtTranslationY.Text = "";
txtTranslationZ.Text = "";
txtId.Text = "";
}
}
private void txtMinX_TextChanged(object sender, EventArgs e)
{
Single.TryParse(txtMinX.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMinBounds[0]);
UpdateClients();
}
private void txtMinY_TextChanged(object sender, EventArgs e)
{
Single.TryParse(txtMinY.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMinBounds[1]);
UpdateClients();
}
private void txtMinZ_TextChanged(object sender, EventArgs e)
{
Single.TryParse(txtMinZ.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMinBounds[2]);
UpdateClients();
}
private void txtMaxX_TextChanged(object sender, EventArgs e)
{
Single.TryParse(txtMaxX.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMaxBounds[0]);
UpdateClients();
}
private void txtMaxY_TextChanged(object sender, EventArgs e)
{
Single.TryParse(txtMaxY.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMaxBounds[1]);
UpdateClients();
}
private void txtMaxZ_TextChanged(object sender, EventArgs e)
{
Single.TryParse(txtMaxZ.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.aMaxBounds[2]);
UpdateClients();
}
private void chFilter_CheckedChanged(object sender, EventArgs e)
{
oSettings.bFilter = chFilter.Checked;
UpdateClients();
}
private void txtFilterNeighbors_TextChanged(object sender, EventArgs e)
{
Int32.TryParse(txtFilterNeighbors.Text, out oSettings.nFilterNeighbors);
UpdateClients();
}
private void txtFilterDistance_TextChanged(object sender, EventArgs e)
{
Single.TryParse(txtFilterDistance.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out oSettings.fFilterThreshold);
UpdateClients();
}
private void txtICPIters_TextChanged(object sender, EventArgs e)
{
Int32.TryParse(txtICPIters.Text, out oSettings.nNumICPIterations);
}
private void txtRefinIters_TextChanged(object sender, EventArgs e)
{
Int32.TryParse(txtRefinIters.Text, out oSettings.nMaxNumRefineIters);
}
private void chMerge_CheckedChanged(object sender, EventArgs e)
{
oSettings.bMergeScansForSave = chMerge.Checked;
}
private void btAdd_Click(object sender, EventArgs e)
{
lock (oSettings)
oSettings.lMarkerPoses.Add(new MarkerPose());
lisMarkers.SelectedIndex = oSettings.lMarkerPoses.Count - 1;
UpdateMarkerFields();
UpdateClients();
}
private void btRemove_Click(object sender, EventArgs e)
{
if (oSettings.lMarkerPoses.Count > 0)
{
oSettings.lMarkerPoses.RemoveAt(lisMarkers.SelectedIndex);
lisMarkers.SelectedIndex = oSettings.lMarkerPoses.Count - 1;
UpdateMarkerFields();
UpdateClients();
}
}
private void lisMarkers_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateMarkerFields();
}
private void txtOrientationX_TextChanged(object sender, EventArgs e)
{
if (lisMarkers.SelectedIndex >= 0)
{
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
float X, Y, Z;
pose.GetOrientation(out X, out Y, out Z);
Single.TryParse(txtOrientationX.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out X);
pose.SetOrientation(X, Y, Z);
UpdateClients();
}
}
private void txtOrientationY_TextChanged(object sender, EventArgs e)
{
if (lisMarkers.SelectedIndex >= 0)
{
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
float X, Y, Z;
pose.GetOrientation(out X, out Y, out Z);
Single.TryParse(txtOrientationY.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out Y);
pose.SetOrientation(X, Y, Z);
UpdateClients();
}
}
private void txtOrientationZ_TextChanged(object sender, EventArgs e)
{
if (lisMarkers.SelectedIndex >= 0)
{
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
float X, Y, Z;
pose.GetOrientation(out X, out Y, out Z);
Single.TryParse(txtOrientationZ.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out Z);
pose.SetOrientation(X, Y, Z);
UpdateClients();
}
}
private void txtTranslationX_TextChanged(object sender, EventArgs e)
{
if (lisMarkers.SelectedIndex >= 0)
{
float X;
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
Single.TryParse(txtTranslationX.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out X);
pose.pose.t[0] = X;
UpdateClients();
}
}
private void txtTranslationY_TextChanged(object sender, EventArgs e)
{
if (lisMarkers.SelectedIndex >= 0)
{
float Y;
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
Single.TryParse(txtTranslationY.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out Y);
pose.pose.t[1] = Y;
UpdateClients();
}
}
private void txtTranslationZ_TextChanged(object sender, EventArgs e)
{
if (lisMarkers.SelectedIndex >= 0)
{
float Z;
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
Single.TryParse(txtTranslationZ.Text, NumberStyles.Any, CultureInfo.InvariantCulture, out Z);
pose.pose.t[2] = Z;
UpdateClients();
}
}
private void txtId_TextChanged(object sender, EventArgs e)
{
if (lisMarkers.SelectedIndex >= 0)
{
int id;
MarkerPose pose = oSettings.lMarkerPoses[lisMarkers.SelectedIndex];
Int32.TryParse(txtId.Text, out id);
pose.id = id;
UpdateClients();
}
}
}
}
+120
View File
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+95
View File
@@ -0,0 +1,95 @@
// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl)
// License: MIT Software License See LICENSE.txt for the full license.
// If you use this software in your research, then please use the following citation:
// Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data
// Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015
// @INPROCEEDINGS{Kowalski15,
// author={Kowalski, M. and Naruniec, J. and Daniluk, M.},
// booktitle={3D Vision (3DV), 2015 International Conference on},
// title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors},
// year={2015},
// }
using System;
namespace KinectServer
{
[Serializable]
public class AffineTransform
{
public float[,] R = new float[3, 3];
public float[] t = new float[3];
public AffineTransform()
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (i == j)
R[i, j] = 1;
else
R[i, j] = 0;
}
t[i] = 0;
}
}
}
[Serializable]
public class MarkerPose
{
public AffineTransform pose = new AffineTransform();
public int id = -1;
public MarkerPose()
{
UpdateRotationMatrix();
}
public void SetOrientation(float X, float Y, float Z)
{
r[0] = X;
r[1] = Y;
r[2] = Z;
UpdateRotationMatrix();
}
public void GetOrientation(out float X, out float Y, out float Z)
{
X = r[0];
Y = r[1];
Z = r[2];
}
private void UpdateRotationMatrix()
{
float radX = r[0] * (float)Math.PI / 180.0f;
float radY = r[1] * (float)Math.PI / 180.0f;
float radZ = r[2] * (float)Math.PI / 180.0f;
float c1 = (float)Math.Cos(radZ);
float c2 = (float)Math.Cos(radY);
float c3 = (float)Math.Cos(radX);
float s1 = (float)Math.Sin(radZ);
float s2 = (float)Math.Sin(radY);
float s3 = (float)Math.Sin(radX);
//Z Y X rotation
pose.R[0, 0] = c1 * c2;
pose.R[0, 1] = c1 * s2 * s3 - c3 * s1;
pose.R[0, 2] = s1 * s3 + c1 * c3 * s2;
pose.R[1, 0] = c2 * s1;
pose.R[1, 1] = c1 * c3 + s1 * s2 * s3;
pose.R[1, 2] = c3 * s1 * s2 - c1 * s3;
pose.R[2, 0] = -s2;
pose.R[2, 1] = c2 * s3;
pose.R[2, 2] = c2 * c3;
}
private float[] r = new float[3];
}
}