mirror of
https://github.com/storytold/LiveScan3D.git
synced 2026-10-09 00:09:58 +00:00
Data streaming is now much faster (up to 40%). Also added the option to save to binary PLY which is faster than ASCII.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -38,6 +38,7 @@ namespace KinectServer
|
||||
public int nNumICPIterations = 10;
|
||||
public int nNumRefineIters = 2;
|
||||
public bool bMergeScansForSave = false;
|
||||
public bool bSaveAsBinaryPLY = true;
|
||||
|
||||
public KinectSettings()
|
||||
{
|
||||
|
||||
@@ -206,8 +206,11 @@ namespace KinectServer
|
||||
}
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
lFrameVerts.Add(BitConverter.ToSingle(buffer, startIdx));
|
||||
startIdx += 4;
|
||||
float val = BitConverter.ToInt16(buffer, startIdx);
|
||||
//converting from milimeters to meters
|
||||
val /= 1000.0f;
|
||||
lFrameVerts.Add(val);
|
||||
startIdx += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ namespace KinectServer
|
||||
if (!oSettings.bMergeScansForSave)
|
||||
{
|
||||
string outputFilename = outDir + "\\" + nFrames.ToString().PadLeft(5, '0') + i.ToString() + ".ply";
|
||||
saveToPly(outputFilename, lFrameVertsAllDevices[i], lFrameRGBAllDevices[i]);
|
||||
saveToPly(outputFilename, lFrameVertsAllDevices[i], lFrameRGBAllDevices[i], oSettings.bSaveAsBinaryPLY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace KinectServer
|
||||
if (oSettings.bMergeScansForSave)
|
||||
{
|
||||
string outputFilename = outDir + "\\" + nFrames.ToString().PadLeft(5, '0') + ".ply";
|
||||
saveToPly(outputFilename, lFrameVerts, lFrameRGB);
|
||||
saveToPly(outputFilename, lFrameVerts, lFrameRGB, oSettings.bSaveAsBinaryPLY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -450,27 +450,53 @@ namespace KinectServer
|
||||
refineWorker.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void saveToPly(string filename, List<Single> vertices, List<byte> colors)
|
||||
private void saveToPly(string filename, List<Single> vertices, List<byte> colors, bool binary)
|
||||
{
|
||||
int nVertices = vertices.Count / 3;
|
||||
|
||||
System.IO.StreamWriter file = new System.IO.StreamWriter(filename);
|
||||
FileStream fileStream = File.Open(filename, FileMode.Create);
|
||||
|
||||
System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(fileStream);
|
||||
System.IO.BinaryWriter binaryWriter = new System.IO.BinaryWriter(fileStream);
|
||||
|
||||
//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");
|
||||
if (binary)
|
||||
streamWriter.WriteLine("ply\nformat binary_little_endian 1.0");
|
||||
else
|
||||
streamWriter.WriteLine("ply\nformat ascii 1.0\n");
|
||||
streamWriter.Write("element vertex " + nVertices.ToString() + "\n");
|
||||
streamWriter.Write("property float x\nproperty float y\nproperty float z\nproperty uchar red\nproperty uchar green\nproperty uchar blue\nend_header\n");
|
||||
streamWriter.Flush();
|
||||
|
||||
//Vertex and color data are written here.
|
||||
for (int j = 0; j < vertices.Count / 3; j++)
|
||||
if (binary)
|
||||
{
|
||||
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);
|
||||
for (int j = 0; j < vertices.Count / 3; j++)
|
||||
{
|
||||
for (int k = 0; k < 3; k++)
|
||||
binaryWriter.Write(vertices[j * 3 + k]);
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
byte temp = colors[j * 3 + k];
|
||||
binaryWriter.Write(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file.Close();
|
||||
else
|
||||
{
|
||||
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) + " ";
|
||||
streamWriter.WriteLine(s);
|
||||
}
|
||||
}
|
||||
streamWriter.Flush();
|
||||
binaryWriter.Flush();
|
||||
fileStream.Close();
|
||||
}
|
||||
|
||||
void RestartUpdateWorker()
|
||||
|
||||
Generated
+81
-39
@@ -33,6 +33,9 @@
|
||||
this.lbICPIters = new System.Windows.Forms.Label();
|
||||
this.txtICPIters = new System.Windows.Forms.TextBox();
|
||||
this.grClient = new System.Windows.Forms.GroupBox();
|
||||
this.grBody = new System.Windows.Forms.GroupBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.chBodyData = new System.Windows.Forms.CheckBox();
|
||||
this.grMarkers = new System.Windows.Forms.GroupBox();
|
||||
this.lbX2 = new System.Windows.Forms.Label();
|
||||
this.btRemove = new System.Windows.Forms.Button();
|
||||
@@ -69,17 +72,17 @@
|
||||
this.lbFilterDistance = new System.Windows.Forms.Label();
|
||||
this.txtFilterDistance = new System.Windows.Forms.TextBox();
|
||||
this.grServer = new System.Windows.Forms.GroupBox();
|
||||
this.rBinaryPly = new System.Windows.Forms.RadioButton();
|
||||
this.lbFormat = new System.Windows.Forms.Label();
|
||||
this.rAsciiPly = new System.Windows.Forms.RadioButton();
|
||||
this.txtRefinIters = new System.Windows.Forms.TextBox();
|
||||
this.lbOuterIters = new System.Windows.Forms.Label();
|
||||
this.grBody = new System.Windows.Forms.GroupBox();
|
||||
this.chBodyData = new System.Windows.Forms.CheckBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.grClient.SuspendLayout();
|
||||
this.grBody.SuspendLayout();
|
||||
this.grMarkers.SuspendLayout();
|
||||
this.grBounding.SuspendLayout();
|
||||
this.grFiltering.SuspendLayout();
|
||||
this.grServer.SuspendLayout();
|
||||
this.grBody.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// lbMerge
|
||||
@@ -132,6 +135,37 @@
|
||||
this.grClient.TabStop = false;
|
||||
this.grClient.Text = "KinectClient settings";
|
||||
//
|
||||
// grBody
|
||||
//
|
||||
this.grBody.Controls.Add(this.label1);
|
||||
this.grBody.Controls.Add(this.chBodyData);
|
||||
this.grBody.Location = new System.Drawing.Point(9, 211);
|
||||
this.grBody.Name = "grBody";
|
||||
this.grBody.Size = new System.Drawing.Size(249, 110);
|
||||
this.grBody.TabIndex = 47;
|
||||
this.grBody.TabStop = false;
|
||||
this.grBody.Text = "Body data";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(11, 43);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(187, 13);
|
||||
this.label1.TabIndex = 20;
|
||||
this.label1.Text = "More features will be added here soon";
|
||||
//
|
||||
// chBodyData
|
||||
//
|
||||
this.chBodyData.AutoSize = true;
|
||||
this.chBodyData.Location = new System.Drawing.Point(11, 19);
|
||||
this.chBodyData.Name = "chBodyData";
|
||||
this.chBodyData.Size = new System.Drawing.Size(113, 17);
|
||||
this.chBodyData.TabIndex = 19;
|
||||
this.chBodyData.Text = "stream only bodies";
|
||||
this.chBodyData.UseVisualStyleBackColor = true;
|
||||
this.chBodyData.CheckedChanged += new System.EventHandler(this.chBodyData_CheckedChanged);
|
||||
//
|
||||
// grMarkers
|
||||
//
|
||||
this.grMarkers.Controls.Add(this.lbX2);
|
||||
@@ -470,6 +504,9 @@
|
||||
//
|
||||
// grServer
|
||||
//
|
||||
this.grServer.Controls.Add(this.rBinaryPly);
|
||||
this.grServer.Controls.Add(this.lbFormat);
|
||||
this.grServer.Controls.Add(this.rAsciiPly);
|
||||
this.grServer.Controls.Add(this.txtRefinIters);
|
||||
this.grServer.Controls.Add(this.lbOuterIters);
|
||||
this.grServer.Controls.Add(this.lbMerge);
|
||||
@@ -478,11 +515,44 @@
|
||||
this.grServer.Controls.Add(this.lbICPIters);
|
||||
this.grServer.Location = new System.Drawing.Point(12, 345);
|
||||
this.grServer.Name = "grServer";
|
||||
this.grServer.Size = new System.Drawing.Size(632, 78);
|
||||
this.grServer.Size = new System.Drawing.Size(632, 111);
|
||||
this.grServer.TabIndex = 44;
|
||||
this.grServer.TabStop = false;
|
||||
this.grServer.Text = "KinectServer settings";
|
||||
//
|
||||
// rBinaryPly
|
||||
//
|
||||
this.rBinaryPly.AutoSize = true;
|
||||
this.rBinaryPly.Location = new System.Drawing.Point(179, 71);
|
||||
this.rBinaryPly.Name = "rBinaryPly";
|
||||
this.rBinaryPly.Size = new System.Drawing.Size(76, 17);
|
||||
this.rBinaryPly.TabIndex = 30;
|
||||
this.rBinaryPly.TabStop = true;
|
||||
this.rBinaryPly.Text = "binary PLY";
|
||||
this.rBinaryPly.UseVisualStyleBackColor = true;
|
||||
this.rBinaryPly.CheckedChanged += new System.EventHandler(this.PlyFormat_CheckedChanged);
|
||||
//
|
||||
// lbFormat
|
||||
//
|
||||
this.lbFormat.AutoSize = true;
|
||||
this.lbFormat.Location = new System.Drawing.Point(6, 73);
|
||||
this.lbFormat.Name = "lbFormat";
|
||||
this.lbFormat.Size = new System.Drawing.Size(58, 13);
|
||||
this.lbFormat.TabIndex = 29;
|
||||
this.lbFormat.Text = "File format:";
|
||||
//
|
||||
// rAsciiPly
|
||||
//
|
||||
this.rAsciiPly.AutoSize = true;
|
||||
this.rAsciiPly.Location = new System.Drawing.Point(98, 71);
|
||||
this.rAsciiPly.Name = "rAsciiPly";
|
||||
this.rAsciiPly.Size = new System.Drawing.Size(75, 17);
|
||||
this.rAsciiPly.TabIndex = 28;
|
||||
this.rAsciiPly.TabStop = true;
|
||||
this.rAsciiPly.Text = "ASCII PLY";
|
||||
this.rAsciiPly.UseVisualStyleBackColor = true;
|
||||
this.rAsciiPly.CheckedChanged += new System.EventHandler(this.PlyFormat_CheckedChanged);
|
||||
//
|
||||
// txtRefinIters
|
||||
//
|
||||
this.txtRefinIters.Location = new System.Drawing.Point(266, 23);
|
||||
@@ -500,42 +570,11 @@
|
||||
this.lbOuterIters.TabIndex = 26;
|
||||
this.lbOuterIters.Text = "Num of refinement iters:";
|
||||
//
|
||||
// grBody
|
||||
//
|
||||
this.grBody.Controls.Add(this.label1);
|
||||
this.grBody.Controls.Add(this.chBodyData);
|
||||
this.grBody.Location = new System.Drawing.Point(9, 211);
|
||||
this.grBody.Name = "grBody";
|
||||
this.grBody.Size = new System.Drawing.Size(249, 110);
|
||||
this.grBody.TabIndex = 47;
|
||||
this.grBody.TabStop = false;
|
||||
this.grBody.Text = "Body data";
|
||||
//
|
||||
// chBodyData
|
||||
//
|
||||
this.chBodyData.AutoSize = true;
|
||||
this.chBodyData.Location = new System.Drawing.Point(11, 19);
|
||||
this.chBodyData.Name = "chBodyData";
|
||||
this.chBodyData.Size = new System.Drawing.Size(113, 17);
|
||||
this.chBodyData.TabIndex = 19;
|
||||
this.chBodyData.Text = "stream only bodies";
|
||||
this.chBodyData.UseVisualStyleBackColor = true;
|
||||
this.chBodyData.CheckedChanged += new System.EventHandler(this.chBodyData_CheckedChanged);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(11, 43);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(187, 13);
|
||||
this.label1.TabIndex = 20;
|
||||
this.label1.Text = "More features will be added here soon";
|
||||
//
|
||||
// SettingsForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(656, 435);
|
||||
this.ClientSize = new System.Drawing.Size(656, 468);
|
||||
this.Controls.Add(this.grServer);
|
||||
this.Controls.Add(this.grClient);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
@@ -544,6 +583,8 @@
|
||||
this.Text = "Settings";
|
||||
this.Load += new System.EventHandler(this.SettingsForm_Load);
|
||||
this.grClient.ResumeLayout(false);
|
||||
this.grBody.ResumeLayout(false);
|
||||
this.grBody.PerformLayout();
|
||||
this.grMarkers.ResumeLayout(false);
|
||||
this.grMarkers.PerformLayout();
|
||||
this.grBounding.ResumeLayout(false);
|
||||
@@ -552,8 +593,6 @@
|
||||
this.grFiltering.PerformLayout();
|
||||
this.grServer.ResumeLayout(false);
|
||||
this.grServer.PerformLayout();
|
||||
this.grBody.ResumeLayout(false);
|
||||
this.grBody.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
@@ -606,6 +645,9 @@
|
||||
private System.Windows.Forms.GroupBox grBody;
|
||||
private System.Windows.Forms.CheckBox chBodyData;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.RadioButton rBinaryPly;
|
||||
private System.Windows.Forms.Label lbFormat;
|
||||
private System.Windows.Forms.RadioButton rAsciiPly;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,16 @@ namespace KinectServer
|
||||
chMerge.Checked = oSettings.bMergeScansForSave;
|
||||
txtICPIters.Text = oSettings.nNumICPIterations.ToString();
|
||||
txtRefinIters.Text = oSettings.nNumRefineIters.ToString();
|
||||
if (oSettings.bSaveAsBinaryPLY)
|
||||
{
|
||||
rBinaryPly.Checked = true;
|
||||
rAsciiPly.Checked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
rBinaryPly.Checked = false;
|
||||
rAsciiPly.Checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateClients()
|
||||
@@ -288,5 +298,17 @@ namespace KinectServer
|
||||
oSettings.bStreamOnlyBodies = chBodyData.Checked;
|
||||
UpdateClients();
|
||||
}
|
||||
|
||||
private void PlyFormat_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (rAsciiPly.Checked)
|
||||
{
|
||||
oSettings.bSaveAsBinaryPLY = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
oSettings.bSaveAsBinaryPLY = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,10 +56,10 @@ private:
|
||||
SocketClient *m_pClientSocket;
|
||||
std::vector<float> m_vBounds;
|
||||
|
||||
std::vector<Point3f> m_vLastFrameVertices;
|
||||
std::vector<Point3s> m_vLastFrameVertices;
|
||||
std::vector<RGB> m_vLastFrameRGB;
|
||||
std::vector<Body> m_vLastFrameBody;
|
||||
std::vector<std::vector<Point3f>> m_vGatheredVertices;
|
||||
std::vector<std::vector<Point3s>> m_vGatheredVertices;
|
||||
std::vector<std::vector<RGB>> m_vGatheredRGBPoints;
|
||||
|
||||
HWND m_hWnd;
|
||||
@@ -84,7 +84,7 @@ private:
|
||||
bool SetStatusMessage(_In_z_ WCHAR* szMessage, DWORD nShowTimeMsec, bool bForce);
|
||||
|
||||
void HandleSocket();
|
||||
void SendFrame(vector<Point3f> vertices, vector<RGB> RGB, vector<Body> body);
|
||||
void SendFrame(vector<Point3s> vertices, vector<RGB> RGB, vector<Body> body);
|
||||
|
||||
void SocketThreadFunction();
|
||||
void StoreFrame(Point3f *vertices, Point2f *mapping, RGB *color, vector<Body> &bodies, BYTE* bodyIndex);
|
||||
|
||||
@@ -57,6 +57,32 @@ typedef struct Point3f
|
||||
float Z;
|
||||
} Point3f;
|
||||
|
||||
typedef struct Point3s
|
||||
{
|
||||
Point3s()
|
||||
{
|
||||
this->X = 0;
|
||||
this->Y = 0;
|
||||
this->Z = 0;
|
||||
}
|
||||
Point3s(short X, short Y, short Z)
|
||||
{
|
||||
this->X = X;
|
||||
this->Y = Y;
|
||||
this->Z = Z;
|
||||
}
|
||||
//meters to milimeters
|
||||
Point3s(Point3f &other)
|
||||
{
|
||||
this->X = static_cast<short>(1000 * other.X);
|
||||
this->Y = static_cast<short>(1000 * other.Y);
|
||||
this->Z = static_cast<short>(1000 * other.Z);
|
||||
}
|
||||
short X;
|
||||
short Y;
|
||||
short Z;
|
||||
} Point3s;
|
||||
|
||||
typedef struct Point2f
|
||||
{
|
||||
Point2f()
|
||||
|
||||
@@ -163,7 +163,7 @@ HRESULT ImageRenderer::Draw(BYTE* pImage, unsigned long cbImage, std::vector<Bod
|
||||
// Draw the bitmap stretched to the size of the window
|
||||
m_pRenderTarget->DrawBitmap(m_pBitmap);
|
||||
|
||||
for (int i = 0; i < vBodies.size(); i++)
|
||||
for (unsigned int i = 0; i < vBodies.size(); i++)
|
||||
{
|
||||
if (vBodies[i].bTracked)
|
||||
{
|
||||
@@ -226,7 +226,7 @@ void ImageRenderer::DrawBody(Body &body)
|
||||
DrawBone(body, JointType_KneeLeft, JointType_AnkleLeft);
|
||||
DrawBone(body, JointType_AnkleLeft, JointType_FootLeft);
|
||||
|
||||
for (int i = 0; i < body.vJoints.size(); i++)
|
||||
for (unsigned int i = 0; i < body.vJoints.size(); i++)
|
||||
{
|
||||
D2D1_POINT_2F tempPoint;
|
||||
tempPoint.x = body.vJointsInColorSpace[i].X;
|
||||
|
||||
@@ -611,9 +611,9 @@ void LiveScanClient::HandleSocket()
|
||||
}
|
||||
}
|
||||
|
||||
void LiveScanClient::SendFrame(vector<Point3f> vertices, vector<RGB> RGB, vector<Body> body)
|
||||
void LiveScanClient::SendFrame(vector<Point3s> vertices, vector<RGB> RGB, vector<Body> body)
|
||||
{
|
||||
int size = RGB.size() * (3 + 3 * sizeof(float)) + sizeof(int);
|
||||
int size = RGB.size() * (3 + 3 * sizeof(short)) + sizeof(int);
|
||||
|
||||
vector<char> buffer(size);
|
||||
char *ptr2 = (char*)vertices.data();
|
||||
@@ -630,9 +630,9 @@ void LiveScanClient::SendFrame(vector<Point3f> vertices, vector<RGB> RGB, vector
|
||||
buffer[pos++] = RGB[i].rgbBlue;
|
||||
|
||||
|
||||
memcpy(buffer.data() + pos, ptr2, sizeof(float)* 3);
|
||||
ptr2 += sizeof(float)* 3;
|
||||
pos += sizeof(float)* 3;
|
||||
memcpy(buffer.data() + pos, ptr2, sizeof(short)* 3);
|
||||
ptr2 += sizeof(short) * 3;
|
||||
pos += sizeof(short) * 3;
|
||||
}
|
||||
|
||||
int nBodies = body.size();
|
||||
@@ -745,8 +745,15 @@ void LiveScanClient::StoreFrame(Point3f *vertices, Point2f *mapping, RGB *color,
|
||||
if (m_bFilter)
|
||||
filter(goodVertices, goodColorPoints, m_nFilterNeighbors, m_fFilterThreshold);
|
||||
|
||||
vector<Point3s> goodVerticesShort(goodVertices.size());
|
||||
|
||||
for (unsigned int i = 0; i < goodVertices.size(); i++)
|
||||
{
|
||||
goodVerticesShort[i] = goodVertices[i];
|
||||
}
|
||||
|
||||
m_vLastFrameBody = bodies;
|
||||
m_vLastFrameVertices = goodVertices;
|
||||
m_vLastFrameVertices = goodVerticesShort;
|
||||
m_vLastFrameRGB = goodColorPoints;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user