pythonfor-loopnumpy-ndarrayspectral-python

Never ending for loop in Python


I have a code that basically takes two images,big image and small image. the small image is being reduced into one row image and then is being subtracted from each row of the big image. The result should be new big- image with different values.

both images are ndarray (more then 2 dimensions ). When I run this code on one row, it works , but when I try to use for loop in order to run it on all the rows in the image, it never stops .

details of the image: -The big image has currently 11 rows with 1024 columns. -The small reduced image has 1 row only with 1024 columns.

This is the code:

import spectral.io.envi as envi
import matplotlib.pyplot as plt
import os
from spectral import *
import numpy as np


#Create the image path
#the path 
img_path = r'N:\path\Image_Python\13-8-2019\emptyname_2019-08-13_11-05-46\capture'

resized_path=r'N:\path\Image_Python'


#the specific file 

img_dark= 'DARKREF_emptyname_2019-08-13_11-05-46.hdr'
resized_file='resize3.hdr'

#load images
img_dark= envi.open(os.path.join(img_path,img_dark)).load()
resized= envi.open(os.path.join(resized_path,resized_file)).load()


wavelength=[float(i) for i in resized.metadata['wavelength']]

#reduce image into 1 row
dark_1024=img_dark.mean(axis=0)


#the follow command works and was compared with the image in ENVI
#resized[0] suppoose to be  row no. 0 in image resized
#so the problem is in the for loop 
resized[0]-dark_1024

#Here I have tried to run at the beginning my computation but then it took too much so I tried to run #this count in order to see how many rows it iterate through 
#I have tried this also with a== 3,000,000 and it got there
a=0
for i in resized[0,1]:
    a=a+1
    print(a)
    if a==8000:
        break

My end goal is to be able to run the process "resize-dark_1024" for each row in my n-dimensional image using for loop

clarification: Whenever I run:

resized[i]-dark_1024[i]

when i is a number. for example i=3, i-4...

it works

edit 2: If I run this with the dark_1024,which has 1 row with 1024 pixels:

a=0
for i in dark_1024:
    a=a+1
    print(a)
    if a==8000:
        break

it counts up to 1024:


Solution

  • An easy way to accomplish what you want is by using numpy's broadcasting capability. For example, I'll create a dummy dark array.

    In [1]: import spectral as spy
    
    In [2]: import numpy as np
    
    In [3]: img = spy.open_image('92AV3C.lan').load()
    
    In [4]: dark = np.random.rand(*img.shape[1:]).astype(img.dtype)
    
    In [5]: print(img.shape, dark.shape)
    (145, 145, 220) (145, 220)
    

    To be able to subtract dark from all rows of img, we just need to create a dummy index for the first dimension so numpy can broadcast the operation.

    In [6]: y = img - dark[None, :, :]
    

    And just to verify that it worked, make sure that the difference between y and img is equal to dark across multiple rows.

    In [7]: dark[:2, :2]
    Out[7]: 
    array([[0.38583156, 0.08694188],
           [0.79687476, 0.24988273]], dtype=float32)
    
    In [8]: img[:2, :2, :2] - y[:2, :2, :2]
    Out[8]: 
    array([[[0.3857422 , 0.08691406],
            [0.796875  , 0.25      ]],
    
           [[0.3857422 , 0.08691406],
            [0.796875  , 0.25      ]]], dtype=float32)