5

I was looking for a way to divide a numpy image into grid like patches.

This task has been answered a couple times. Extracting patches of a certain size from the image in python efficiently

skleans extract_patches_2d looks exactly right.

http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.image.extract_patches_2d.html

However, I feel that i'm not understanding the docs.

I have a image, its not particularly large, a few Mb on disk. OpenCV has no trouble with it.

Its dimensions are

self.original_image.shape
(1536, 2048, 3)

So let's extract it into blocks each 100 X 100. Back of the envelope calculation the number of patches should be something like

(1536 * 2048) / (100*100) = 314

patches=extract_patches_2d(self.original_image,(100,100))
Traceback (most recent call last):
  Debug Probe, prompt 46, line 1
  File "c:\Python27\Lib\site-packages\sklearn\feature_extraction\image.py", line 374, in extract_patches_2d
    extraction_step=1)
  File "c:\Python27\Lib\site-packages\sklearn\feature_extraction\image.py", line 296, in extract_patches
    patches = as_strided(arr, shape=shape, strides=strides)
  File "c:\Python27\Lib\site-packages\numpy\lib\stride_tricks.py", line 48, in as_strided
    array = np.asarray(DummyArray(interface, base=x))
  File "c:\Python27\Lib\site-packages\numpy\core\numeric.py", line 482, in asarray
    return array(a, dtype, copy=False, order=order)
ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.

This is a numpy memory error. What is causing that?

I get the feeling I don't follow entirely, lets make a tiny image and split that into pretty large sections

patches=extract_patches_2d(self.original_image[0:100,0:100],(50,50))

That works, but yields thousands of patches

len(patches)
2601

Not the ~ 4 I'd expect. What am I not understanding about this function? How do people go about getting patches, it seems like a common thing in computer vision.

Python 2.7 on Windows, packages recently installed and up to date

Ben@Laptop MINGW64 ~/Desktop
$ pip install -U scikit-learn

Requirement already up-to-date: scikit-learn in c:\python27\lib\site-packages
bw4sz
  • 2,237
  • 2
  • 29
  • 53
  • sklearn also has `extract_patches` (notice no _2d). In this function you can give the step between patches, like `extract_patches(img, (100,100,1), (100,100,1)).squeeze()` – user7138814 Jul 04 '17 at 21:17

1 Answers1

6

The function creates all possible combinations of patches from the given image. In your case, the first patch will span 0:49 pixels row wise and 0: 49 pixels column wise. The second patch from 1:50 row wise and column wise and o on. So if you have an image of size (m,n) and wish to extract patches of size (a,b) , then (m-a)+1 x (n-b+1) maximum possible patches can be extracted . In your case that is 51x 51 = 2601 patches.. If you want to limit the number of patches to be extracted, you can do so by the optional parameter by the max_ patches parameter.

Siva-Sg
  • 2,741
  • 19
  • 27
  • oh! That is radically different. All possible combinations! That is totally not mentioned in the docs! I'm looking to divide into consistent sub-grid, so patches of a given size that comprise the full image, not a window search. – bw4sz Jul 04 '17 at 16:12
  • 1
    Specifying `max_patches` means randomly choosing `max_patches` patches from all the combinations of the image. – mrtpk Jun 24 '19 at 12:01