mirror of
https://github.com/storytold/LiveScan3D.git
synced 2026-10-09 00:09:58 +00:00
Calibration now gets saved and loaded to a file on the client side.
Simplified the calibration data structure on client. Updated README, LICENSE and gitignore.
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
*.user
|
*.user
|
||||||
*.userosscache
|
*.userosscache
|
||||||
*.sln.docstates
|
*.sln.docstates
|
||||||
|
*.tlog
|
||||||
|
|
||||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
*.userprefs
|
*.userprefs
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2015 Marek
|
Copyright (c) 2015 Marek Kowalski, Jacek Naruniec
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace KinectServer
|
|||||||
|
|
||||||
public void SendCalibrationData()
|
public void SendCalibrationData()
|
||||||
{
|
{
|
||||||
int size = 1 + 2 * (9 + 3) * sizeof(float);
|
int size = 1 + (9 + 3) * sizeof(float);
|
||||||
byte[] data = new byte[size];
|
byte[] data = new byte[size];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
@@ -111,12 +111,6 @@ namespace KinectServer
|
|||||||
Buffer.BlockCopy(oWorldTransform.t, 0, data, i, 3 * sizeof(float));
|
Buffer.BlockCopy(oWorldTransform.t, 0, data, i, 3 * sizeof(float));
|
||||||
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())
|
if (SocketConnected())
|
||||||
oSocket.Send(data);
|
oSocket.Send(data);
|
||||||
}
|
}
|
||||||
@@ -141,11 +135,15 @@ namespace KinectServer
|
|||||||
buffer = Receive(sizeof(float) * 3);
|
buffer = Receive(sizeof(float) * 3);
|
||||||
Buffer.BlockCopy(buffer, 0, oWorldTransform.t, 0, sizeof(float) * 3);
|
Buffer.BlockCopy(buffer, 0, oWorldTransform.t, 0, sizeof(float) * 3);
|
||||||
|
|
||||||
buffer = Receive(sizeof(float) * 9);
|
oCameraPose.R = oWorldTransform.R;
|
||||||
Buffer.BlockCopy(buffer, 0, oCameraPose.R, 0, sizeof(float) * 9);
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
buffer = Receive(sizeof(float) * 3);
|
oCameraPose.t[i] = 0.0f;
|
||||||
Buffer.BlockCopy(buffer, 0, oCameraPose.t, 0, sizeof(float) * 3);
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
oCameraPose.t[i] += oWorldTransform.t[j] * oWorldTransform.R[i, j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UpdateSocketState();
|
UpdateSocketState();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ While all of our code is licensed under the MIT license, the 3rd party libraries
|
|||||||
* nanoflann - https://github.com/jlblancoc/nanoflann, BSD license
|
* nanoflann - https://github.com/jlblancoc/nanoflann, BSD license
|
||||||
* OpenCV - https://github.com/Itseez/opencv, 3-clause BSD license
|
* OpenCV - https://github.com/Itseez/opencv, 3-clause BSD license
|
||||||
* OpenTK - https://github.com/opentk/opentk, MIT/X11 license
|
* OpenTK - https://github.com/opentk/opentk, MIT/X11 license
|
||||||
|
* ZSTD - https://github.com/facebook/zstd, BSD license
|
||||||
* SocketCS - http://www.adp-gmbh.ch/win/misc/sockets.html
|
* SocketCS - http://www.adp-gmbh.ch/win/misc/sockets.html
|
||||||
|
|
||||||
If you use this software in your research, then please use the following citation:
|
If you use this software in your research, then please use the following citation:
|
||||||
|
|||||||
@@ -34,9 +34,6 @@ public:
|
|||||||
vector<vector<float>> worldR;
|
vector<vector<float>> worldR;
|
||||||
int iUsedMarkerId;
|
int iUsedMarkerId;
|
||||||
|
|
||||||
vector<float> cameraT;
|
|
||||||
vector<vector<float>> cameraR;
|
|
||||||
|
|
||||||
vector<MarkerPose> markerPoses;
|
vector<MarkerPose> markerPoses;
|
||||||
|
|
||||||
bool bCalibrated;
|
bool bCalibrated;
|
||||||
@@ -45,6 +42,8 @@ public:
|
|||||||
~Calibration();
|
~Calibration();
|
||||||
|
|
||||||
bool Calibrate(RGB *pBuffer, Point3f *pCameraCoordinates, int cColorWidth, int cColorHeight);
|
bool Calibrate(RGB *pBuffer, Point3f *pCameraCoordinates, int cColorWidth, int cColorHeight);
|
||||||
|
bool LoadCalibration();
|
||||||
|
void SaveCalibration();
|
||||||
private:
|
private:
|
||||||
IMarker *pDetector;
|
IMarker *pDetector;
|
||||||
int nSampleCounter;
|
int nSampleCounter;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
#include "Kinect.h"
|
#include "Kinect.h"
|
||||||
#include "opencv\cv.h"
|
#include "opencv\cv.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
Calibration::Calibration()
|
Calibration::Calibration()
|
||||||
{
|
{
|
||||||
@@ -25,6 +25,13 @@ Calibration::Calibration()
|
|||||||
nSampleCounter = 0;
|
nSampleCounter = 0;
|
||||||
nRequiredSamples = 20;
|
nRequiredSamples = 20;
|
||||||
|
|
||||||
|
worldT = vector<float>(3, 0.0f);
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
worldR.push_back(vector<float>(3, 0.0f));
|
||||||
|
worldR[i][i] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
pDetector = new MarkerDetector();
|
pDetector = new MarkerDetector();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,17 +109,10 @@ bool Calibration::Calibrate(RGB *pBuffer, Point3f *pCameraCoordinates, int cColo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cameraR = worldR;
|
|
||||||
cameraT = RotatePoint(worldT, cameraR);
|
|
||||||
|
|
||||||
vector<float> translationIncr(3);
|
vector<float> translationIncr(3);
|
||||||
translationIncr[0] = markerPose.t[0];
|
translationIncr[0] = markerPose.t[0];
|
||||||
translationIncr[1] = markerPose.t[1];
|
translationIncr[1] = markerPose.t[1];
|
||||||
translationIncr[2] = markerPose.t[2];
|
translationIncr[2] = markerPose.t[2];;
|
||||||
|
|
||||||
cameraT[0] += translationIncr[0];
|
|
||||||
cameraT[1] += translationIncr[1];
|
|
||||||
cameraT[2] += translationIncr[2];
|
|
||||||
|
|
||||||
translationIncr = InverseRotatePoint(translationIncr, worldR);
|
translationIncr = InverseRotatePoint(translationIncr, worldR);
|
||||||
|
|
||||||
@@ -125,9 +125,50 @@ bool Calibration::Calibrate(RGB *pBuffer, Point3f *pCameraCoordinates, int cColo
|
|||||||
marker3DSamples.clear();
|
marker3DSamples.clear();
|
||||||
nSampleCounter = 0;
|
nSampleCounter = 0;
|
||||||
|
|
||||||
|
SaveCalibration();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Calibration::LoadCalibration()
|
||||||
|
{
|
||||||
|
ifstream file;
|
||||||
|
file.open("calibration.txt");
|
||||||
|
if (!file.is_open())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
file >> worldT[i];
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
file >> worldR[i][j];
|
||||||
|
}
|
||||||
|
file >> iUsedMarkerId;
|
||||||
|
file >> bCalibrated;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Calibration::SaveCalibration()
|
||||||
|
{
|
||||||
|
ofstream file;
|
||||||
|
file.open("calibration.txt");
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
file << worldT[i] << " ";
|
||||||
|
file << endl;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
file << worldR[i][j];
|
||||||
|
file << endl;
|
||||||
|
}
|
||||||
|
file << iUsedMarkerId << endl;
|
||||||
|
file << bCalibrated << endl;
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
void Calibration::Procrustes(MarkerInfo &marker, vector<Point3f> &markerInWorld, vector<float> &worldToMarkerT, vector<vector<float>> &worldToMarkerR)
|
void Calibration::Procrustes(MarkerInfo &marker, vector<Point3f> &markerInWorld, vector<float> &worldToMarkerT, vector<vector<float>> &worldToMarkerR)
|
||||||
{
|
{
|
||||||
int nVertices = marker.points.size();
|
int nVertices = marker.points.size();
|
||||||
@@ -232,8 +273,6 @@ bool Calibration::GetMarkerCorners3D(vector<Point3f> &marker3D, MarkerInfo &mark
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vector<float> InverseRotatePoint(vector<float> &point, std::vector<std::vector<float>> &R)
|
vector<float> InverseRotatePoint(vector<float> &point, std::vector<std::vector<float>> &R)
|
||||||
{
|
{
|
||||||
vector<float> res(3);
|
vector<float> res(3);
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ LiveScanClient::LiveScanClient() :
|
|||||||
m_vBounds.push_back(0.5);
|
m_vBounds.push_back(0.5);
|
||||||
m_vBounds.push_back(0.5);
|
m_vBounds.push_back(0.5);
|
||||||
m_vBounds.push_back(0.5);
|
m_vBounds.push_back(0.5);
|
||||||
|
|
||||||
|
calibration.LoadCalibration();
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveScanClient::~LiveScanClient()
|
LiveScanClient::~LiveScanClient()
|
||||||
@@ -347,6 +349,9 @@ LRESULT CALLBACK LiveScanClient::DlgProc(HWND hWnd, UINT message, WPARAM wParam,
|
|||||||
m_pClientSocket = new SocketClient(address, 48001);
|
m_pClientSocket = new SocketClient(address, 48001);
|
||||||
|
|
||||||
m_bConnected = true;
|
m_bConnected = true;
|
||||||
|
if (calibration.bCalibrated)
|
||||||
|
m_bConfirmCalibrated = true;
|
||||||
|
|
||||||
SetDlgItemTextA(m_hWnd, IDC_BUTTON_CONNECT, "Disconnect");
|
SetDlgItemTextA(m_hWnd, IDC_BUTTON_CONNECT, "Disconnect");
|
||||||
//Clear the status bar so that the "Failed to connect..." disappears.
|
//Clear the status bar so that the "Failed to connect..." disappears.
|
||||||
SetStatusMessage(L"", 1, true);
|
SetStatusMessage(L"", 1, true);
|
||||||
@@ -581,20 +586,6 @@ void LiveScanClient::HandleSocket()
|
|||||||
i += sizeof(float);
|
i += sizeof(float);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
for (int k = 0; k < 3; k++)
|
|
||||||
{
|
|
||||||
calibration.cameraR[j][k] = *(float*)(received.c_str() + i);
|
|
||||||
i += sizeof(float);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
calibration.cameraT[j] = *(float*)(received.c_str() + i);
|
|
||||||
i += sizeof(float);
|
|
||||||
}
|
|
||||||
|
|
||||||
//so that we do not lose the next character in the stream
|
//so that we do not lose the next character in the stream
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@@ -614,7 +605,7 @@ void LiveScanClient::HandleSocket()
|
|||||||
|
|
||||||
if (m_bConfirmCalibrated)
|
if (m_bConfirmCalibrated)
|
||||||
{
|
{
|
||||||
int size = 2 * (9 + 3) * sizeof(float) + sizeof(int) + 1;
|
int size = (9 + 3) * sizeof(float) + sizeof(int) + 1;
|
||||||
char *buffer = new char[size];
|
char *buffer = new char[size];
|
||||||
buffer[0] = MSG_CONFIRM_CALIBRATED;
|
buffer[0] = MSG_CONFIRM_CALIBRATED;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
@@ -630,14 +621,6 @@ void LiveScanClient::HandleSocket()
|
|||||||
memcpy(buffer + i, calibration.worldT.data(), 3 * sizeof(float));
|
memcpy(buffer + i, calibration.worldT.data(), 3 * sizeof(float));
|
||||||
i += 3 * sizeof(float);
|
i += 3 * sizeof(float);
|
||||||
|
|
||||||
memcpy(buffer + i, calibration.cameraR[0].data(), 3 * sizeof(float));
|
|
||||||
i += 3 * sizeof(float);
|
|
||||||
memcpy(buffer + i, calibration.cameraR[1].data(), 3 * sizeof(float));
|
|
||||||
i += 3 * sizeof(float);
|
|
||||||
memcpy(buffer + i, calibration.cameraR[2].data(), 3 * sizeof(float));
|
|
||||||
i += 3 * sizeof(float);
|
|
||||||
memcpy(buffer + i, calibration.cameraT.data(), 3 * sizeof(float));
|
|
||||||
|
|
||||||
m_pClientSocket->SendBytes(buffer, size);
|
m_pClientSocket->SendBytes(buffer, size);
|
||||||
m_bConfirmCalibrated = false;
|
m_bConfirmCalibrated = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user