2013-08-21 10 views
8

Mam kod, który dzieli tablicę numpy na okrąg. Chciałbym odzyskać tylko wartości zawarte w pewnym zakresie kątów z okręgu i zamaskować tablicę. Na przykład: zamaskuj oryginalną tablicę z pozycjami (x, y) zawartymi pomiędzy 0 a 45 stopniami koła.Maskuj okrągły sektor w tablicy numpy

Czy jest to python?

Oto moje (uproszczone) oryginalny kod:

import numpy as np 
matrix = np.zeros((500,500)) 
x = 240 
y = 280 
radius = 10 
mask=np.ogrid[x-radius:x+radius+1,y-radius:y+radius+1] 
matrix[mask] 

góry dzięki

EDIT: I pominięte, że promień może być różna.

+2

Twój kod zamaskuje kwadrat w tablicy, a nie w kółko - czy to zdecydowanie krąg, który chcesz? –

+0

Tak, to jest. Widzę mój błąd i próbuję go rozwiązać! – Guadancil11

+0

Może to jest duplikat http://stackoverflow.com/q/8647024/832621 –

Odpowiedz

17

chciałbym to zrobić poprzez konwersję z kartezjański do współrzędnych biegunowych i konstruowaniu logicznych maski na kole i dla zakresu kątów chcesz:

import numpy as np 

def sector_mask(shape,centre,radius,angle_range): 
    """ 
    Return a boolean mask for a circular sector. The start/stop angles in 
    `angle_range` should be given in clockwise order. 
    """ 

    x,y = np.ogrid[:shape[0],:shape[1]] 
    cx,cy = centre 
    tmin,tmax = np.deg2rad(angle_range) 

    # ensure stop angle > start angle 
    if tmax < tmin: 
      tmax += 2*np.pi 

    # convert cartesian --> polar coordinates 
    r2 = (x-cx)*(x-cx) + (y-cy)*(y-cy) 
    theta = np.arctan2(x-cx,y-cy) - tmin 

    # wrap angles between 0 and 2*pi 
    theta %= (2*np.pi) 

    # circular mask 
    circmask = r2 <= radius*radius 

    # angular mask 
    anglemask = theta <= (tmax-tmin) 

    return circmask*anglemask 

Na przykład:

from matplotlib import pyplot as pp 
from scipy.misc import lena 

matrix = lena() 
mask = sector_mask(matrix.shape,(200,100),300,(0,50)) 
matrix[~mask] = 0 
pp.imshow(matrix) 
pp.show() 

enter image description here

+0

To działało idealnie, tego właśnie szukałem. Bardzo dziękuję – Guadancil11

+0

Cieszę się, że to słyszę! Powinieneś oznaczyć moją odpowiedź jako zaakceptowaną. –

+1

@ali_m +1. Mam nadzieję, że nie masz nic przeciwko, dodałem obrazek do odpowiedzi, abyśmy mogli dokładnie zobaczyć, co się dzieje. – Hooked

0

To samo podejście do wyśrodkowanych okręgów w kwadratowych matrycach:

def circleMask(mat, r=0): 
    if mat.shape[0] != mat.shape[1]: 
     raise TypeError('Matrix has to be square') 
    if not isinstance(r, int): 
     raise TypeError('Radius has to be of type int') 

    s = mat.shape[0] 
    d = num.abs(num.arange(-s/2 + s%2, s/2 + s%2)) 
    dm = num.sqrt(d[:, num.newaxis]**2 + d[num.newaxis, :]**2) 

    return num.logical_and(dm >= r-.5, dm < r+.5) 

Zapętlenie tej niejawnej funkcji jest kosztowne!