2016-09-24 4 views
0

Ich habe ein Bild Pyramide mit einer nach unten Abtastrate von 2. Das heißt, daß der Boden meiner Pyramide ist ein ist ein Bild der Form (256, 256), wo die nächste Ebene ist (128, 128) usw.Wie kann ich eine Teilmenge einer numpigen Matrix für die Platzierung einer kleineren Matrix angeben?

Mein Ziel ist dies anzuzeigen Pyramide in ein einzelnes Bild. Das erste Bild wird auf der linken Seite platziert. Der zweite befindet sich in der oberen rechten Ecke. Jedes nachfolgende Bild muss unter dem vorherigen platziert und in die Ecke eingekeilt werden.

Hier ist meine aktuelle Funktion:

def pyramid2img(pmd): 
    ''' 
    Given a pre-constructed pyramid, this is a helper 
    function to display the pyramid in a single image. 
    ''' 

    # orignal shape (pyramid goes from biggest to smallest) 
    org_img_shp = pmd[0].shape 

    # the output will have to have 1.5 times the width 
    out_shp = tuple(int(x*y) \ 
     for (x,y) in zip(org_img_shp, (1, 1.5))) 
    new_img = np.zeros(out_shp, dtype=np.int8) 

    # i keep track of the top left corner of where I want to 
    # place the current image matrix 
    origin = [0, 0] 
    for lvl, img_mtx in enumerate(pmd): 

     # trying to specify the subset to place the next img_mtx in 
     sub = new_img[origin[0]:origin[0]+pmd[lvl].shape[0], 
      origin[1]:origin[1]+pmd[lvl].shape[1]]# = img_mtx 

     # some prints to see exactly whats being called above^
     print 'level {}, sub {}, mtx {}'.format(
      lvl, sub.shape, img_mtx.shape) 
     print 'sub = new_img[{}:{}, {}:{}]'.format(
      origin[0], origin[0]+pmd[lvl].shape[0], 
      origin[1], origin[1]+pmd[lvl].shape[1]) 

     # first shift moves the origin to the right 
     if lvl == 0: 
      origin[0] += pmd[lvl].shape[0] 
     # the rest move the origin downward 
     else: 
      origin[1] += pmd[lvl].shape[1] 

    return new_img 

Ausgabe von der PRINT AUSSAGEN:

level 0, sub (256, 256), mtx (256, 256) 
sub = new_img[0:256, 0:256] 


level 1, sub (0, 128), mtx (128, 128) 
sub = new_img[256:384, 0:128] 


level 2, sub (0, 64), mtx (64, 64) 
sub = new_img[256:320, 128:192] 


level 3, sub (0, 32), mtx (32, 32) 
sub = new_img[256:288, 192:224] 


level 4, sub (0, 16), mtx (16, 16) 
sub = new_img[256:272, 224:240] 


level 5, sub (0, 8), mtx (8, 8) 
sub = new_img[256:264, 240:248] 


level 6, sub (0, 4), mtx (4, 4) 
sub = new_img[256:260, 248:252] 

Wenn Sie am Ausgang anschaut, kann man sehen, dass ich eine 2d-Scheibe zu verweisen versuchen des Ausgabebildes, so dass ich die nächste Ebene der Pyramide darin platzieren kann.

Das Problem ist, dass das Slicing, das ich ausführe, kein 2d-Array mit der Form gibt, die ich auch erwarte. Ich denke, ich versuche eine (n, n) Matrix in eine (0, n) Matrix zu bringen.

Wie kommt es, wenn ich ein Stück wie new_img[256:320, 128:192] angeben, gibt es ein Objekt mit der Form (0, 64), nicht (64, 64)?

Gibt es eine einfachere Möglichkeit zu tun, was ich versuche zu tun?

Antwort

1

Hier ist ein Beispiel.

eine Pyramide erstellen zuerst:

import numpy as np 
import pylab as pl 
import cv2 

img = cv2.imread("earth.jpg")[:, :, ::-1] 

size = 512 
imgs = [] 
while size >= 2: 
    imgs.append(cv2.resize(img, (size, size))) 
    size //= 2 

Und hier ist der Code, um die Bilder zu fusionieren:

def align(size, width, loc): 
    if loc in ("left", "top"): 
     return 0 
    elif loc in ("right", "bottom"): 
     return size - width 
    elif loc == "center": 
     return (size - width) // 2 

def resize_canvas(img, shape, loc, fill=255): 
    new_img = np.full(shape + img.shape[2:], fill, dtype=img.dtype) 
    y = align(shape[0], img.shape[0], loc[0]) 
    x = align(shape[1], img.shape[1], loc[1]) 
    new_img[y:y+img.shape[0], x:x+img.shape[1], ...] = img 
    return new_img 

def vbox(imgs, align="right", fill=255): 
    width = max(img.shape[1] for img in imgs) 
    return np.concatenate([ 
      resize_canvas(img, (img.shape[0], width), ("top", align), fill=fill) 
      for img in imgs 
     ]) 

def hbox(imgs, align="top", fill=255): 
    height = max(img.shape[0] for img in imgs) 
    return np.concatenate([ 
      resize_canvas(img, (height, img.shape[1]), (align, "left"), fill=fill) 
      for img in imgs 
     ], axis=1) 

die Ausgabe von:

pl.imshow(hbox([imgs[0], vbox(imgs[1:])])) 

enter image description here

+0

Wow, was für Eine clevere Art das zu tun ! Vielen Dank :) Ich begann zu lesen über numpy slicing/schreiten über http://stackoverflow.com/questions/4257394/slicing-of-a-numpy-2d-array-or-how-do-i-extract -an-mxm-submatrix-from-a-nxn-ar , die wie ein Albtraum schien. Ihre Lösung ist sehr intuitiv. Vielen Dank. – spanishgum

Verwandte Themen