1

I am using the sliding window technic to an image and i am extracting the mean values of pixels of each one window. So the results are someting like this [[[[215.015625][123.55036272][111.66057478]]]].now the question is how could i save all these values for every one window into a txt file or at a CSV because i want to use them for further compare similarities? whatever i tried the error is same..that it is a 4D array and not an 1D or 2D. I ll appreciate any help really.! Thank you in advance

import cv2
import matplotlib.pyplot as plt
import numpy as np


# read the image and define the stepSize and window size
# (width,height)
image2 = cv2.imread("bird.jpg")# your image path

image = cv2.resize(image2, (224, 224))
tmp = image  # for drawing a rectangle
stepSize = 10
(w_width, w_height) = (60, 60 )  # window size
for x in range(0, image.shape[1] - w_width, stepSize):
    for y in range(0, image.shape[0] - w_height, stepSize):
        window = image[x:x + w_width, y:y + w_height, :]

        # classify content of the window with your classifier and
        # determine if the window includes an object (cell) or not
        # draw window on image
        cv2.rectangle(tmp, (x, y), (x + w_width, y + w_height), (255, 0, 0), 2)  # draw rectangle on image
        plt.imshow(np.array(tmp).astype('uint8'))
        # show all windows
        plt.show()
        mean_values=[]
        mean_val, std_dev = cv2.meanStdDev(image)
        mean_val = mean_val[:3]
        mean_values.append([mean_val])
        mean_values = np.asarray(mean_values)
        print(mean_values)
chmarios
  • 39
  • 3

1 Answers1

1

Human Readable Option

Assuming that you want the data to be human readable, saving the data takes a little bit more work. My search showed me that there's this solution for saving 3D data to a text file. However, it's pretty simple to extend this example to 4D for your use case. This code is taken and adapted from that post, thank you Joe Kington and David Cheung.

import numpy as np
data = np.arange(2*3*4*5).reshape((2,3,4,5))
with open('test.csv', 'w') as outfile:
    # We write this header for readable, the pound symbol
    # will cause numpy to ignore it
    outfile.write('# Array shape: {0}\n'.format(data.shape))

    # Iterating through a ndimensional array produces slices along
    # the last axis. This is equivalent to data[i,:,:] in this case.
    # Because we are dealing with 4D data instead of 3D data,
    # we need to add another for loop that's nested inside of the
    # previous one.
    for threeD_data_slice in data:
        for twoD_data_slice in threeD_data_slice:
            # The formatting string indicates that I'm writing out
            # the values in left-justified columns 7 characters in width
            # with 2 decimal places. 
            np.savetxt(outfile, twoD_data_slice, fmt='%-7.2f')
            # Writing out a break to indicate different slices...
            outfile.write('# New slice\n')

And then once the data has been saved all you need to do is load it and reshape it (np.load()) will default to reading in the data as a 2D array but np.reshape() will allow us to recover the structure. Again, this code is adapted from the previous post.

new_data = np.loadtxt('test.csv')
# Note that this returned a 2D array!
print(new_data.shape)

# However, going back to 3D is easy if we know the 
# original shape of the array
new_data = new_data.reshape((2,3,4,5))

# Just to check that they're the same...
assert np.all(new_data == data)

Binary Option

Assuming that human readability is not necessary, I would recommend using the built-in *.npy format which is described here. This stores the data in a binary format.

You can save the array by doing np.save('NAME_OF_ARRAY.npy', ARRAY_TO_BE_SAVED) and then load it with SAVED_ARRAY = np.load('NAME_OF_ARRAY.npy').

You can also save several numpy array in a single zip file with the np.savez() function like so np.savez('MANY_ARRAYS.npz', ARRAY_ONE, ARRAY_TWO). And you load the zipped arrays in a similar fashion SEVERAL_ARRAYS = np.load('MANY_ARRAYS.npz').

Max Feinberg
  • 627
  • 4
  • 14