|
18 | 18 | from scipy import kron, ones
|
19 | 19 | from scipy import sparse
|
20 | 20 | from scipy.io import loadmat as scipy_loadmat
|
| 21 | +import skimage |
21 | 22 |
|
22 | 23 |
|
23 | 24 | def build_logger(name, **kwargs):
|
@@ -391,6 +392,72 @@ def vec2mat(d, Nf):
|
391 | 392 | return np.reshape(d, (M / Nf, Nf, N), order='F')
|
392 | 393 |
|
393 | 394 |
|
| 395 | +def extract_patches(img, patch_shape=(3, 3)): |
| 396 | + r""" |
| 397 | + Extract a patch feature vector for every pixel of an image. |
| 398 | +
|
| 399 | + Parameters |
| 400 | + ---------- |
| 401 | + img : array |
| 402 | + Input image. |
| 403 | + patch_shape : tuple, optional |
| 404 | + Dimensions of the patch window. Syntax: (height, width), or (height,), |
| 405 | + in which case width = height. |
| 406 | +
|
| 407 | + Returns |
| 408 | + ------- |
| 409 | + array |
| 410 | + Feature matrix. |
| 411 | +
|
| 412 | + Notes |
| 413 | + ----- |
| 414 | + The feature vector of a pixel `i` will consist of the stacking of the |
| 415 | + intensity values of all pixels in the patch centered at `i`, for all color |
| 416 | + channels. So, if the input image has `d` color channels, the dimension of |
| 417 | + the feature vector of each pixel is (patch_shape[0] * patch_shape[1] * d). |
| 418 | +
|
| 419 | + Examples |
| 420 | + -------- |
| 421 | + >>> from pygsp import utils |
| 422 | + >>> import skimage |
| 423 | + >>> img = skimage.img_as_float(skimage.data.camera()[::2, ::2]) |
| 424 | + >>> X = utils.extract_patches(img) |
| 425 | +
|
| 426 | + """ |
| 427 | + |
| 428 | + try: |
| 429 | + h, w, d = img.shape |
| 430 | + except ValueError: |
| 431 | + try: |
| 432 | + h, w = img.shape |
| 433 | + d = 0 |
| 434 | + except ValueError: |
| 435 | + print("Image should be at least a 2-d array.") |
| 436 | + |
| 437 | + try: |
| 438 | + r, c = patch_shape |
| 439 | + except ValueError: |
| 440 | + r = patch_shape[0] |
| 441 | + c = r |
| 442 | + if d == 0: |
| 443 | + pad_width = ((int((r - 0.5) / 2.), int((r + 0.5) / 2.)), |
| 444 | + (int((c - 0.5) / 2.), int((c + 0.5) / 2.))) |
| 445 | + window_shape = (r, c) |
| 446 | + d = 1 # For the reshape in the return call |
| 447 | + else: |
| 448 | + pad_width = ((int((r - 0.5) / 2.), int((r + 0.5) / 2.)), |
| 449 | + (int((c - 0.5) / 2.), int((c + 0.5) / 2.)), |
| 450 | + (0, 0)) |
| 451 | + window_shape = (r, c, d) |
| 452 | + # Pad the image |
| 453 | + img_pad = skimage.util.pad(img, pad_width=pad_width, mode='symmetric') |
| 454 | + |
| 455 | + # Extract patches |
| 456 | + patches = skimage.util.view_as_windows(img_pad, window_shape=window_shape) |
| 457 | + |
| 458 | + return patches.reshape((h * w, r * c * d)) |
| 459 | + |
| 460 | + |
394 | 461 | def import_modules(names, src, dst):
|
395 | 462 | """Import modules in package."""
|
396 | 463 | for name in names:
|
|
0 commit comments