Visualization of Sperical Coordinates with Primitive Type Representing Pixels of Img

Dear Community,

I have a *.csv file representing spherical coordinates of pixels picked up from a Fish-eye camera (185 DEG, all directions) looking like this:

x, y, z, R, G, B
0.1, 3.5, 4.0, 150, 150, 150

The source image is in gray scale ==> R=G=B. Thats why I wrote 150,150,150.
The total amount of coordinates is 752*480 (resolution).


I want to visualize the pixels in 3D space. We have applied the pixels on a sphere and generated the 3D position for each pixel around the center point (0,0,0) based on undistortion and calibration. I am not interested in rendering the end result but to view the result inside the view port.

Since a Vertex isn’t consuming any space and I can’t just place Vertexes and give them a RGB-color I figured that a Cube would be easiest and the most performance effective object (except for pyramid).

Cube = 8 vertexes, 6 sides * 2 triangles = 12 faces.
Pyramid = 5 vertexes, bottom 2 triangles + sides 4 triangles = 6 faces.
Plane = 4 vertexes, two triangles.
** Not considering the Object’s internal settings

An additional idea was to use planes facing the view port but that would probably consume a lot of real time in scene performance while rotating the view port in the center point to view the image.

A other idea could be to use particles but I am not sure of how that would work and the particles them self’s have to obtain some space based on a shape I think.

First I tried this in 3dsMax scripting and it was far to slow and heavy. But I have a feeling that Blender with pyton script is the tool for the job.

Problem is that the resolution requires so many objects and blender crashes (752x480= 360960 px). Code and files can be find bellow.

How can this be done in a more efficient way? How do I remove the shading etc? even though I use specular color 0,0,0 I still have shadings.

import bpy
import csv
file = csv.reader(open('\\Users\Jose Estevez\BlenderPY\\sphere.csv', newline=''), delimiter=',')
curRow = [] #empty placeholder for current row
color = 0
magnifier = 500

def returnMaterialByName(passedName):
    result = None
    for m in
        if == passedName:
            result = m
    return result
def createNewMaterial (passedName):
    tempMat =
    if tempMat != None:
        tempMat.diffuse_color = (color/255,color/255,color/255)
        tempMat.diffuse_shader = 'LAMBERT'
        tempMat.diffuse_intensity = 1.0
        tempMat.specular_color = (0.0,0.0,0.0)
        tempMat.specular_shader = 'COOKTORR'
        tempMat.specular_intensity = 0.5
        tempMat.alpha = 1.0
        tempMat.ambient = 0.3
        tempMat.emit = 0.2
        tempMat.use_shadeless = True
    return tempMat
def aquireOrCreateMaterial(passedName):
    tempMat = returnMaterialByName(passedName)
    if tempMat == None:
        tempMat = createNewMaterial(passedName)
    return tempMat
for idx, row in enumerate(file):
    if ((idx % 100) == 0):          ## IMPORTANT! Constant 100 will only limit to create every 100'th Object. Change Constant to 1 to create all the objects of pixles.
        curRow = row
        x = eval(curRow[0])
        y = eval(curRow[1])
        z = eval(curRow[2])
        color = eval(curRow[3])         

        # create cube and transform resize
        bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(x*magnifier, y*magnifier, z*magnifier), rotation=(0.0,0.0,0.0))
        # store the location of current 3d cursor
        saved_location = bpy.context.scene.cursor_location.copy()  # returns a copy of the vector
        # give 3dcursor new coordinates
        bpy.context.scene.cursor_location = (0,0,0)
        # set the origin on the current object to the 3dcursor location
        # set 3dcursor location back to the stored location
        bpy.context.scene.cursor_location = saved_location

        myObj = bpy.context.active_object


        me =
        mat = aquireOrCreateMaterial(curRow[3])
        # before applying below, you need to create material data slot first!
        myObj.material_slots[0].material =[curRow[3]]


OK, I am far from an expert on this, but my instinct says that you are working at the wrong level. Create a 2D image from your csv file and then project it onto a sphere using some kind of fisheye projection. Why are they in x,y,z format, anyway? You should have two polar coordinates for each pixel, not three.

Thanks for your reply Sjoerd.

The source image is fisheye 185DEG in all directions (meaning that it is bigger then a 1/2 sphere). We are undistorting and re-projecting it to spherical coordinates to get coordinates in form of vectors where each angle is deturmend from the center point 0,0,0 to the pixel position in 3D space. The CSV file is spherical coordinates (vectors) from our output already and not a 2D image.

Yes, you can also define a spherical vector by three other values, radius, zenith and azimuth like in the picture in this (
The reason is that we later want to reproject this to the ground plane to generate a birds-eye view of our fish eye video stream. So basically fish-eye to spherical to Cartesian ground plane.

The picture is of a road for a miniature autonomous car that we are programming to be able to follow lain’s, handle parking and over take obsolesces. The mapping is to be able to map the road in global space and for controlling algorithms.

For some reason the birds-eye we are outputting in the last step is crocked. So the only way to visualize if the spherical coordinates have been generated properly is to paint them in 3D space to see if it is covering 185 DEG of the sphere.

Maybe went a bit overkill on explaining all the steps we are trying to achieve but at least I explained why for those that might wonder the purpose.

My main question is how to visualize the csv data in a optimized way?