def rotate_zero_shift_image(_img, _angle_lim = 1.5, _angle_step = 0.1, _edge = .1, crop = False): top = []; bottom = []; left = []; right = [] angles = np.arange(-_angle_lim, _angle_lim, _angle_step) for i in range(len(angles)): img = ndimage.interpolation.rotate(_img, angles[i], reshape = False, mode = 'nearest') img = ndimage.morphological_laplace(img, 5) h_line = np.mean(img, axis = 1) v_line = np.mean(img, axis = 0) h_line = savgol_filter(x = h_line, window_length = 15, polyorder = 2, mode = 'mirror', deriv = 0) v_line = savgol_filter(x = v_line, window_length = 15, polyorder = 2, mode = 'mirror', deriv = 0) j = np.where( h_line == h_line[:int(h_line.shape[0]*_edge)].min() )[0][0] top.append( [ h_line[ j ], j, angles[i] ] ) j = np.where( h_line == h_line[-int(h_line.shape[0]*_edge):].min() )[0][0] bottom.append( [ h_line[ j ], j, angles[i] ] ) j = np.where( v_line == v_line[:int(v_line.shape[0]*_edge)].min() )[0][0] left.append( [ v_line[ j ], j, angles[i] ] ) j = np.where( v_line == v_line[-int(v_line.shape[0]*_edge):].min() )[0][0] right.append( [ v_line[ j ], j, angles[i] ] ) top = np.stack(top, axis = 0) bottom = np.stack(bottom, axis = 0) left = np.stack(left, axis = 0) right = np.stack(right, axis = 0) # get average of edges avg = [] sets = [top, bottom, left, right] for i in range(len(sets)): _set = sets[i][np.argsort(sets[i][:,2]),:] avg.append(_set[:, 0]) avg = np.median( np.vstack(avg).T, axis = 1) sy = savgol_filter(x = avg, window_length = 15, polyorder = 2, mode = 'mirror', deriv = 0) j = np.where(sy == sy.min())[0] angle = sets[0][j, 2][0] edges = [ s[j, 1] for s in sets ] # rotate image by reverse angle img = ndimage.interpolation.rotate(_img, angle, reshape = False, mode = 'nearest') # shift image to top-left zero img = ndimage.interpolation.shift(_img, shift = [-int(edges[0]), -int(edges[2])], mode = 'nearest') if crop: # crop image to edges img = img[ int(edges[0]):int(edges[1]), int(edges[2]):int(edges[3]) ] return img
def test_morphological_laplace_operation_sparse_input_struct_zeros(self): struct = np.zeros((3, 3, 3)) print( "\n test_morphological_laplace_operation_sparse_input_struct_zeros..." ) v_output = vc.morphological_laplace(input_svar, structure=struct, make_float32=False) d_output = ndimage.morphological_laplace(input_svar, structure=struct) msgs = "test_morphological_laplace_operation_sparse_input_struct_zeros" self.assertTrue((d_output == v_output).all(), msg=msgs)
def __test_morphological_laplace_operation(self,input_var): print("\n morphological_laplace Voxel testing...") start_time = t.time() v_output = vc.morphological_laplace(input_var,structure=structure,no_of_blocks=PL[0],fakeghost=PL[1],make_float32=False) print("morphological_laplace Voxel testing time taken: ",(t.time() - start_time)," sec") #print("\n morphological_laplace Default testing...") start_time = t.time() d_output = ndimage.morphological_laplace(input_var,structure=structure) print("morphological_laplace Default testing time taken: ",(t.time() - start_time)," sec") msgs = "morphological_laplace_operation_FAIL_with parameters: ",PL self.assertTrue((d_output==v_output).all(), msg=msgs)
def test_morphological_laplace_operation_sparse_input_default_value(self): print( "\n test_morphological_laplace_operation_sparse_input_default_value..." ) v_output = vc.morphological_laplace(input_svar, structure=structure, make_float32=False) d_output = ndimage.morphological_laplace( input_svar, structure=structure, ) msgs = "test_morphological_laplace_operation_sparse_input_default_value" self.assertTrue((d_output == v_output).all(), msg=msgs)
def test_morphological_laplace_operation_sparse_input_blocks_ten(self): print( "\n test_morphological_laplace_operation_sparse_input_blocks_ten..." ) v_output = vc.morphological_laplace(input_svar, structure=structure, no_of_blocks=10, make_float32=False) d_output = ndimage.morphological_laplace( input_svar, structure=structure, ) msgs = "test_morphological_laplace_operation_sparse_input_blocks_ten" self.assertTrue((d_output == v_output).all(), msg=msgs)
def test_morphological_laplace_operation_dense_input_fakeghost_four(self): print( "\n test_morphological_laplace_operation_dense_input_fakeghost_four..." ) v_output = vc.morphological_laplace(input_dvar, structure=structure, fakeghost=4, make_float32=False) d_output = ndimage.morphological_laplace( input_dvar, structure=structure, ) msgs = "test_morphological_laplace_operation_dense_input_fakeghost_four" self.assertTrue((d_output == v_output).all(), msg=msgs)
def __operationTask(self,input_var): ''' perform respective moephological operation on input block. Parameters ---------- input_var : type: 3d numpy array, ith block. Returns ------- output : type: 3d array, output of operation, ith block array. ''' D=self.__operationArgumentDic if self.__operation=="binary_closing": return ndimage.binary_closing(input_var, structure=D["structure"], iterations=D["iterations"], output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"], brute_force=D["brute_force"]) elif self.__operation=="binary_dilation": return ndimage.binary_dilation(input_var, structure=D["structure"], iterations=D["iterations"], output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"], brute_force=D["brute_force"]) elif self.__operation=="binary_erosion": return ndimage.binary_erosion(input_var, structure=D["structure"], iterations=D["iterations"], output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"], brute_force=D["brute_force"]) elif self.__operation=="binary_fill_holes": #the output might be different then scipy.ndimage return ndimage.binary_fill_holes(input_var, structure=D["structure"],output=D["output"], origin=D["origin"]) elif self.__operation=="binary_hit_or_miss": return ndimage.binary_hit_or_miss(input_var, structure1=D["structure1"],structure2=D["structure2"],output=D["output"], origin1=D["origin1"], origin2=D["origin2"]) elif self.__operation=="binary_opening": return ndimage.binary_opening(input_var, structure=D["structure"], iterations=D["iterations"], output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"], brute_force=D["brute_force"]) elif self.__operation=="binary_propagation": return ndimage.binary_propagation(input_var, structure=D["structure"],output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"]) elif self.__operation=="black_tophat": return ndimage.black_tophat(input_var, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif self.__operation=="grey_dilation": return ndimage.grey_dilation(input_var, structure=D["structure"],size=D["size"], footprint=D["footprint"],output=D["output"], mode=D["mode"], cval=D["cval"], origin=D["origin"]) elif self.__operation=="grey_closing": return ndimage.grey_closing(input_var, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif self.__operation=="grey_erosion": return ndimage.grey_erosion(input_var, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif self.__operation=="grey_opening": return ndimage.grey_opening(input_var, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif self.__operation=="morphological_gradient": return ndimage.morphological_gradient(input_var, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif self.__operation=="morphological_laplace": return ndimage.morphological_laplace(input_var, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif self.__operation=="white_tophat": return ndimage.white_tophat(input_var, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif self.__operation=="multiply": return input_var*D["scalar"] else: return input_var # no operation performed....
def get_skel_distance_trans(img, radius_laplace): ################# img = img.astype(np.float32) threshold = img > 0 skeleton = np.zeros(img.shape) distance_image = ndimage.distance_transform_edt(threshold) morph_laplace_image = ndimage.morphological_laplace(distance_image, (radius_laplace,radius_laplace)) skel = morph_laplace_image < morph_laplace_image.min()/2 skeleton[skel] = 1 # import pdb; pdb.set_trace() cv2.imshow('t',skeleton) cv2.waitKey(0) ############### # skel = skel.astype(np.uint8) # indexes = np.where(skel > 0) return skel.astype(np.uint8)
def edgedetection(imgarray,mode="sobel",size=3): """ Edge detection functions Parameters ---------- imgarray : Image as ndArray. Satellite image as n-Dim numpy array.. mode : type of filter , optional "sobel", "sobelH", "sobelV", "laplace", "prewitt", "prewittH","prewittV". The default is "sobel". size : Size of kernel for laplace, optional kernel size only for laplace edge detection. The default is 3. Returns ------- Edge detection on satellite image. """ if mode=="sobel": sobel_v=scind.filters.sobel(imgarray,axis=-1) sobel_h=scind.filters.sobel(imgarray,axis=1) out=(sobel_v+sobel_h)/2 elif mode=="sobelH": out=scind.filters.sobel(imgarray,axis=1) elif mode=="sobelV": out=scind.filters.sobel(imgarray,axis=-1) elif mode=="laplace": out=scind.morphological_laplace(imgarray,size=size) elif mode=="prewitt": prewitt_v=scind.filters.prewitt(imgarray,axis=-1) prewitt_h=scind.filters.prewitt(imgarray,axis=1) out=(prewitt_v+prewitt_h)/2 elif mode=="prewittH": out=scind.filters.prewitt(imgarray,axis=1) elif mode=="prewittV": out=scind.filters.prewitt(imgarray,axis=-1) else: print("Please provide a valid statistical method: mean, median or mode") return out
def operationTask(input): D=operationArgumentDic #self.M.add_mem()#..................................................................................................... if operation=="binary_closing": return ndimage.binary_closing(input, structure=D["structure"], iterations=D["iterations"], output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"], brute_force=D["brute_force"]) elif operation=="binary_dilation": return ndimage.binary_dilation(input, structure=D["structure"], iterations=D["iterations"], output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"], brute_force=D["brute_force"]) elif operation=="binary_erosion": return ndimage.binary_erosion(input, structure=D["structure"], iterations=D["iterations"], output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"], brute_force=D["brute_force"]) elif operation=="binary_fill_holes": return ndimage.binary_fill_holes(input, structure=D["structure"],output=D["output"], origin=D["origin"]) elif operation=="binary_hit_or_miss": return ndimage.binary_hit_or_miss(input, structure1=D["structure1"],structure2=D["structure2"],output=D["output"], origin1=D["origin1"], origin2=D["origin2"]) elif operation=="binary_opening": return ndimage.binary_opening(input, structure=D["structure"], iterations=D["iterations"], output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"], brute_force=D["brute_force"]) elif operation=="binary_propagation": return ndimage.binary_propagation(input, structure=D["structure"],output=D["output"], origin=D["origin"], mask=D["mask"], border_value=D["border_value"]) elif operation=="black_tophat": return ndimage.black_tophat(input, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif operation=="grey_dilation": return ndimage.grey_dilation(input, structure=D["structure"],size=D["size"], footprint=D["footprint"],output=D["output"], mode=D["mode"], cval=D["cval"], origin=D["origin"]) elif operation=="grey_closing": return ndimage.grey_closing(input, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif operation=="grey_erosion": return ndimage.grey_erosion(input, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif operation=="grey_opening": return ndimage.grey_opening(input, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif operation=="morphological_gradient": return ndimage.morphological_gradient(input, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif operation=="morphological_laplace": return ndimage.morphological_laplace(input, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif operation=="white_tophat": return ndimage.white_tophat(input, structure=D["structure"], size=D["size"], footprint=D["footprint"], output=D["output"], origin=D["origin"],mode=D["mode"], cval=D["cval"]) elif operation=="intMultiply": return input*D["scalar"] else: return input
def morphological_laplace(img, params): if params['footprint_shape'] == 'rectangle': footprint = np.ones( (params['footprint_size_y'], params['footprint_size_x']), dtype=int) elif params['footprint_shape'] == 'ellipse': a = params['footprint_size_x'] / 2 b = params['footprint_size_y'] / 2 x, y = np.mgrid[-ceil(a):ceil(a) + 1, -ceil(b):ceil(b) + 1] footprint = ((x / a)**2 + (y / b)**2 < 1) * 1 mode = params['mode'] cval = params['cval'] origin = params['origin'] return ndimage.morphological_laplace(img, size=None, footprint=footprint, structure=None, mode=mode, cval=cval, origin=origin)
def main(): structure = np.ones((3, 3, 3)) #.............test1. dense....... filename = 'gyroidUniform.npy' input = np.load(filename, mmap_mode="r") print( "..............................dense.............................................." ) #0.Nothing.............. print("\n nothing testing...") output = vc.nothing(input, blockSize=50, fakeGhost=4, makeFloat32=False) print("\nresult: ", (input == output).all()) print(output.dtype, input.dtype) #1.grey_dilation.............. print("\ngrey_dilation VoxelProcessind") output = vc.grey_dilation(input, structure=structure, makeFloat32=False) print("\ngrey_dilation Default") d = ndimage.grey_dilation(input, structure=structure) print("\nresult: ", (d == output).all()) print(output.dtype, input.dtype) #2.grey_erosion.............. print("\ngrey_erosion VoxelProcessind") output = vc.grey_erosion(input, makeFloat32=False, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\ngrey_erosion Default") d = ndimage.grey_erosion(input, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nresult: ", (d == output).all()) #3.grey_closing.............. print("\ngrey_closing VoxelProcessind") output = vc.grey_closing(input, makeFloat32=False, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\ngrey_closing Default") d = ndimage.grey_closing(input, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nresult: ", (d == output).all()) print(output.dtype, input.dtype) #4.grey_opening.............. print("\ngrey_opening VoxelProcessind") output = vc.grey_opening(input, makeFloat32=False, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\ngrey_opening Default") d = ndimage.grey_opening(input, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nresult: ", (d == output).all()) #5.binary_closing.............. print("\nbinary_closing VoxelProcessind") output = vc.binary_closing(input, makeFloat32=False, structure=None, iterations=1, output=None, origin=0, mask=None, border_value=0, brute_force=False) print("\nbinary_closing Default") d = ndimage.binary_closing(input, structure=None, iterations=1, output=None, origin=0, mask=None, border_value=0, brute_force=False) print("\nresult: ", (d == output).all()) print(output[151][151][151]) #6.binary_opening.............. print("\nbinary_opening VoxelProcessind") output = vc.binary_opening(input, structure=None, iterations=1, output=None, origin=0, mask=None, border_value=0, brute_force=False) print("\nbinary_opening Default") d = ndimage.binary_opening(input, structure=None, iterations=1, output=None, origin=0, mask=None, border_value=0, brute_force=False) print("\nresult: ", (d == output).all()) #7.binary_dilation.............. print("\nbinary_dilation VoxelProcessind") output = vc.binary_dilation(input, makeFloat32=False, structure=structure, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False) print("\nbinary_dilation Default") d = ndimage.binary_dilation(input, structure=structure, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False) print("\nresult: ", (d == output).all()) #8.binary_erosion.............. print("\nbinary_erosion VoxelProcessind") output = vc.binary_erosion(input, makeFloat32=False, structure=None, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False) print("\nbinary_erosion Default") d = ndimage.binary_erosion(input, structure=None, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False) print("\nresult: ", (d == output).all()) #9.binary_fill_holes.............. print("\nbinary_fill_holes VoxelProcessind") output = vc.binary_fill_holes(input, makeFloat32=False, structure=None, output=None, origin=0) print("\nbinary_fill_holes Default") d = ndimage.binary_fill_holes(input, structure=None, output=None, origin=0) print("\nresult: ", (d == output).all()) #10.binary_hit_or_miss.............. print("\nbinary_hit_or_miss VoxelProcessind") output = vc.binary_hit_or_miss(input, makeFloat32=False, structure1=None, structure2=None, output=None, origin1=0, origin2=None) print("\nbinary_hit_or_miss Default") d = ndimage.binary_hit_or_miss(input, structure1=None, structure2=None, output=None, origin1=0, origin2=None) print("\nresult: ", (d == output).all()) #11.binary_propagation.............. print("\nbinary_propagation VoxelProcessind") output = vc.binary_propagation(input, makeFloat32=False, structure=None, mask=None, output=None, border_value=0, origin=0) print("\nbinary_propagation Default") d = ndimage.binary_propagation(input, structure=None, mask=None, output=None, border_value=0, origin=0) print("\nresult: ", (d == output).all()) #12.black_tophat.............. print("\nblack_tophat VoxelProcessind") output = vc.black_tophat(input, makeFloat32=False, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nblack_tophat Default") d = ndimage.black_tophat(input, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nresult: ", (d == output).all()) #13.morphological_gradient.............. print("\nmorphological_gradient VoxelProcessind") output = vc.morphological_gradient(input, makeFloat32=False, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nmorphological_gradient Default") d = ndimage.morphological_gradient(input, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nresult: ", (d == output).all()) #14.morphological_laplace.............. print("\nmorphological_laplace VoxelProcessind") output = vc.morphological_laplace(input, makeFloat32=False, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nmorphological_laplace Default") d = ndimage.morphological_laplace(input, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nresult: ", (d == output).all()) #15.white_tophat.............. print("\nwhite_tophat VoxelProcessind") output = vc.white_tophat(input, makeFloat32=False, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nwhite_tophat VoxelProcessind Default") d = ndimage.white_tophat(input, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("\nresult: ", (d == output).all()) #16.intMultiply.............. print("\nintMultiply VoxelProcessind") output = vc.intMultiply(input, makeFloat32=False, blockSize=50, fakeGhost=1, scalar=10) print("\nintMultiply Default") d = input * 10 print("\nresult: ", (d == output).all()) print( "..............................Sparse.............................................." ) input = random(400, 80000, density=0.3, dtype="float64") input = input.todense() input = np.array(input) input = np.reshape(input, (400, 200, 400)) #0.Nothing.............. print("\n nothing testing...") output = vc.nothing(input, makeFloat32=False) print("\nresult: ", (input == output).all()) print(output.dtype, input.dtype) #1.grey_dilation.............. print("\ngrey_dilation VoxelProcessind") output = vc.grey_dilation(input, structure=structure, makeFloat32=False) print("\ngrey_dilation Default") d = ndimage.grey_dilation(input, structure=structure) print("\nresult: ", (d == output).all()) print(output.dtype, input.dtype) #2.grey_erosion.............. print("\ngrey_erosion VoxelProcessind") output = vc.grey_erosion(input, makeFloat32=False, structure=structure) print("\ngrey_erosion Default") d = ndimage.grey_erosion(input, structure=structure) print("\nresult: ", (d == output).all()) #3.grey_closing.............. print("\ngrey_closing VoxelProcessind") output = vc.grey_closing(input, makeFloat32=False, structure=structure) print("\ngrey_closing Default") d = ndimage.grey_closing(input, structure=structure) print("\nresult: ", (d == output).all()) print(output.dtype, input.dtype) #4.grey_opening.............. print("\ngrey_opening VoxelProcessind") output = vc.grey_opening(input, makeFloat32=False, structure=structure) print("\ngrey_opening Default") d = ndimage.grey_opening(input, structure=structure) print("\nresult: ", (d == output).all()) #5.binary_closing.............. print("\nbinary_closing VoxelProcessind") output = vc.binary_closing(input, makeFloat32=False) print("\nbinary_closing Default") d = ndimage.binary_closing(input) print("\nresult: ", (d == output).all()) #6.binary_opening.............. print("\nbinary_opening VoxelProcessind") output = vc.binary_opening(input, makeFloat32=False) print("\nbinary_opening Default") d = ndimage.binary_opening(input) print("\nresult: ", (d == output).all()) #7.binary_dilation.............. print("\nbinary_dilation VoxelProcessind") output = vc.binary_dilation(input, makeFloat32=False, structure=structure) print("\nbinary_dilation Default") d = ndimage.binary_dilation(input, structure=structure) print("\nresult: ", (d == output).all()) #8.binary_erosion.............. print("\nbinary_erosion VoxelProcessind") output = vc.binary_erosion(input, makeFloat32=False) print("\nbinary_erosion Default") d = ndimage.binary_erosion(input) print("\nresult: ", (d == output).all()) #9.binary_fill_holes.............. print("\nbinary_fill_holes VoxelProcessind") output = vc.binary_fill_holes(input, makeFloat32=False) print("\nbinary_fill_holes Default") d = ndimage.binary_fill_holes(input) print("\nresult: ", (d == output).all()) #10.binary_hit_or_miss.............. print("\nbinary_hit_or_miss VoxelProcessind") output = vc.binary_hit_or_miss(input, makeFloat32=False) print("\nbinary_hit_or_miss Default") d = ndimage.binary_hit_or_miss(input) print("\nresult: ", (d == output).all()) #11.binary_propagation.............. print("\nbinary_propagation VoxelProcessind") output = vc.binary_propagation(input, makeFloat32=False) print("\nbinary_propagation Default") d = ndimage.binary_propagation(input) print("\nresult: ", (d == output).all()) #12.black_tophat.............. print("\nblack_tophat VoxelProcessind") output = vc.black_tophat(input, makeFloat32=False, structure=structure) print("\nblack_tophat Default") d = ndimage.black_tophat(input, structure=structure) print("\nresult: ", (d == output).all()) #13.morphological_gradient.............. print("\nmorphological_gradient VoxelProcessind") output = vc.morphological_gradient( input, structure=structure, makeFloat32=False, ) print("\nmorphological_gradient Default") d = ndimage.morphological_gradient(input, structure=structure) print("\nresult: ", (d == output).all()) #14.morphological_laplace.............. print("\nmorphological_laplace VoxelProcessind") output = vc.morphological_laplace(input, structure=structure, makeFloat32=False) print("\nmorphological_laplace Default") d = ndimage.morphological_laplace(input, structure=structure) print("\nresult: ", (d == output).all()) #15.white_tophat.............. print("\nwhite_tophat VoxelProcessind") output = vc.white_tophat(input, makeFloat32=False, structure=structure) print("\nwhite_tophat VoxelProcessind Default") d = ndimage.white_tophat(input, structure=structure) print("\nresult: ", (d == output).all()) #16.intMultiply.............. print("\nintMultiply VoxelProcessind") output = vc.intMultiply(input, makeFloat32=False, scalar=10) print("\nintMultiply Default") d = input * 10 print("\nresult: ", (d == output).all())
# Can we find the contour pixel positions of the otsu filtered image edges? # approach 1: Canny filtering the otsu filtered image canny_filter_im_edge = feature.canny(otsu_imArray, sigma=1.0) canny_filter_img = mi.toimage(canny_filter_im_edge) #canny_filter_img.show() f1, ax1 = plt.subplots() ax1.imshow(canny_filter_img, cmap='gray') ax1.set_title('Canny Filtered Otsu Threshold Image') plt.show() # approach 2 laplace filtering the otsu filtered image radius = 10 distance_img = ndimage.distance_transform_edt(otsu_imArray) morph_laplace_img = ndimage.morphological_laplace(distance_img, (radius, radius)) skeleton = morph_laplace_img < morph_laplace_img.min() / 2 # figure showing effectiveness of Otsu-Laplace filtered image f2, ax = plt.subplots(1, 3) ax[0].imshow(imArray, cmap=cm.Greys_r) ax[0].set_title('Raw Image') ax[0].set_xlabel('X Pixel Coordinates') ax[0].set_ylabel('Y Pixel Coordinates') ax[1].imshow(otsu_imArray, cmap=cm.Greys_r) ax[1].set_title('Otsu Filtered Image') ax[1].set_xlabel('X Pixel Coordinates') ax[1].set_ylabel('Y Pixel Coordinates') ax[2].imshow(skeleton, cmap=cm.Greys_r) ax[2].set_title('Otsu-Laplace Filtered Image') ax[2].set_xlabel('X Pixel Coordinates')
def sharpen(img, bg=None, t='laplace', blur_radius=30, blur_guided_eps=1e-8, use_guidedfilter='if_large_img'): """Use distortion model to deblur image. Equivalent to usharp mask: 1/t * img - (1-1/t) * blurry(img) Then, apply guided filter to smooth result but preserve edges. img - image to sharpen, assume normalized in [0,1] bg - image background t - the transmission map (inverse amount of sharpening) can be scalar, matrix of same (h, w) as img, or 3 channel image. By default, use a multi-channel sharpened laplace filter on a smoothed image with 10x10 kernel. For enhancing fine details in large images. use_guidedfilter - a bool or the string 'if_large_img' determining whether to clean up the resulting sharpened image. If the min image dimension is less that 1500, this cleanup operation may blur the image, ruining its quality. """ if bg is None: bg = np.zeros(img.shape[:2], dtype='bool') else: img = img.copy() img[bg] = 0 # assert np.isnan(img).sum() == 0 # assert np.isnan(t).sum() == 0 # blurring (faster than ndi.gaussian_filter(I) A = cv2.ximgproc.guidedFilter( # radiance.astype('float32'), img.astype('float32'), img.astype('float32'), blur_radius, blur_guided_eps) if t == 'laplace': t = 1-util.norm01(sharpen(ndi.morphological_laplace( img, (2,2,1), mode='wrap'), bg, 0.15), bg) # t = 1-util.norm01(ndi.morphological_laplace( # img, (2,2,1), mode='wrap'), bg) # todo note: laplace t is 01 normalized. should we keep the max # and just normalize the lower range (or vice versa or something)? # note2: if laplace is all zeros (due to bad input img), t will be all nan. if len(np.shape(t)) + 1 == len(img.shape): t_refined = np.expand_dims(t, -1).astype('float') else: t_refined = t if np.shape(t): t_refined[bg] = 1 # ignore background, but fix division by zero J = ( img.astype('float')-A) / np.maximum(1e-8, np.maximum(t_refined, np.min(t_refined)/2)) + A # assert np.isnan(J).sum() == 0 if bg is not None: J[bg] = 0 # applying a guided filter for smoothing image at this point can be # problematic to the image quality, significantly blurring it. if use_guidedfilter == 'if_large_img': # note: at some point, find a better threshold? This works. use_guidedfilter = min(J.shape[0], J.shape[1]) >= 1500 if not use_guidedfilter: J = check_and_fix_nan(J, img) return J r2 = cv2.ximgproc.guidedFilter( img.astype('float32'), J.astype('float32'), 2, 1e-8) r2 = check_and_fix_nan(r2, img) if bg is not None: r2[bg] = 0 return r2
def run(self, show=False): # Load data filename = self.filename d = pyfits.getdata(filename) h = pyfits.getheader(filename) path, filename = os.path.split(filename) # Get wavelength calibration z = np.arange(h['naxis3']) w = h['CRVAL3'] + h['CDELT3'] * (z - h['CRPIX3']) # Convert wavelength from nm to Angstrom # if w.all() < 1000.: # w *= 10 # Signal-to-noise clipping s = d.sum(axis=2) s = s.sum(axis=1) gauss_p, _ = self.fit_gaussian(z, s) log.debug("Gaussian parameters ---") log.debug("p[0] = %.2f" % gauss_p[0]) log.debug("p[1] = %.2f" % gauss_p[1]) log.debug("p[2] = %.2f" % gauss_p[2]) log.debug("p[3] = %.2f" % gauss_p[3]) lor_p = self.fit_lorentzian(z, s) log.debug("Lorentzian parameters ---") log.debug("p[0] = %.2f" % lor_p[0]) log.debug("p[1] = %.2f" % lor_p[1]) log.debug("p[2] = %.2f" % lor_p[2]) log.debug("p[3] = %.2f" % lor_p[3]) fwhm = np.abs(gauss_p[2] * 2 * np.sqrt(2 * np.log(2))) filter_ = np.where(np.abs(z - gauss_p[1]) < fwhm, True, False) if show: plt.plot(z, self.gaussian(gauss_p, z), 'r-', lw=2, label='Gaussian Fit') plt.plot(z, self.lorentzian(lor_p, z), 'b-', lw=2, label='Lorentzian Fit') plt.plot(z, s, 'ko') plt.plot(z[filter_], s[filter_], 'ro') plt.title('Cube collapsed in XY and fits.') plt.grid() plt.legend(loc='best') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.show() signal = d[filter_].mean(axis=0) noise = d[np.logical_not(filter_)].mean(axis=0) snr = signal / noise snr = ndimage.median_filter(snr, 3) snr_mask = np.where(snr > 2, True, False) snr_laplacian = ndimage.morphological_laplace(snr * snr_mask, size=3) snr_mask *= np.where(np.abs(snr_laplacian) < 5.0, True, False) snr_mask = ndimage.binary_opening(snr_mask, iterations=5) snr_mask = ndimage.binary_closing(snr_mask, iterations=5) if show: fig1 = plt.figure(figsize=(20, 5)) plt.title('Signal-to-Noise Ratio') gs = GridSpec(1, 3) ax1 = plt.subplot(gs[0]) ax1.set_title('SNR') im1 = ax1.imshow(snr, cmap='cubehelix', interpolation='nearest', origin='lower', vmin=0) div1 = make_axes_locatable(ax1) cax1 = div1.append_axes("right", size="5%", pad=0.05) cbar1 = plt.colorbar(mappable=im1, cax=cax1, use_gridspec=True, orientation='vertical') ax2 = plt.subplot(gs[1]) ax2.set_title('Mask') im2 = ax2.imshow(np.where(snr_mask, 1, 0), cmap='gray', interpolation='nearest', origin='lower', vmin=0, vmax=1) div2 = make_axes_locatable(ax2) cax2 = div2.append_axes("right", size="5%", pad=0.05) cbar2 = plt.colorbar(mappable=im2, cax=cax2, use_gridspec=True, orientation='vertical') cmap = plt.get_cmap('cubehelix') cmap.set_bad('w', 1.0) ax3 = plt.subplot(gs[2]) ax3.set_title('Masked') im3 = ax3.imshow(np.ma.masked_where(~snr_mask, snr), cmap=cmap, interpolation='nearest', origin='lower', vmin=0) div3 = make_axes_locatable(ax3) cax3 = div3.append_axes("right", size="5%", pad=0.05) cbar3 = plt.colorbar(mappable=im3, cax=cax3, use_gridspec=True, orientation='vertical') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) gs.tight_layout(fig1) plt.show() pyfits.writeto(filename.replace('.','.SNR.'), snr, h, clobber=True) pyfits.writeto(filename.replace('.','.SNR_LAPLACIAN.'), snr_laplacian, h, clobber=True) # Adjust continuum continuum = self.fit_continuum(d) # Subtract continuum continuum = np.reshape(continuum, (continuum.size, 1, 1)) continuum = np.repeat(continuum, d.shape[1], axis=1) continuum = np.repeat(continuum, d.shape[2], axis=2) d -= continuum del continuum # Save the data-cube with the continuum subtracted pyfits.writeto(os.path.join(path, filename.replace('.fits', '.no_cont.fits')), d, h, clobber=True) # Adjust each pixel to a gaussian flux = np.zeros_like(snr) - np.inf velocity = np.zeros_like(snr) - np.inf width = np.zeros_like(snr) - np.inf continuum = np.zeros_like(snr) - np.inf niter = np.zeros_like(snr) - np.inf fit_gauss_cube = np.zeros_like(d) for (j, i) in itertools.product(range(d.shape[1]), range(d.shape[2])): if snr_mask[j, i]: p, s = self.fit_gaussian(w, d[:,j,i]) else: p, s = [-np.inf, -np.inf, -np.inf, -np.inf], -1 flux[j, i] = p[0] velocity[j, i] = p[1] width[j, i] = p[2] continuum[j, i] = p[3] niter[j,i] = s fit_gauss_cube[:, j, i] = self.gaussian(p, w) log.debug("%04d %04d" % (j, i)) mask = np.ma.masked_equal(snr_mask, False) pyfits.writeto(os.path.join(path, filename.replace('.fits', '.GAUSS.fits')), fit_gauss_cube, h, clobber=True) if show: fig1 = plt.figure(figsize=(16,6)) plt.title('Final Results') gs = GridSpec(2, 3) magma = plt.get_cmap('magma') magma.set_bad('w', 1.0) ax1 = plt.subplot(gs[0]) ax1.set_title('Collapsed cube') im1 = ax1.imshow(np.ma.masked_where(~snr_mask, d.sum(axis=0)), cmap=magma, interpolation='nearest', origin='lower') divider1 = make_axes_locatable(ax1) cax1 = divider1.append_axes("right", size="5%", pad=0.05) cbar1 = plt.colorbar(mappable=im1, cax=cax1, use_gridspec=True, orientation='vertical') viridis = plt.get_cmap('viridis') viridis.set_bad('w', 1.0) ax2 = plt.subplot(gs[1]) ax2.set_title('Fit n-iteractions') im2 = ax2.imshow(np.ma.masked_where(~snr_mask, niter), cmap=viridis, interpolation='nearest', origin='lower') divider2 = make_axes_locatable(ax2) cax2 = divider2.append_axes("right", size="5%", pad=0.05) cbar2 = plt.colorbar(mappable=im2, cax=cax2, use_gridspec=True, orientation='vertical') ax3 = plt.subplot(gs[3]) ax3.set_title('Flux') divider3 = make_axes_locatable(ax3) cax3 = divider3.append_axes("right", size="5%", pad=0.05) im3 = ax3.imshow(flux * mask, cmap=viridis, interpolation='nearest', origin='lower') cbar3 = plt.colorbar(mappable=im3, cax=cax3, use_gridspec=True, orientation='vertical') RdYlBu = plt.get_cmap('RdYlBu') RdYlBu.set_bad('w', 1.0) ax4 = plt.subplot(gs[4]) ax4.set_title('Center') vmin = np.median(velocity * mask) - 2 * np.std(velocity * mask) vmax = np.median(velocity * mask) + 2 * np.std(velocity * mask) im4 = ax4.imshow(velocity * mask, cmap=RdYlBu, interpolation='nearest', origin='lower', vmin=vmin, vmax=vmax) divider4 = make_axes_locatable(ax4) cax4 = divider4.append_axes("right", size="5%", pad=0.05) cbar4 = plt.colorbar(mappable=im4, cax=cax4, use_gridspec=True, orientation='vertical') ax5 = plt.subplot(gs[5]) ax5.set_title('Width') vmin = np.median(width * mask) - 2 * np.std(width * mask) vmax = np.median(width * mask) + 2 * np.std(width * mask) im5 = ax5.imshow(width * mask, cmap=viridis, interpolation='nearest', origin='lower') divider5 = make_axes_locatable(ax5) cax5 = divider5.append_axes("right", size="5%", pad=0.05) cbar5 = plt.colorbar(mappable=im5, cax=cax5, use_gridspec=True, orientation='vertical') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.tight_layout() plt.show() del h['CRVAL3'] del h['CDELT3'] del h['CRPIX3'] del h['CTYPE3'] del h['CUNIT3'] del h['C3_3'] del h['CD3_3'] pyfits.writeto( os.path.join(path, filename.replace('.fits', '.flux.fits')), flux, h, clobber=True) pyfits.writeto( os.path.join(path, filename.replace('.fits', '.velo.fits')), velocity, h, clobber=True) pyfits.writeto( os.path.join(path, filename.replace('.fits', '.width.fits')), width, h, clobber=True) pyfits.writeto( os.path.join(path, filename.replace('.fits', '.cont.fits')), continuum, h, clobber=True) return
output = vc.morphological_laplace(input_var, make_float32=False, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("vc morphological_laplace: ", (t.time() - start_time), " sec") print("\nmorphological_laplace Default") start_time = t.time() d = ndimage.morphological_laplace(input_var, size=None, footprint=None, structure=structure, output=None, mode='reflect', cval=0.0, origin=0) print("scipy morphological_laplace: ", (t.time() - start_time), " sec") print("\nresult: ", (d == output).all()) #15.white_tophat.............. print("\nwhite_tophat VoxelProcessing") start_time = t.time() output = vc.white_tophat(input_var, make_float32=False, size=None, footprint=None, structure=structure, output=None,
def run(self, show=False): # Load data filename = self.filename d = pyfits.getdata(filename) h = pyfits.getheader(filename) path, filename = os.path.split(filename) # Get wavelength calibration z = np.arange(h['naxis3']) w = h['CRVAL3'] + h['CDELT3'] * (z - h['CRPIX3']) # Signal-to-noise clipping s = d.sum(axis=2) s = s.sum(axis=1) gauss_pw, _ = self.fit_gaussian(z, s) log.debug("Gaussian parameters ---") log.debug("p[0] = %.2f" % gauss_pw[0]) log.debug("p[1] = %.2f" % gauss_pw[1]) log.debug("p[2] = %.2f" % gauss_pw[2]) log.debug("p[3] = %.2f" % gauss_pw[3]) lor_p = self.fit_lorentzian(z, s) log.debug("Lorentzian parameters ---") log.debug("p[0] = %.2f" % lor_p[0]) log.debug("p[1] = %.2f" % lor_p[1]) log.debug("p[2] = %.2f" % lor_p[2]) log.debug("p[3] = %.2f" % lor_p[3]) fwhm = np.abs(gauss_pw[2] * 2 * np.sqrt(2 * np.log(2))) filter_ = np.where(np.abs(z - gauss_pw[1]) < fwhm, True, False) if show: plt.plot(z, self.gaussian(gauss_pw, z), 'r-', lw=2, label='Gaussian Fit') plt.plot(z, self.lorentzian(lor_p, z), 'b-', lw=2, label='Lorentzian Fit') plt.plot(z, s, 'ko') plt.plot(z[filter_], s[filter_], 'ro') plt.title('Cube collapsed in XY and fits.') plt.grid() plt.legend(loc='best') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.show() signal = d[filter_].mean(axis=0) noise = d[np.logical_not(filter_)].mean(axis=0) target_snr = 3 snr = signal / noise snr = ndimage.median_filter(snr, 3) snr_mask = np.where(signal > target_snr * noise, True, False) snr_laplacian = ndimage.morphological_laplace(snr * snr_mask, size=3) snr_mask *= np.where(np.abs(snr_laplacian) < 5.0, True, False) snr_mask = ndimage.binary_opening(snr_mask, iterations=5) snr_mask = ndimage.binary_closing(snr_mask, iterations=5) # SNR MASK Based on circular aperture # aperture_radius = 1 # arcmin # aperture_radius = aperture_radius / 60 # arcmin to deg # aperture_radius = np.abs(aperture_radius / h['CD1_1']) # deg to pix # print(aperture_radius) # c = SkyCoord('7:41:55.400', '-18:12:33.00', frame=h['RADECSYS'].lower(), unit=(u.hourangle, u.deg)) # x, y = np.arange(h['NAXIS1']), np.arange(h['NAXIS2']) # X, Y = np.meshgrid(x, y) # center_wcs = wcs.WCS(h) # center = center_wcs.wcs_world2pix(c.ra.deg, c.dec.deg, 6563, 1) # snr_mask = np.sqrt((X - center[0]) ** 2 + (Y - center[1]) ** 2) # snr_mask = np.where(snr_mask < aperture_radius, True, False) # plt.imshow(snr_mask) # plt.show() # SNR MASK Based on squared area aperture_width = 256 * 4.048e-1 # arcsec (from original image) aperture_width /= 3600 # arcsec to deg aperture_width /= np.abs(h['CD1_1']) # deg to pix c = SkyCoord('7:41:55.197', '-18:12:35.97', frame=h['RADECSYS'].lower(), unit=(u.hourangle, u.deg)) x, y = np.arange(h['NAXIS1']), np.arange(h['NAXIS2']) X, Y = np.meshgrid(x, y) center_wcs = wcs.WCS(h) center = center_wcs.wcs_world2pix(c.ra.deg, c.dec.deg, 6563, 1) print(center, np.abs(X - center[0]), np.abs(Y - center[1]), aperture_width) X = np.where(np.abs(X - center[0]) < aperture_width / 2, True, False) Y = np.where(np.abs(Y - center[1]) < aperture_width / 2, True, False) snr_mask = X * Y plt.imshow(snr_mask) plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.show() if show: fig1 = plt.figure(figsize=(20, 5)) plt.title('Signal-to-Noise Ratio') gs = GridSpec(1, 3) ax1 = plt.subplot(gs[0]) ax1.set_title('SNR') im1 = ax1.imshow(snr, cmap='cubehelix', interpolation='nearest', origin='lower', vmin=3, vmax=20) div1 = make_axes_locatable(ax1) cax1 = div1.append_axes("right", size="5%", pad=0.05) cbar1 = plt.colorbar(mappable=im1, cax=cax1, use_gridspec=True, orientation='vertical') ax2 = plt.subplot(gs[1]) ax2.set_title('Mask') im2 = ax2.imshow(np.where(snr_mask, 1, 0), cmap='gray', interpolation='nearest', origin='lower', vmin=0, vmax=1) div2 = make_axes_locatable(ax2) cax2 = div2.append_axes("right", size="5%", pad=0.05) cbar2 = plt.colorbar(mappable=im2, cax=cax2, use_gridspec=True, orientation='vertical') cmap = plt.get_cmap('cubehelix') cmap.set_bad('w', 1.0) ax3 = plt.subplot(gs[2]) ax3.set_title('Masked') im3 = ax3.imshow(np.ma.masked_where(~snr_mask, snr), cmap=cmap, interpolation='nearest', origin='lower', vmin=0) div3 = make_axes_locatable(ax3) cax3 = div3.append_axes("right", size="5%", pad=0.05) cbar3 = plt.colorbar(mappable=im3, cax=cax3, use_gridspec=True, orientation='vertical') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) gs.tight_layout(fig1) plt.show() pyfits.writeto(filename.replace('.', '.SNR.'), snr, h, clobber=True) pyfits.writeto(filename.replace('.', '.SNR_LAPLACIAN.'), snr_laplacian, h, clobber=True) # Adjust continuum continuum = self.fit_continuum(d) # Subtract continuum continuum = np.reshape(continuum, (continuum.size, 1, 1)) continuum = np.repeat(continuum, d.shape[1], axis=1) continuum = np.repeat(continuum, d.shape[2], axis=2) d -= continuum del continuum # Integrate along the planetary nebulae d = d * snr_mask d = d.sum(axis=2) d = d.sum(axis=1) d = d / np.float(h['EXPTIME']) gauss_pw, _ = self.fit_gaussian(w, d) gauss_pc, _ = self.fit_gaussian(z, d) log.info("Gaussian parameters ---") log.info("p[0] = %.4f ADU/s" % gauss_pw[0]) log.info("p[1] = %.4f A = %.4f channels" % (gauss_pw[1], gauss_pc[1])) log.info("p[2] = %.4f A = %.4f channels" % (gauss_pw[2], gauss_pc[2])) log.info("p[3] = %.4f ADU/s" % gauss_pw[3]) # total_flux = (gauss_pc[0] - gauss_pc[3]) * np.sqrt(2 * np.pi) \ # * gauss_pc[2] # log.info("Total flux = (a - d) * sqrt(2pi) * c") # log.info(" %.5E ADU/s" % total_flux) fwhm = np.abs(gauss_pw[2] * 2 * np.sqrt(2 * np.log(2))) filter_ = np.where(np.abs(w - gauss_pw[1]) < fwhm, True, False) # d = d - d[~filter_].mean() if show: plt.plot(w, self.gaussian(gauss_pw, w), 'r-', lw=2, label='Gaussian Fit') # plt.plot(w, self.lorentzian(lor_p, w), 'b-', lw=2, label='Lorentzian Fit') plt.plot(w[~filter_], d[~filter_], 'ko') plt.plot(w[filter_], d[filter_], 'ro') plt.title('Spectral profile of the masked area.') plt.xlabel(u'Wavelenght [$\AA$]') plt.ylabel(u'Integrated Count Level [ADU/s]') plt.grid() plt.legend(loc='best') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.show() integrated_flux = (gauss_pc[0] - gauss_pc[3]) \ * (gauss_pc[2] * np.sqrt(2 * np.pi)) log.info("Total flux: %.4E adu/s" % (integrated_flux)) snr_mask = np.where(snr_mask, 1, 0) pyfits.writeto(os.path.join(path, filename.replace('.fits', '.mask.fits')), snr_mask, h, clobber=True) return
def run(self, show=False): # Load data filename = self.filename d = pyfits.getdata(filename) h = pyfits.getheader(filename) path, filename = os.path.split(filename) # Get wavelength calibration z = np.arange(h['naxis3']) w = h['CRVAL3'] + h['CDELT3'] * (z - h['CRPIX3']) # Signal-to-noise clipping s = d.sum(axis=2) s = s.sum(axis=1) gauss_pw, _ = self.fit_gaussian(z, s) log.debug("Gaussian parameters ---") log.debug("p[0] = %.2f" % gauss_pw[0]) log.debug("p[1] = %.2f" % gauss_pw[1]) log.debug("p[2] = %.2f" % gauss_pw[2]) log.debug("p[3] = %.2f" % gauss_pw[3]) lor_p = self.fit_lorentzian(z, s) log.debug("Lorentzian parameters ---") log.debug("p[0] = %.2f" % lor_p[0]) log.debug("p[1] = %.2f" % lor_p[1]) log.debug("p[2] = %.2f" % lor_p[2]) log.debug("p[3] = %.2f" % lor_p[3]) fwhm = np.abs(gauss_pw[2] * 2 * np.sqrt(2 * np.log(2))) filter_ = np.where(np.abs(z - gauss_pw[1]) < fwhm, True, False) if show: plt.plot(z, self.gaussian(gauss_pw, z), 'r-', lw=2, label='Gaussian Fit') plt.plot(z, self.lorentzian(lor_p, z), 'b-', lw=2, label='Lorentzian Fit') plt.plot(z, s, 'ko') plt.plot(z[filter_], s[filter_], 'ro') plt.title('Cube collapsed in XY and fits.') plt.grid() plt.legend(loc='best') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.show() signal = d[filter_].mean(axis=0) noise = d[np.logical_not(filter_)].mean(axis=0) target_snr = 3 snr = signal / noise snr = ndimage.median_filter(snr, 3) snr_mask = np.where(signal > target_snr * noise, True, False) snr_laplacian = ndimage.morphological_laplace(snr * snr_mask, size=3) snr_mask *= np.where(np.abs(snr_laplacian) < 5.0, True, False) snr_mask = ndimage.binary_opening(snr_mask, iterations=5) snr_mask = ndimage.binary_closing(snr_mask, iterations=5) # SNR MASK Based on circular aperture # aperture_radius = 1 # arcmin # aperture_radius = aperture_radius / 60 # arcmin to deg # aperture_radius = np.abs(aperture_radius / h['CD1_1']) # deg to pix # print(aperture_radius) # c = SkyCoord('7:41:55.400', '-18:12:33.00', frame=h['RADECSYS'].lower(), unit=(u.hourangle, u.deg)) # x, y = np.arange(h['NAXIS1']), np.arange(h['NAXIS2']) # X, Y = np.meshgrid(x, y) # center_wcs = wcs.WCS(h) # center = center_wcs.wcs_world2pix(c.ra.deg, c.dec.deg, 6563, 1) # snr_mask = np.sqrt((X - center[0]) ** 2 + (Y - center[1]) ** 2) # snr_mask = np.where(snr_mask < aperture_radius, True, False) # plt.imshow(snr_mask) # plt.show() # SNR MASK Based on squared area aperture_width = 256 * 4.048e-1 # arcsec (from original image) aperture_width /= 3600 # arcsec to deg aperture_width /= np.abs(h['CD1_1']) # deg to pix c = SkyCoord('7:41:55.197', '-18:12:35.97', frame=h['RADECSYS'].lower(), unit=(u.hourangle, u.deg)) x, y = np.arange(h['NAXIS1']), np.arange(h['NAXIS2']) X, Y = np.meshgrid(x, y) center_wcs = wcs.WCS(h) center = center_wcs.wcs_world2pix(c.ra.deg, c.dec.deg, 6563, 1) print(center, np.abs(X - center[0]), np.abs(Y - center[1]), aperture_width) X = np.where(np.abs(X - center[0]) < aperture_width / 2, True, False) Y = np.where(np.abs(Y - center[1]) < aperture_width / 2, True, False) snr_mask = X * Y plt.imshow(snr_mask) plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.show() if show: fig1 = plt.figure(figsize=(20, 5)) plt.title('Signal-to-Noise Ratio') gs = GridSpec(1, 3) ax1 = plt.subplot(gs[0]) ax1.set_title('SNR') im1 = ax1.imshow(snr, cmap='cubehelix', interpolation='nearest', origin='lower', vmin=3, vmax=20) div1 = make_axes_locatable(ax1) cax1 = div1.append_axes("right", size="5%", pad=0.05) cbar1 = plt.colorbar(mappable=im1, cax=cax1, use_gridspec=True, orientation='vertical') ax2 = plt.subplot(gs[1]) ax2.set_title('Mask') im2 = ax2.imshow(np.where(snr_mask, 1, 0), cmap='gray', interpolation='nearest', origin='lower', vmin=0, vmax=1) div2 = make_axes_locatable(ax2) cax2 = div2.append_axes("right", size="5%", pad=0.05) cbar2 = plt.colorbar(mappable=im2, cax=cax2, use_gridspec=True, orientation='vertical') cmap = plt.get_cmap('cubehelix') cmap.set_bad('w', 1.0) ax3 = plt.subplot(gs[2]) ax3.set_title('Masked') im3 = ax3.imshow(np.ma.masked_where(~snr_mask, snr), cmap=cmap, interpolation='nearest', origin='lower', vmin=0) div3 = make_axes_locatable(ax3) cax3 = div3.append_axes("right", size="5%", pad=0.05) cbar3 = plt.colorbar(mappable=im3, cax=cax3, use_gridspec=True, orientation='vertical') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) gs.tight_layout(fig1) plt.show() pyfits.writeto(filename.replace('.','.SNR.'), snr, h, clobber=True) pyfits.writeto(filename.replace('.','.SNR_LAPLACIAN.'), snr_laplacian, h, clobber=True) # Adjust continuum continuum = self.fit_continuum(d) # Subtract continuum continuum = np.reshape(continuum, (continuum.size, 1, 1)) continuum = np.repeat(continuum, d.shape[1], axis=1) continuum = np.repeat(continuum, d.shape[2], axis=2) d -= continuum del continuum # Integrate along the planetary nebulae d = d * snr_mask d = d.sum(axis=2) d = d.sum(axis=1) d = d / np.float(h['EXPTIME']) gauss_pw, _ = self.fit_gaussian(w, d) gauss_pc, _ = self.fit_gaussian(z, d) log.info("Gaussian parameters ---") log.info("p[0] = %.4f ADU/s" % gauss_pw[0]) log.info("p[1] = %.4f A = %.4f channels" % (gauss_pw[1], gauss_pc[1])) log.info("p[2] = %.4f A = %.4f channels" % (gauss_pw[2], gauss_pc[2])) log.info("p[3] = %.4f ADU/s" % gauss_pw[3]) # total_flux = (gauss_pc[0] - gauss_pc[3]) * np.sqrt(2 * np.pi) \ # * gauss_pc[2] # log.info("Total flux = (a - d) * sqrt(2pi) * c") # log.info(" %.5E ADU/s" % total_flux) fwhm = np.abs(gauss_pw[2] * 2 * np.sqrt(2 * np.log(2))) filter_ = np.where(np.abs(w - gauss_pw[1]) < fwhm, True, False) # d = d - d[~filter_].mean() if show: plt.plot(w, self.gaussian(gauss_pw, w), 'r-', lw=2, label='Gaussian Fit') # plt.plot(w, self.lorentzian(lor_p, w), 'b-', lw=2, label='Lorentzian Fit') plt.plot(w[~filter_], d[~filter_], 'ko') plt.plot(w[filter_], d[filter_], 'ro') plt.title('Spectral profile of the masked area.') plt.xlabel(u'Wavelenght [$\AA$]') plt.ylabel(u'Integrated Count Level [ADU/s]') plt.grid() plt.legend(loc='best') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.show() integrated_flux = (gauss_pc[0] - gauss_pc[3]) \ * (gauss_pc[2] * np.sqrt(2 * np.pi)) log.info("Total flux: %.4E adu/s" % (integrated_flux)) snr_mask = np.where(snr_mask, 1, 0) pyfits.writeto( os.path.join(path, filename.replace('.fits', '.mask.fits')), snr_mask, h, clobber=True) return
def run(self, show=False): # Load data filename = self.filename d = pyfits.getdata(filename) h = pyfits.getheader(filename) path, filename = os.path.split(filename) # Get wavelength calibration z = np.arange(h['naxis3']) w = h['CRVAL3'] + h['CDELT3'] * (z - h['CRPIX3']) # Convert wavelength from nm to Angstrom # if w.all() < 1000.: # w *= 10 # Signal-to-noise clipping s = d.sum(axis=2) s = s.sum(axis=1) gauss_p, _ = self.fit_gaussian(z, s) log.debug("Gaussian parameters ---") log.debug("p[0] = %.2f" % gauss_p[0]) log.debug("p[1] = %.2f" % gauss_p[1]) log.debug("p[2] = %.2f" % gauss_p[2]) log.debug("p[3] = %.2f" % gauss_p[3]) lor_p = self.fit_lorentzian(z, s) log.debug("Lorentzian parameters ---") log.debug("p[0] = %.2f" % lor_p[0]) log.debug("p[1] = %.2f" % lor_p[1]) log.debug("p[2] = %.2f" % lor_p[2]) log.debug("p[3] = %.2f" % lor_p[3]) fwhm = np.abs(gauss_p[2] * 2 * np.sqrt(2 * np.log(2))) filter_ = np.where(np.abs(z - gauss_p[1]) < fwhm, True, False) if show: plt.plot(z, self.gaussian(gauss_p, z), 'r-', lw=2, label='Gaussian Fit') plt.plot(z, self.lorentzian(lor_p, z), 'b-', lw=2, label='Lorentzian Fit') plt.plot(z, s, 'ko') plt.plot(z[filter_], s[filter_], 'ro') plt.title('Cube collapsed in XY and fits.') plt.grid() plt.legend(loc='best') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.show() signal = d[filter_].mean(axis=0) noise = d[np.logical_not(filter_)].mean(axis=0) snr = signal / noise snr = ndimage.median_filter(snr, 3) snr_mask = np.where(snr > 2, True, False) snr_laplacian = ndimage.morphological_laplace(snr * snr_mask, size=3) snr_mask *= np.where(np.abs(snr_laplacian) < 5.0, True, False) snr_mask = ndimage.binary_opening(snr_mask, iterations=5) snr_mask = ndimage.binary_closing(snr_mask, iterations=5) if show: fig1 = plt.figure(figsize=(20, 5)) plt.title('Signal-to-Noise Ratio') gs = GridSpec(1, 3) ax1 = plt.subplot(gs[0]) ax1.set_title('SNR') im1 = ax1.imshow(snr, cmap='cubehelix', interpolation='nearest', origin='lower', vmin=0) div1 = make_axes_locatable(ax1) cax1 = div1.append_axes("right", size="5%", pad=0.05) cbar1 = plt.colorbar(mappable=im1, cax=cax1, use_gridspec=True, orientation='vertical') ax2 = plt.subplot(gs[1]) ax2.set_title('Mask') im2 = ax2.imshow(np.where(snr_mask, 1, 0), cmap='gray', interpolation='nearest', origin='lower', vmin=0, vmax=1) div2 = make_axes_locatable(ax2) cax2 = div2.append_axes("right", size="5%", pad=0.05) cbar2 = plt.colorbar(mappable=im2, cax=cax2, use_gridspec=True, orientation='vertical') cmap = plt.get_cmap('cubehelix') cmap.set_bad('w', 1.0) ax3 = plt.subplot(gs[2]) ax3.set_title('Masked') im3 = ax3.imshow(np.ma.masked_where(~snr_mask, snr), cmap=cmap, interpolation='nearest', origin='lower', vmin=0) div3 = make_axes_locatable(ax3) cax3 = div3.append_axes("right", size="5%", pad=0.05) cbar3 = plt.colorbar(mappable=im3, cax=cax3, use_gridspec=True, orientation='vertical') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) gs.tight_layout(fig1) plt.show() pyfits.writeto(filename.replace('.', '.SNR.'), snr, h, clobber=True) pyfits.writeto(filename.replace('.', '.SNR_LAPLACIAN.'), snr_laplacian, h, clobber=True) # Adjust continuum continuum = self.fit_continuum(d) # Subtract continuum continuum = np.reshape(continuum, (continuum.size, 1, 1)) continuum = np.repeat(continuum, d.shape[1], axis=1) continuum = np.repeat(continuum, d.shape[2], axis=2) d -= continuum del continuum # Save the data-cube with the continuum subtracted pyfits.writeto(os.path.join(path, filename.replace('.fits', '.no_cont.fits')), d, h, clobber=True) # Adjust each pixel to a gaussian flux = np.zeros_like(snr) - np.inf velocity = np.zeros_like(snr) - np.inf width = np.zeros_like(snr) - np.inf continuum = np.zeros_like(snr) - np.inf niter = np.zeros_like(snr) - np.inf fit_gauss_cube = np.zeros_like(d) for (j, i) in itertools.product(range(d.shape[1]), range(d.shape[2])): if snr_mask[j, i]: p, s = self.fit_gaussian(w, d[:, j, i]) else: p, s = [-np.inf, -np.inf, -np.inf, -np.inf], -1 flux[j, i] = p[0] velocity[j, i] = p[1] width[j, i] = p[2] continuum[j, i] = p[3] niter[j, i] = s fit_gauss_cube[:, j, i] = self.gaussian(p, w) log.debug("%04d %04d" % (j, i)) mask = np.ma.masked_equal(snr_mask, False) pyfits.writeto(os.path.join(path, filename.replace('.fits', '.GAUSS.fits')), fit_gauss_cube, h, clobber=True) if show: fig1 = plt.figure(figsize=(16, 6)) plt.title('Final Results') gs = GridSpec(2, 3) magma = plt.get_cmap('magma') magma.set_bad('w', 1.0) ax1 = plt.subplot(gs[0]) ax1.set_title('Collapsed cube') im1 = ax1.imshow(np.ma.masked_where(~snr_mask, d.sum(axis=0)), cmap=magma, interpolation='nearest', origin='lower') divider1 = make_axes_locatable(ax1) cax1 = divider1.append_axes("right", size="5%", pad=0.05) cbar1 = plt.colorbar(mappable=im1, cax=cax1, use_gridspec=True, orientation='vertical') viridis = plt.get_cmap('viridis') viridis.set_bad('w', 1.0) ax2 = plt.subplot(gs[1]) ax2.set_title('Fit n-iteractions') im2 = ax2.imshow(np.ma.masked_where(~snr_mask, niter), cmap=viridis, interpolation='nearest', origin='lower') divider2 = make_axes_locatable(ax2) cax2 = divider2.append_axes("right", size="5%", pad=0.05) cbar2 = plt.colorbar(mappable=im2, cax=cax2, use_gridspec=True, orientation='vertical') ax3 = plt.subplot(gs[3]) ax3.set_title('Flux') divider3 = make_axes_locatable(ax3) cax3 = divider3.append_axes("right", size="5%", pad=0.05) im3 = ax3.imshow(flux * mask, cmap=viridis, interpolation='nearest', origin='lower') cbar3 = plt.colorbar(mappable=im3, cax=cax3, use_gridspec=True, orientation='vertical') RdYlBu = plt.get_cmap('RdYlBu') RdYlBu.set_bad('w', 1.0) ax4 = plt.subplot(gs[4]) ax4.set_title('Center') vmin = np.median(velocity * mask) - 2 * np.std(velocity * mask) vmax = np.median(velocity * mask) + 2 * np.std(velocity * mask) im4 = ax4.imshow(velocity * mask, cmap=RdYlBu, interpolation='nearest', origin='lower', vmin=vmin, vmax=vmax) divider4 = make_axes_locatable(ax4) cax4 = divider4.append_axes("right", size="5%", pad=0.05) cbar4 = plt.colorbar(mappable=im4, cax=cax4, use_gridspec=True, orientation='vertical') ax5 = plt.subplot(gs[5]) ax5.set_title('Width') vmin = np.median(width * mask) - 2 * np.std(width * mask) vmax = np.median(width * mask) + 2 * np.std(width * mask) im5 = ax5.imshow(width * mask, cmap=viridis, interpolation='nearest', origin='lower') divider5 = make_axes_locatable(ax5) cax5 = divider5.append_axes("right", size="5%", pad=0.05) cbar5 = plt.colorbar(mappable=im5, cax=cax5, use_gridspec=True, orientation='vertical') plt.gcf().canvas.mpl_connect('key_press_event', self.on_key_press) plt.tight_layout() plt.show() del h['CRVAL3'] del h['CDELT3'] del h['CRPIX3'] del h['CTYPE3'] del h['CUNIT3'] del h['C3_3'] del h['CD3_3'] pyfits.writeto(os.path.join(path, filename.replace('.fits', '.flux.fits')), flux, h, clobber=True) pyfits.writeto(os.path.join(path, filename.replace('.fits', '.velo.fits')), velocity, h, clobber=True) pyfits.writeto(os.path.join(path, filename.replace('.fits', '.width.fits')), width, h, clobber=True) pyfits.writeto(os.path.join(path, filename.replace('.fits', '.cont.fits')), continuum, h, clobber=True) return