2

I'm trying to create a 3D matrix stacking multiple images in order to create a 3D visualization of densities in order to interpolate those data and other operations... right now I'm trying to stack images with this code:

import numpy as np
import matplotlib.pyplot as plt



stacked = np.ndarray(shape=(300,300,20))
for s in range(11):
    s=s+1
    source = cv2.imread('IMAGE_#'+ str(s) +'.png',0)
    m = np.asmatrix(source)
    stacked[:,:,s]=m

x=stacked[:,0]
y=stacked[:,1]
z=stacked[:,2]

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x,y,z)
plt.xlim(0,300)
plt.ylim(0,300)

plt.show()

but the plot results in something like this wrong plot

While I'm expecting a cloud of dots in the middle of the graph. What am I doing wrong?

EDIT 1> To test the code feel free to use 'Image Stacking\StarM '+ str(s) +'.png',0 in the 10th line with this images: https://wetransfer.com/downloads/7a3cdac121427d122787b5e24943d4b320210412123454/edfcc9

EDIT 2> changed the code as follows:

import numpy as np
import matplotlib.pyplot as plt



stacked = np.ndarray(shape=(300,300,20))


for s in range(11):
    s=s+1
    source = cv2.imread('ss\StarM '+ str(s) +'.png',2)
    m = np.asmatrix(source)
    stacked[:,:,s]=m

x=stacked[:,:,0]
y=stacked[:,:,1]
z=stacked[:,:,2]

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x,y,z)
plt.xlim(0,300)
plt.ylim(0,300)

plt.show() 

And now the plot shows: WrongPlot2

thx

2
  • cant test your code without your images Commented Apr 12, 2021 at 11:34
  • Your images seem 2d to me so you are trying to pile them up to create a 3D image ? Are you converting them to grayscale before adding one to another? Commented Apr 12, 2021 at 17:59

2 Answers 2

1

ok had to rewrite starting from Pillow I don't know opencv.

Here my code:


from PIL import Image

import numpy as np
import matplotlib.pyplot as plt


size_image = Image.open('StarM 1.png', 'r')

print(size_image.size)

stacked = np.ndarray(shape=(size_image.size[0], size_image.size[1], 11)) #empty array


for s in range(11):
    s = s+1
    source = Image.open('StarM ' + str(s) + '.png', 'r').convert('L') #open image convertiung it to grayscale
    # source.show() #show grayscale image
    # print('source :', source) #print image
    m = np.asarray(source) #convert image to array
    print(m) #print array 
    print(m.shape) #print array shape

    stacked[:, :, s-1] = m #fill empty array with image
    
# print(stacked)
print(stacked.shape) #print array shape


x,y,z =stacked.nonzero() #gets non zero values from stacked
print(x,y,z)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x,y,z)
plt.show()

the result is:

enter image description here

not sure is what you were expecting let me know.

changing line 47 to

x,y,z =(stacked >  100).nonzero() #gets >100 values from stacked

with values ranging from 0 to 255 (remember we are on 8 bit grayscale 0 - 255)

you get nicer pics:

enter image description here

borrowed from Creating a 3D plot from a 3D numpy array

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, that's exactly what i was looking for, thank you so much
0

cant test your code without your images, but just moving your code I get more than

one dot

import numpy as np
import matplotlib.pyplot as plt



stacked = np.ndarray(shape=(300,300,20))
for s in range(11):
    s=s+1
    source = cv2.imread('IMAGE_#'+ str(s) +'.png',0)
    print(source)
    m = np.asmatrix(source)
    stacked[:,:,s]=m

    x=stacked[:,0]
    y=stacked[:,1]
    z=stacked[:,2]
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.scatter(x,y,z)
    plt.xlim(0,300)
    plt.ylim(0,300)
    
    plt.show()

see:

enter image description here

3 Comments

I tried this but nothing has changed, the result still shows only (0,0,0). I edited the question with images
think I was just taking the p***s, you right for some unesplicable reason my IDE doesnt open 11 graphs showing a single dot on an Y axis but put them all toghether. Wandering around I discovered that calling plt.figure() inside a loop is no good : Your issue is that you're creating a new figure with every iteration using plt.figure(). Remove this line from your for loop and it should work fine, as this short example below shows [see her]( stackoverflow.com/questions/26355313/…)
@L.Vezzani sorry to bother again : do you know what is the 'libpng warning: iCCP: known incorrect sRGB profile' error I got oprening the images ? tried pngcrush -ow -rem allb -reduce *.png from here: stackoverflow.com/questions/22745076/… but didnt work. Now I am at the 11 opened graph plot with the single dot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.