5

Ich benutze google tango tablet, um Punktwolkendaten und RGB-Kamerabilder zu erfassen. Ich möchte einen 3D-Scan des Raums erstellen. Dafür muss ich 2D Bildpixel zum Punktwolkenpunkt abbilden. Ich werde das mit vielen Punktwolken und entsprechenden Bildern machen. So muss ich ein Codeskript schreiben, das zwei Eingänge hat: 1. Punktwolke und 2. Bild vom selben Punkt in die gleiche Richtung genommen und das Skript sollte einen farbigen Punkt ausgeben Wolke. Wie sollte ich diese & nähern welche Plattformen werden sehr einfach zu bedienen sein?Wie man Punktwolke von Bildpixeln koloriert?

Antwort

5

Hier ist die Mathematik einen 3D-Punktes v zu 2D-Pixelraum im Kamerabild zur Karte (unter der Annahme, dass v enthält bereits die extrinsische Kameraposition und -orientierung, unten siehe Anmerkung *):

// Project to tangent space. 
vec2 imageCoords = v.xy/v.z; 

// Apply radial distortion. 
float r2 = dot(imageCoords, imageCoords); 
float r4 = r2*r2; 
float r6 = r2*r4; 
imageCoords *= 1.0 + k1*r2 + k2*r4 + k3*r6; 

// Map to pixel space. 
vec3 pixelCoords = cameraTransform*vec3(imageCoords, 1); 

Wo cameraTransform ist die 3x3-Matrix:

[ fx 0 cx ] 
[ 0 fy cy ] 
[ 0 0 1 ] 

mit fx, fy, cx, cy, k1, k2, k3 von TangoCameraIntrinsics.

pixelCoords ist vec3 deklariert, ist aber tatsächlich 2D in homogenen Koordinaten. Die dritte Koordinate ist immer 1 und kann daher für praktische Zwecke ignoriert werden.

Beachten Sie, dass wenn Sie Texturkoordinaten anstelle von Pixelkoordinaten haben möchten, dies nur eine weitere lineare Transformation ist, die vorab auf cameraTransform vormultipliziert werden kann (wie von oben nach unten oder von unten nach oben). .

Für was "Plattform" (die ich locker als "Sprache" interpretiert) ist am einfachsten, die native API scheint die einfachste Möglichkeit, Ihre Hände auf Kamera Pixel zu bekommen, obwohl es scheint, Menschen sind auch erfolgreich mit Unity und Java.


* geliefert Points by TangoXYZij integrieren bereits die Tiefe Kamera extrinsische verwandeln. Da das aktuelle Entwickler-Tablet die gleiche Hardware wie die Tiefen- und Farbbildaufnahme nutzt, ist es technisch nicht möglich, ein exakt übereinstimmendes Farbbild zu erhalten, es sei denn, sowohl Ihr Gerät als auch Ihre Szene sind stationär. Glücklicherweise in der Praxis können die meisten Anwendungen wahrscheinlich annehmen, dass weder die Kamera-Pose noch die Szene sich in einer Bildzeit genug ändert, um die Farbsuche signifikant zu beeinflussen.

2

Diese Antwort ist nicht originell, sie ist einfach als Annehmlichkeit für Unity-Benutzer gedacht, die die richtige Antwort von @rhashimoto erhalten möchten, die für sie entwickelt wurde. Mein Beitrag (hoffentlich) ist Code, der die normalen 16 Multiplikationen und 12 Additionen (bei Unity ergeben nur 4x4-Matrizen) zu 2 Multiplikationen und 2 Additionen durch Auslassen aller Null-Ergebnisse reduziert. Ich lief ein wenig unter einer Million Punkte durch den Test und überprüfte jedes Mal, wenn meine Berechnungen mit den grundlegenden Matrixberechnungen übereinstimmten - definiert als die absolute Differenz zwischen den beiden Ergebnissen, die kleiner als Maschinen-Epsilon sind - ich bin damit so gut wie möglich bedenke, dass @rhashimoto auftauchen und ein riesiges Loch darin stecken kann :-)

Wenn du hin und her schalten willst, denk daran, dass dies C# ist, also muss die USEMATRIXMATH-Definition am Anfang der Datei erscheinen.

Da gibt es nur eine Tango-Gerät gerade jetzt, und ich gehe davon aus den Spezifika sind konstant über alle Geräte, ich ließ sie nur als Konstanten in, so dass

fx = 1042.73999023438 
fy = 1042.96997070313 
cx = 637.273986816406 
cy = 352.928985595703 
k1 = 0.228532999753952 
k2 = -0.663019001483917 
k3 = 0.642908990383148 

Ja sie entsorgt werden können als Konstanten, die die Dinge lesbarer machen würden, und C# ist wahrscheinlich schlau genug, um es zu optimieren - aber ich habe zu viel von meinem Leben in Agner Foggs Zeug verbracht und werde immer paranoid sein.

Der auskommentierte Code unten dient zum Testen des Unterschieds, falls Sie es wünschen. Sie müssen einige andere Kommentare auskommentieren und die Ergebnisse auskommentieren, wenn Sie die Ergebnisse testen möchten.

Mein Dank wieder @rhashimoto, das ist weit, weit besser als das, was ich

musste ich seine Logik treu geblieben sind, erinnern diese Pixelkoordinaten, nicht UV-Koordinaten - er richtig ist, dass Sie die premultiply kann Transformation normalisiert UV-Werte, aber da er mich schon einmal auf diese geschult, werde ich mit genau der Mathe-Stick er präsentiert, bevor ich mit zu viel :-)

static public Vector2 PictureUV(Vector3 tangoDepthPoint) 
    { 
     Vector2 imageCoords = new Vector2(tangoDepthPoint.x/tangoDepthPoint.z, tangoDepthPoint.y/tangoDepthPoint.z); 
     float r2 = Vector2.Dot(imageCoords, imageCoords); 
     float r4 = r2*r2; 
     float r6 = r2*r4; 
     imageCoords *= 1.0f + 0.228532999753952f*r2 + -0.663019001483917f*r4 + 0.642908990383148f*r6; 
     Vector3 ic3 = new Vector3(imageCoords.x,imageCoords.y,1); 

#if USEMATRIXMATH 
     Matrix4x4 cameraTransform = new Matrix4x4(); 
     cameraTransform.SetRow(0,new Vector4(1042.73999023438f,0,637.273986816406f,0)); 
     cameraTransform.SetRow(1, new Vector4(0, 1042.96997070313f, 352.928985595703f, 0)); 
     cameraTransform.SetRow(2, new Vector4(0, 0, 1, 0)); 
     cameraTransform.SetRow(3, new Vector4(0, 0, 0, 1)); 
     Vector3 pixelCoords = cameraTransform * ic3; 
     return new Vector2(pixelCoords.x, pixelCoords.y); 
#else 
     //float v1 = 1042.73999023438f * imageCoords.x + 637.273986816406f; 
     //float v2 = 1042.96997070313f * imageCoords.y + 352.928985595703f; 
     //float v3 = 1; 
     return new Vector2(1042.73999023438f * imageCoords.x + 637.273986816406f,1042.96997070313f * imageCoords.y + 352.928985595703); 
#endif 

     //float dx = Math.Abs(v1 - pixelCoords.x); 
     //float dy = Math.Abs(v2 - pixelCoords.y); 
     //float dz = Math.Abs(v3 - pixelCoords.z); 
     //if (dx > float.Epsilon || dy > float.Epsilon || dz > float.Epsilon) 
     // UnityEngine.Debug.Log("Well, that didn't work"); 
     //return new Vector2(v1, v2); 
    } 

Als eine letzte Anmerkung Geige, tun beachten Code, den er zur Verfügung stellt, ist GLSL - wenn Sie nur für schöne Bilder verwenden, verwenden Sie es - das ist für diejenigen, die tatsächlich hinzufügen müssen natürliche Verarbeitung.

Verwandte Themen