2

I have an image given as a 3D numpy array (width, height and color as dimensions). Now I would like to extract all possible sub-images of a given shape. For example, the width and height of the original image is 300 and 200 pixels, respectively, and I would like to extract all sub-images with width and heights equal to 10 and 20 pixels, respectively. Moreover, each sub-image I would like to have as 1D array (for that I need to specify a particular ordering of pixels).

I solve the problem in the following way:

for col0 in range(w_max - max_shift):
    x3s_new = [x + col0 for x in x3s]
    for row0 in range(h_max - max_shift):

        vec_1 = []
        for col_shift, row_shift in px_inds:
            col = col0 + col_shift
            row = row0 + row_shift
            vec_1 += [ia[row, col, 0], ia[row, col, 1], ia[row, col, 2]]

        y3s_new = [y + row0 for y in y3s]
        vec_2 = list(ia[y3s_new, x3s_new, z3s])

In the above code I make a loop over columns and rows of the "matrix" representing the image. Then each pixel (given by its column and row) I treat as the left-top corner of the sub-image and extract the sub-image.

The vec_1 and vec_2 are the desired sub-images given as 1D arrays (lists). They are identical, I just wanted to test what way is faster. Surprisingly, it take more time to generate vec_2 than vec_1. However, according to this answer to my question it was expected to be faster. So, why it is not faster?

Finally, I also would like to know if there is a faster alternative to looping over all columns and rows of the image-matrix.

To summarize, my question is: How to achive what I need in faster way? At the moment it takes me about 5 minutes to "process" one image and it is not acceptable for my purposes.

2
  • 2
    Do you know about slicing? Commented May 19, 2015 at 6:18
  • @cfh, no (some_symbols_to_make_it_acceptably_long). Commented May 19, 2015 at 7:19

1 Answer 1

5

You should use Numpy slicing.

Given a 3D numpy array M, you can select an sub-array of it, with for instance,

M_selection = M[i_min:i_max, j_min:j_max, k_min:k_max]

or alternatively, explicitly defining the slice,

sl_i = slice(i_min, i_max)
sl_j = slice(j_min, j_max)
sl_k = slice(k_min, k_max)
M_selection = M[sl_i, sl_j, sl_k]

where (i_min, i_max), etc. are the boundaries of the sub-array.

See the documentation of advanced Numpy indexing for more details.

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

Comments

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.