2016-05-04 9 views
1

Für meine Arbeit muss ich eine Punktwolke in ein Graustufen- (Tiefen-) Bild umwandeln, was bedeutet, dass die z-Koordinate jedes XYZ-Punktes in der Wolke einen Grauton darstellt. Zum Abbilden eines von dem Z-Koordinate [z_min, z_max] Intervall auf das [0..255] Intervall verwenden ich die Kartenfunktion von Arduino:Wie konvertiert man eine 3D-Punktwolke in ein Tiefenbild?

float map(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min)/(in_max - in_min) + out_min; }

damit fertig ich brauche das Ergebnis in einem schreiben Das Problem ist, dass die Wolken, die ich habe, Millionen von Punkten haben können, so dass ich sie nicht einfach 1 zu 1 in ein Bild schreiben kann. Nehmen wir an, ich habe 3000x1000 geordnete XY-Punkte. Wie würde ich tun, wenn ich sie in ein Bild mit 700 x 300 Pixeln schreiben wollte? Ich hoffe die Frage ist klar, danke im Voraus für die Beantwortung.

+0

Vielleicht nur die Koordinaten skalieren und die Grauwerte, wenn mehrere Punkte auf einem Pixel liegen aufaddieren? –

+0

Hi, das hatte ich auch im Kopf, aber lasst uns darüber nachdenken.Eine Wolkenreihe entspricht 3600 Punkten und eine Bildreihe entspricht 1680 Punkten. Das Ergebnis wäre 2,41 Punkte pro Pixel. Gehe ich einfach mit 2 Punkten pro Pixel und fülle die nicht belegten Pixel mit 0s? –

+0

Es ist nicht klar, ob Ihre Punktwolke dicht ist. Das heißt, wenn mehrere Punkte in demselben Pixel landen, würde ich den Z-Wert des nächsten Pixels nehmen, wie es passieren würde, wenn Sie sie rasterisierten. Also, wenn Sie diese Aufgabe nicht von Hand machen wollen, reichen Sie einfach Ihre Punkte ein, um OpenGL zu sagen und lassen Sie sie für Sie rastern, dann lesen Sie den Tiefenpuffer aus. – masterxilo

Antwort

0

Ich habe es geschafft, eine Lösung für mein Problem zu finden. Es ist ein fee long Algorithmus für Stack-Überlauf, aber ertragen Sie mit mir. Die Idee ist, einen Vektor von XY Graustufenpunkten als pgm Datei zu schreiben.

Schritt 1:cloud_to_greyscale - Funktion, die eine XYZ Punktwolke in einen Vektor von XY Graustufenpunkte umwandelt und empfängt ein cloud als Parameter:

for each point pt in cloud 
    point_xy_greyscale.x <- pt.x 
    point_xy_greyscale.y <- pt.y 
    point_xy_greyscale.greyscale <- map(pt.z, z_min, z_max, 0, 255) 
    greyscale_vector.add(point_xy_greyscale) 
loop 

return greyscale_vector 

Schritt 2:greyscale_to_image - Funktion, die den zuvor zurückgegebenen Vektor als greyscale_image schreibt, eine Klasse mit width, height und _pixels Element, das normalerweise einem zweidimensionalen Array von unsigned short entspricht. Die Funktion empfängt die folgenden Parameter: a greyscale_vector (wird in das Bild umgewandelt) und x_epsilon, die uns helfen, die x Pixelkoordinaten für unsere Punkte zu begrenzen, da die x Punktkoordinaten Floats sind (und daher nicht als Arrayindizes geeignet sind) .

Ein wenig Hintergrundinformationen: Ich arbeite an etwas widop Wolken genannt, so in meinem 3D-Raum x die width ist, y die depth ist und z ist die height. Bemerkenswert ist auch die Tatsache, dass y eine integer ist so für mein Problem, die height des Bildes ist einfach zu finden: es ist y_max - y_min. Um die width des Bildes zu finden, folgen Sie dem Algorithmus unten und wenn es nicht klar ist, werde ich alle Fragen beantworten und ich bin offen für Vorschläge.

img_width <- 0; // image width 
img_height <- y_max - y_min + 1 // image height 

// determining image width 
for each point greyscale_xy_point in greyscale_vector 
    point_x_cell <- (pt.x - x_min) * x_epsilon * 10 

    if point_x_cell > img_width 
     img_width <- point_x_cell + 1 
loop 

// defining and initializing image with the calculated height and width 
greyscale_img(img_width, img_height) 

// initializing greyscale image points 
for y <- 0 to greyscale_img.height 
    for x <- 0 to greyscale_img.width 
     greyscale_img[y][x] = 0 
    loop 
loop 

// filling image with vector data 
for each point point_xy_greyscale in greyscale_vector 
    image_x = (point_xy_greyscale.x - x_min) * x_epsilon * 10 
    image_y = point_xy_greyscale.y - y_min 

    greyscale_image[image_y][image_x] = point_xy_greyscale.greyscale 
loop 

return greyscale_image 

Das einzige, was zu tun ist links das Bild in die Datei zu schreiben, aber das ist einfach zu tun, kann man einfach die Formatregeln in diesem Link zum pgm-Format bezogen finden. Ich hoffe, das hilft jemandem.

EDIT_1: Ich habe ein Bild des Ergebnisses hinzugefügt. Es soll eine Eisenbahn sein und der Grund, warum es ziemlich dunkel ist, ist, dass es einige Objekte gibt, die hoch sind, so dass Bodenobjekte dunkler sind.

depth image of railway

+0

Was ist Ihre Kartenfunktion in Ihrer Antwort? – Ehsan