public override bool SavePointCloud(string path, string fileName) { try { if (ColorMetaData == null || DepthMetaData == null) { return(false); } //List<int> listToBeRemoved = new List<int>(); PointCloud pc = MetaDataBase.ToPointCloud(this.ColorMetaData, this.DepthMetaData, this.BodyMetaData, this.coordinateMapper); List <Vector3> vList = new List <Vector3>(); List <Vector3> cList = new List <Vector3>();; if (PointCloudScannerSettings.ShowFaceScanEllipse) { for (int i = pc.Count - 1; i >= 0; i--) { bool add = true; if (pc.Vectors[i].X > 0 && pc.Vectors[i].X > faceX) { add = false; } else if (pc.Vectors[i].X < 0 && pc.Vectors[i].X < -faceX) { add = false; } else if (pc.Vectors[i].Y > 0 && pc.Vectors[i].Y > faceY) { add = false; } else if (pc.Vectors[i].Y < 0 && pc.Vectors[i].Y < -faceY) { add = false; } if (add) { vList.Add(pc.Vectors[i]); cList.Add(pc.Colors[i]); } } } PointCloud pcNew = new OpenTKExtension.PointCloud(vList, cList, null, null, null, null); //pc.RemovePoints(listToBeRemoved); return(UtilsPointCloudIO.ToObjFile_ColorInVertex(pcNew, path + "\\" + fileName)); } catch (Exception err) { System.Windows.Forms.MessageBox.Show("SW Error - error saving Point cloud: " + err.Message); return(false); } }
private void testClouds() { ICPLib.IterativeClosestPointTransform icp = new ICPLib.IterativeClosestPointTransform(); pTarget = null; for (int i = 0; i < 10; i++) { //first iteration if (pTarget == null) { pTarget = PointCloud.FromObjFile(GLSettings.Path + GLSettings.PathPointClouds, "Nick\\PointCloudSequence#" + (i).ToString() + ".obj"); } pSource = PointCloud.FromObjFile(GLSettings.Path + GLSettings.PathPointClouds, "Nick\\PointCloudSequence#" + (i + 1).ToString() + ".obj"); //------------------ //ICP icp.Reset_RealData(); //icp.ICPSettings.ThresholdMergedPoints = 0f; icp.ICPSettings.MaximumNumberOfIterations = 15; pTarget = icp.PerformICP(pSource, this.pTarget); System.Diagnostics.Debug.WriteLine("###### ICP for point cloud: " + pTarget.Name + " - points added: " + icp.PointsAdded.ToString()); // this.registrationMatrix = icp.Matrix; // registrationMatrix.Save(GLSettings.Path + GLSettings.PathPointClouds, "registrationMatrix.txt"); } GlobalVariables.ShowLastTimeSpan("--> Time for ICP "); SaveResultCloudAndShow(pTarget); }
private static float CalculateScale_Umeyama(PointCloud pointsSourceShift, Vector3 eigenvalues, Matrix3 K2) { float sigmaSquared = 0f; for (int i = 0; i < pointsSourceShift.Vectors.Length; i++) { sigmaSquared += pointsSourceShift.Vectors[i].NormSquared(); } sigmaSquared /= pointsSourceShift.Vectors.Length; float c = 0.0F; for (int i = 0; i < 3; i++) { c += eigenvalues[i]; } if (K2[2, 2] < 0) { c -= 2 * eigenvalues[2]; } c = c / sigmaSquared; return(c); }
private static double CalculateScale_Umeyama(PointCloud pointsSourceShift, Vector3d eigenvalues, Matrix3d K2) { double sigmaSquared = 0f; for (int i = 0; i < pointsSourceShift.Count; i++) { sigmaSquared += pointsSourceShift.Vectors[i].NormSquared(); } sigmaSquared /= pointsSourceShift.Count; double c = 0.0F; for (int i = 0; i < 3; i++) { c += eigenvalues[i]; } if (K2[2, 2] < 0) { c -= 2 * eigenvalues[2]; } c = c / sigmaSquared; return(c); }
/// <summary> /// colors and indices are lost!! /// </summary> /// <param name="pc"></param> /// <returns></returns> public static PointCloud ResizeAndSort_Distance(PointCloud pc) { pc.ResizeTo1(); List <Vertex> vList = new List <Vertex>(); if (pc.Colors == null || pc.Colors.Length != pc.Vectors.Length) { pc.SetDefaultColors(); } for (int i = 0; i < pc.Vectors.Length; i++) { Vertex v = new Vertex(pc.Vectors[i]); v.Color = pc.Colors[i]; vList.Add(v); } vList.Sort(new Vector_Length()); PointCloud pcNew = PointCloud.FromListVertices(vList); return(pcNew); }
public static Matrix4d FindTransformationMatrix(PointCloud pointsSource, PointCloud pointsTarget, ICP_VersionUsed icpVersionUsed) { //shift points to the center of mass (centroid) Vector3 centroidTarget = pointsTarget.CentroidVector; //Vector3d centroidTarget_Double = new Vector3d(pointsTarget.CentroidVector.X, pointsTarget.CentroidVector.Y, pointsTarget.CentroidVector.Z); PointCloud pointsTargetTranslated = pointsTarget.Clone(); pointsTargetTranslated.SubtractVector(centroidTarget); Vector3 centroidSource = pointsSource.CentroidVector; PointCloud pointsSourceTranslated = pointsSource.Clone(); pointsSourceTranslated.SubtractVector(centroidSource); Matrix3d R = FindRotationMatrix(pointsSourceTranslated, pointsTargetTranslated, icpVersionUsed); Vector3d T = CalculateTranslation(centroidSource, centroidTarget, R); Matrix4d myMatrix = new Matrix4d(); myMatrix = myMatrix.PutTheMatrix4dtogether(T, R); return(myMatrix); }
/// <summary> /// calculates Matrix for alignment of sourceAxes and targetAxes; sets pointCloudResult /// </summary> /// <param name="i"></param> /// <param name="j"></param> /// <param name="bestResultMeanDistance"></param> /// <param name="meanDistance"></param> /// <param name="myMatrixBestResult"></param> /// <param name="sourceAxes"></param> private void SVD_ForTwoPointCloudAlignment_Double(int i, int j, ref float meanDistance, ref Matrix4 myMatrixBestResult, PointCloud sourceAxes) { PointCloud targetAxes = InvertAxes(pcTargetCentered, pcTargetCentered.PCAAxes, j); //Matrix4 myMatrix = SVD_Float.FindTransformationMatrix(sourceAxes, targetAxes, ICP_VersionUsed.Scaling_Umeyama); Matrix4d myMatrix4d = SVD.FindTransformationMatrix_WithoutCentroids(sourceAxes, targetAxes, ICP_VersionUsed.Umeyama); //CheckPCA(myMatrix4d, sourceAxes, targetAxes); PointCloud myResultPC = myMatrix4d.TransformPoints(pcSourceCentered); //-------------- pcTreeResult = KDTree.FindClosestPointCloud_Parallel(myResultPC); meanDistance = KDTree.MeanDistance; //PointCloud myPointCloudTargetTemp = kdtree.FindNearest_Rednaxela(ref myPointsResultTemp, pointCloudTargetCentered, -1); System.Diagnostics.Debug.WriteLine(" in iteration: MeanDistance between orientations: " + i.ToString() + " : " + j.ToString() + " : " + meanDistance.ToString("G")); if (meanDistance < bestResultMeanDistance) { myMatrixBestResult = myMatrix4d.ToMatrix4(); bestResultMeanDistance = meanDistance; pcResultBest = myResultPC; } pcResult = myResultPC; }
public static void CreateOutliers(PointCloud pointCloud, int numberOfOutliers) { int indexInPointCloud = pointCloud.Vectors.Length - 1; int numberIterate = 0; List <Vector3> listV = new List <Vector3>(pointCloud.Vectors); for (int i = pointCloud.Vectors.Length - 1; i >= 0; i--) { //Vector3 p = vectors[i].Vector; Vector3 perturb = new Vector3(pointCloud.Vectors[i]); numberIterate++; if (numberIterate > numberOfOutliers) { return; } if (i % 3 == 0) { perturb.X *= 1.2f; perturb.Y *= 1.3f; perturb.Z *= 1.05f; } else if (i % 3 == 1) { perturb.X *= 1.4f; perturb.Y *= 0.9f; perturb.Z *= 1.2f; } else { perturb.X *= 0.9f; perturb.Y *= 1.2f; perturb.Z *= 1.1f; } indexInPointCloud++; listV.Add(perturb); } pointCloud.Vectors = listV.ToArray(); }
public static void ShuffleRandom(PointCloud pointCloud) { IList <Vector3> lNew = new List <Vector3>(pointCloud.Vectors); lNew.Shuffle(); }
public PointCloud Clone() { return(PointCloud.Clone(this)); }
public void AddPointCloud(string name, PointCloud pc) { this.OpenGL_UControl.AddPointCloud(name, pc); }
public KDTreeKennell(PointCloud pc) : this() { Build(pc); }
public void Update(List <Vector3> points) { this.pointCloud = new OpenTKExtension.PointCloud(points, null, null, null, null, null); FillPointCloud(); FillIndexBuffer(); }
public static Vector3 ResetCentroid(PointCloud pc, bool centered) { return(pc.ResetCentroid(centered)); }
/// <summary>Generates a 3D PointCloud for a cuboid.</summary> /// <param name="Name">PointCloud name.</param> /// <param name="Radius">Cylinder radius.</param> /// <param name="Height">Cylinder height.</param> /// <param name="numPoints">Number of points for circular section.</param> /// <param name="Color">Color vector.</param> public static PointCloud CuboidEmpty(float xMax, float yMax, float zMax, int pointsMaxX, int pointsMaxY, int pointsMaxZ) { float stepX = xMax / pointsMaxX; float stepY = yMax / pointsMaxY; float stepZ = zMax / pointsMaxZ; PointCloud pCloud = new PointCloud(); List <Vector3> pointsList = new List <Vector3>(); List <uint> listIndices = new List <uint>(); uint ind = 0; for (int i = 0; i <= pointsMaxX; i++) { for (int j = 0; j <= pointsMaxY; j++) { if ((i == 0 || i == pointsMaxX) || (j == 0 || j == pointsMaxY)) { for (int k = 0; k <= pointsMaxZ; k++) { Vector3 v = new Vector3(i * stepX, j * stepY, k * stepZ); pointsList.Add(v); if (pointsList.Count > 3) { ind++; listIndices.Add(ind - 1); listIndices.Add(ind); listIndices.Add(ind - 2); listIndices.Add(ind); listIndices.Add(ind - 3); listIndices.Add(ind); listIndices.Add(ind - 4); listIndices.Add(ind); } if (pointsList.Count > 2) { ind++; listIndices.Add(ind - 1); listIndices.Add(ind); listIndices.Add(ind - 2); listIndices.Add(ind); listIndices.Add(ind - 3); listIndices.Add(ind); } if (pointsList.Count > 1) { ind++; listIndices.Add(ind - 1); listIndices.Add(ind); listIndices.Add(ind - 2); listIndices.Add(ind); } if (pointsList.Count > 0) { listIndices.Add(ind); listIndices.Add(ind++); } } } else { Vector3 v = new Vector3(i * stepX, j * stepY, 0); pointsList.Add(v); v = new Vector3(i * stepX, j * stepY, zMax); pointsList.Add(v); } } } pCloud.Vectors = pointsList.ToArray(); pCloud.Indices = listIndices.ToArray(); //pCloud.CreateIndicesDefault(); return(pCloud); }
public static PointCloud Cube_RegularGrid_Empty(float cubeSize, int numberOfPointsPerPlane) { return(PointCloud.FromListVector3(Cube_RegularGrid_Empty_List(cubeSize, numberOfPointsPerPlane))); }
/// <summary> /// u - > v translation /// </summary> /// <param name="mat"></param> /// <param name="sourceV"></param> /// <param name="targetV"></param> /// <returns></returns> public static Matrix3 RotationCoordinateChange(this Matrix3 mat, PointCloud cloudOrigin, PointCloud target) { for (int i = 0; i < 3; i++) { cloudOrigin[i].Vector = cloudOrigin[i].Vector.NormalizeV(); target[i].Vector = target[i].Vector.NormalizeV(); } for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { //float angle = Vector3.CalculateAngle(u[j], v[i]); //float val = Math.Cos(angle); mat[i, j] = Vector3.Dot(cloudOrigin[i].Vector, target[j].Vector); } } // mat.Transpose(); //mat.Invert(); //mat.Transpose(); return(mat); }
//other methods for SVD, for possible later usage //MathUtils.SingularValueDecomposition3x3(Harray, Uarray, warray, VTarray); //MathNet.Numerics.Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider svd = new MathNet.Numerics.Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider(); //double[] a = MatrixUtilsNumerics.doubleFromArraydouble(Harray); //double[] u = MatrixUtilsNumerics.doubleFromArraydouble(Uarray); //double[] vt = MatrixUtilsNumerics.doubleFromArraydouble(Uarray); //double[] s = new double[3]; //svd.SingularValueDecomposition(true, a, 3, 3, s, u, vt); private static Matrix3d CalculateRotationBySingularValueDecomposition(Matrix3d H, PointCloud pointsSourceTranslated, ICP_VersionUsed icpVersionUsed) { Eigenvalues_Helper(H); //gives R, the rotation matrix, U - the left eigenvectors, VT - right transposed eigenvectors, EV - the eigenvalues //see article by Umeyama //if (H.Determinant < 0) //{ // R[2, 2] = -R[2, 2]; // //S[2, 2] = -1; //} //calculate the sign matrix for using the scale factor Matrix3d K2 = Matrix3d.Identity; //double check = U.Determinant * VT.Determinant; //if (check < 0 && Math.Abs(check) > 1E-3) //{ // K2[2, 2] = -1; //} double scale = CalculateScale_Umeyama(pointsSourceTranslated, EV, K2); R = Matrix3d.Mult(R, K2); if (icpVersionUsed == ICP_VersionUsed.Umeyama) { //R = Matrix3d.Mult(R, K2); R = R.MultiplyScalar(scale); } return(R); }
public static Matrix4d FindTransformationMatrix_MinimumDistance(PointCloud pointsSource, PointCloud pointsTarget, ICP_VersionUsed icpVersionUsed, float minimumDistance) { minimumDistance *= minimumDistance * 2; List <Vector3> sourceList = new List <Vector3>(); List <Vector3> targetList = new List <Vector3>(); int numberOfVectorsNotTaken = 0; for (int i = 0; i < pointsSource.Vectors.Length; i++) { float distance = pointsSource.Vectors[i].DistanceSquared(pointsTarget.Vectors[i]); if (distance < minimumDistance) { sourceList.Add(pointsSource.Vectors[i]); targetList.Add(pointsTarget.Vectors[i]); } else { numberOfVectorsNotTaken++; } } if (numberOfVectorsNotTaken > 0) { System.Diagnostics.Debug.WriteLine("Ignored vectors in SVD because too far: " + numberOfVectorsNotTaken.ToString() + " : out of : " + pointsSource.Count.ToString()); } PointCloud pSourceNew = PointCloud.FromListVector3(sourceList); PointCloud pTargetNew = PointCloud.FromListVector3(targetList); if (pSourceNew == null || pTargetNew == null) { return(Matrix4d.Identity); } return(FindTransformationMatrix(pSourceNew, pTargetNew, icpVersionUsed)); }
/// <summary> /// resets all vectors so that there are no negative values /// </summary> /// <param name="pc"></param> public static void ResetToOriginAxis(PointCloud pc) { PointCloud.AddVectorToAll(pc, pc.BoundingBox.Min.Abs()); }
public static Matrix4d FindTransformationMatrix_WithoutCentroids(PointCloud pointsSource, PointCloud pointsTarget, ICP_VersionUsed icpVersionUsed) { Matrix3d R = FindRotationMatrix(pointsSource, pointsTarget, icpVersionUsed); //Vector3d T = new Vector3d(); Matrix4d myMatrix = new Matrix4d(); myMatrix = myMatrix.FromMatrix3d(R); return(myMatrix); }
/// <summary> /// creates color info for all DEPTH pixels (to later e.g. write ply file from it) - needed also for image creation /// </summary> /// <param name="myColorMetaData"></param> /// <param name="myDepthMetaData"></param> /// <param name="myCoordinateMapper"></param> /// <returns></returns> public static byte[] ToColorArrayBytes(PointCloud pointCloud, int width, int height) { byte[] colorPixels = new byte[width * height * 4]; int xInt = 0; int yInt = 0; int zInt = 0; int depthIndex = 0; try { ////out ushort[] depthPixels = PointCloud.ToUshort1Dim(pc, width, height); float xMin = pointCloud.BoundingBoxMin.X; float yMin = pointCloud.BoundingBoxMin.Y; float dx = pointCloud.BoundingBoxMax.X - pointCloud.BoundingBoxMin.X; float dy = pointCloud.BoundingBoxMax.Y - pointCloud.BoundingBoxMin.Y; //init to black background for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { depthIndex = (y * width) + x; //depthIndex = ((height - y - 1) * width) + x; int colorIndex = depthIndex * 4; colorPixels[colorIndex] = (byte)0; colorPixels[colorIndex + 1] = (byte)0; colorPixels[colorIndex + 2] = (byte)0; colorPixels[colorIndex + 3] = (byte)255; } } // set color ------------------------------------- for (int i = 0; i < pointCloud.Count; i++) { Vector3 v = pointCloud.Vectors[i]; Vector3 color = pointCloud.Colors[i]; xInt = Convert.ToInt32((v.X - xMin) * width / dx); yInt = Convert.ToInt32((v.Y - yMin) * height / dy); zInt = Convert.ToInt32(v.Z); //exclude rounding errors if (xInt < width && yInt < height) { //rotate the cloud to 180 degrees, so that display as image is OK depthIndex = ((height - yInt - 1) * width) + xInt; int colorIndex = depthIndex * 4; colorPixels[colorIndex] = Convert.ToByte(color.X * 255); colorPixels[colorIndex + 1] = Convert.ToByte(color.Y * 255); colorPixels[colorIndex + 2] = Convert.ToByte(color.Z * 255); colorPixels[colorIndex + 3] = 255; } } } catch { System.Diagnostics.Debug.WriteLine("Error in ToColorArrayBytes: " + xInt.ToString() + " : " + yInt.ToString() + " : " + zInt.ToString() + " : " + depthIndex.ToString() + " : "); } return(colorPixels); }
public Face(List <Vector3> points) { this.pointCloud = new OpenTKExtension.PointCloud(points, null, null, null, null, null); }
public KDTreeEricRegina(PointCloud pc) : this() { Build(pc); }
/// <summary> /// returns the target (tree) points found for the input (source) points /// </summary> /// <param name="source"></param> /// <returns></returns> public PointCloud FindClosestPointCloud_NotParallel(PointCloud source) { this.source = source; this.ResetTaken(); VertexKDTree[] resultArray = new VertexKDTree[source.Count]; PointCloud sourceShuffled; if (this.TakenAlgorithm) { sourceShuffled = source.Clone(); sourceShuffled.SetDefaultIndices(); sourceShuffled = PointCloud.Shuffle(sourceShuffled); } else { sourceShuffled = source; } int nearest_index = 0; float nearest_distance = 0f; //System.Threading.Tasks.Parallel.For(0, source.Count, i => for (int i = 0; i < sourceShuffled.Count; i++) { VertexKDTree vSource = new VertexKDTree(sourceShuffled.Vectors[i], i); VertexKDTree vTargetFound = FindClosestPoint(vSource, ref nearest_distance, ref nearest_index); //resultArray[i] = vTargetFound.Clone(); resultArray[i] = vTargetFound; } ; List <VertexKDTree> resultList = new List <VertexKDTree>(resultArray); result = PointCloud.FromListVertexKDTree(resultList); //shuffle back //float f = PointCloud.MeanDistance(sourceShuffled, pcResult); PointCloud pcResultShuffledBack; if (this.TakenAlgorithm) { pcResultShuffledBack = result.Clone(); for (int i = 0; i < pcResultShuffledBack.Count; i++) { //pcResultShuffled.Vectors[i] = pcResult.Vectors[Convert.ToInt32(sourceShuffled.Indices[i])]; pcResultShuffledBack.Vectors[Convert.ToInt32(sourceShuffled.Indices[i])] = result.Vectors[i]; } } else { pcResultShuffledBack = result; } // this.MeanDistance = PointCloud.MeanDistance(source, pcResultShuffledBack); return(pcResultShuffledBack); }
/// <summary> /// at least source points should be non zero /// </summary> /// <param name="mypointCloudTarget"></param> /// <param name="mypointCloudSource"></param> /// <param name="mypointCloudResult"></param> /// <param name="changeColor"></param> public void Show3PointClouds(PointCloud mypointCloudSource, PointCloud mypointCloudTarget, PointCloud mypointCloudResult, bool changeColor) { this.OpenGLControl.RemoveAllPointClouds(); mypointCloudTarget.Name = "Target"; mypointCloudSource.Name = "Source"; mypointCloudResult.Name = "Result"; //target in green List <System.Drawing.Color> myColors; if (mypointCloudTarget != null) { if (changeColor) { myColors = ColorExtensions.ToColorList(mypointCloudTarget.Count, 0, 255, 0, 255); PointCloud.SetColorToList(mypointCloudTarget, myColors); } this.OpenGLControl.ShowPointCloud(mypointCloudTarget); } if (mypointCloudSource != null) { //source in white myColors = ColorExtensions.ToColorList(mypointCloudSource.Count, 255, 255, 255, 255); if (changeColor) { PointCloud.SetColorToList(mypointCloudSource, myColors); } this.OpenGLControl.ShowPointCloud(mypointCloudSource); } if (mypointCloudResult != null) { //transformed in red myColors = ColorExtensions.ToColorList(mypointCloudResult.Count, 255, 0, 0, 255); if (changeColor) { PointCloud.SetColorToList(mypointCloudResult, myColors); } this.OpenGLControl.ShowPointCloud(mypointCloudResult); } }
/// <summary> /// at least source points should be non zero /// </summary> /// <param name="mypointCloudTarget"></param> /// <param name="mypointCloudSource"></param> /// <param name="mypointCloudResult"></param> /// <param name="changeColor"></param> public void Show3PointCloudOpenGL(PointCloud mypointCloudSource, PointCloud mypointCloudTarget, PointCloud mypointCloudResult, bool changeColor) { this.OpenGLControl.RemoveAllPointClouds(); //target in green if (mypointCloudTarget != null) { if (changeColor) { mypointCloudTarget.Colors = ColorExtensions.ToVector3Array(mypointCloudTarget.Vectors.Length, 0, 255, 0); } ShowPointCloudOpenGL(mypointCloudTarget, false); } if (mypointCloudSource != null) { //source in white if (changeColor) { mypointCloudSource.Colors = ColorExtensions.ToVector3Array(mypointCloudSource.Vectors.Length, 255, 255, 255); } ShowPointCloudOpenGL(mypointCloudSource, false); } if (mypointCloudResult != null) { //transformed in red if (changeColor) { mypointCloudResult.Colors = ColorExtensions.ToVector3Array(mypointCloudResult.Vectors.Length, 255, 0, 0); } ShowPointCloudOpenGL(mypointCloudResult, false); } }
public static PointCloud CloneAll(PointCloud pc) { return(pc.Clone()); }
public void ShowPointCloud(PointCloud pc) { this.OpenGLControl.ShowPointCloud(pc); }
public static void ToJsonFile(PointCloud pc, string fileName) { JsonUtils.Serialize(pc.Vectors, fileName); }