def add_shape(self, f): #Create shape S = Shape(f, self.R, self.SHAPE_R) #Add to shape list S.shape_num = len(self.shape_list) self.shape_list.append(S) row = [] for k in range(len(self.shape_list)): T = self.shape_list[k] ift = real(ipfft(pft_mult(pft_rotate(S.pft, 2.*pi/6.), T.pft), 2*self.SHAPE_R+1,2*self.SHAPE_R+1)) Spad = imrotate(cpad(S.indicator, array([2*self.SHAPE_R+1,2*self.SHAPE_R+1])), 360./6.) Tpad = cpad(T.indicator, array([2*self.SHAPE_R+1,2*self.SHAPE_R+1])) pind = real(fftconvolve(Spad, Tpad, mode='same')) imshow(pind) imshow(ift) obst = to_ind(pind, 0.001) imshow(obst) cutoff = best_cutoff(ift, obst, S.radius + T.radius) print cutoff imshow(to_ind(ift, cutoff)) row.append(cutoff * self.tarea) self.cutoff_matrix.append(row) return S
from misc import * import fourier_obstacle as obstacle from polar import ipfft, pft_mult import os import pickle db = obstacle.ShapeSet(32, 256) db.add_shape(load_img("shape3.png")) db.add_shape(load_img("shape4.png")) A = db.shape_list[0] B = db.shape_list[1] pconv = ipfft(pft_mult(A.pft, B.pft), 513, 513) imsave("test1.png", pconv) imshow(pconv) #Contstruct sampled convolution field sconv = zeros((513, 513)) for i in range(513): for j in range(513): x = 257. - i y = 257. - j sconv[i, j] = db.potential(A, B, array([0., 0.]), array([x, y]), 0., pi/6.) print x,y, sconv[i,j] imsave("test2.png", sconv) imshow(sconv)
def __init__(self, mass_field, R, SHAPE_R): #Set basic parameters self.R = R self.SHAPE_R = SHAPE_R self.mass_field = mass_field self.mass = sum(mass_field.flatten()) #Recenter shape so that its center of mass is at the center of image center = array(ndi.center_of_mass(mass_field)) offset = array(mass_field.shape)/2 - center nshape = (array(mass_field.shape) + 2. * abs(offset)).round() tmp = cpad(mass_field, nshape) self.mass_field = ndi.shift(tmp, offset, order=1) self.center = array(self.mass_field.shape) / 2 assert(self.mass_field.shape[0] <= SHAPE_R) assert(self.mass_field.shape[1] <= SHAPE_R) #Set indicator/shape area self.indicator = to_ind(self.mass_field, 0.01) self.area = sum(self.indicator.flatten()) #Compute moment of inertia and radius self.moment = 0. self.radius = 0. for x,p in ndenumerate(self.mass_field): r = array(x) - self.center self.moment += p * dot(r,r) if(p > 0.01): self.radius = max(self.radius, norm(r)) #Set shape indicator self.shape_num = -1 #Compute polar fourier truncation of indicator pind = cpad(self.indicator, array([2*SHAPE_R+1,2*SHAPE_R+1])) self.pft = pfft(pind, R) ift = real(ipfft(self.pft, pind.shape[0], pind.shape[1])) self.pft[0][0] -= min(ift.flatten()) * ((2. * SHAPE_R + 1) ** 2) #Enforce positivity self.pdft = map(pds.diff, self.pft) #Compute cutoff parameters ift = real(ipfft(self.pft, pind.shape[0], pind.shape[1])) self.cutoff = best_cutoff(ift, pind, self.radius) ind_ift = to_ind(ift, self.cutoff) self.int_res = sum((ift * ind_ift).flatten()) self.ext_res = sum((ift * (1. - ind_ift)).flatten()) self.res_area = sum(ind_ift.flatten()) imshow(pind) imshow(to_ind(ift, self.cutoff)) #Compute residual energy terms self.energy = [] s = real(self.pft[0][0]) * pi for r,l in enumerate(self.pft): s += sum(abs(self.pft[r])) * (r * 2. * pi / len(self.pft[r])) self.energy.append(s) self.total_energy = s for r,e in enumerate(self.energy): self.energy[r] = s - self.energy[r]