def GPSF(filename): ## Get 2D Gaussian data Gdat = Gauss_2D(*moments(fits_pix(filename))) ## Horrible method: write fits then convert to png if os.path.exists("temp.fits"): os.remove("temp.fits") hdu = pyfits.PrimaryHDU(Gdat) hdu.writeto("temp.fits") if zoom==True: outfile = os.path.splitext(filename)[0]+"_Gauss_z8.png" os.system("ds9 temp.fits -colorbar no -minmax -zoom 8 -saveimage png "+outfile+" -exit") else: outfile = os.path.splitext(filename)[0]+"_Gauss.png" os.system("ds9 temp.fits -colorbar no -minmax -saveimage png "+outfile+" -exit") os.remove("temp.fits") return Gdat
def deconvolve_image(imagefile, kernel, vb=False): ##------------------------------------------------------------ ## Read in image ## Determine image file type and get pixels imgext = os.path.splitext(imagefile)[1] if imgext==".fits": imgarr = fits_pix(imagefile) elif imgext==".png": imgarr = png_pix(imagefile) ## Doesn't work ## For some reason the image is flipped at this point, so un-flip imgarr = imgarr[::-1,:] ## Filter out noise imgarr[imgarr<cutoff] = 0.0 ##------------------------------------------------------------ ## Read in kernel ## Distinguish between array-kernel and file-kernel if type(kernel) is str: ## Ensure the right kernel file has been selected if "PSFtoGauss" in kernel: kernel = numpy.loadtxt(kernel) else: print "DeconvolveToTargetPSF.py: deconvolve_image: wrong kernel file. Abort." return elif type(kernel) is numpy.array: pass ## Kernel dimensions kernel_h,kernel_w = kernel.shape # Should also check match with imagefile # ##------------------------------------------------------------ ## Compute linalg objects from images ## Honest dimensions for scene scene_dim = numpy.array(imgarr.shape)-numpy.array(kernel.shape)+1 scene_siz = scene_dim[0]*scene_dim[1] ##------------------------------------------------------------ convmeth = "scipy" ## Manual convolution if convmeth=="manual": ## 1D array for SCENE (convolved with Gaussian) g_sc = numpy.empty(imgarr.size)#scene_siz ## 1D array for IMAGE stride = imgarr.shape[0] imgarr = imgarr.flatten() ##------------------------------------------------------------ ## Manual matrix product ## Initialise kernel "vector" len_krn_lin = (stride)*(kernel_h-1)+kernel_w ## Still keeps a lot of zeros krn_lin = numpy.zeros(len_krn_lin) ## Loop over slices in the kernel image for j in range (kernel_h): startcol = j*stride krn_lin[startcol:startcol+kernel_w] = kernel[j,:] t0 = time.time() ## Perform linalg product ## i labels the scene pixel and the slice in the original for i in range (scene_siz): imageslice = imgarr[i:i+len_krn_lin] g_sc[i] = numpy.dot(krn_lin,imageslice) if vb: print "DeconvolveToTargetPSF.py: deconvolve_image: vector multiplication took",\ round(time.time()-t0,2),"seconds." ## Delete spurious elements (from overlapping) i=len(g_sc) while i>=0: if i%stride+kernel_w > stride: g_sc = numpy.delete(g_sc,i) i-=1 ## Delete spurious elements from declaring it too big g_sc = numpy.delete(g_sc,slice(scene_siz-len(g_sc)-1,-1)) if scene_siz-len(g_sc): print "LINE #"+str(lineno())+": size discrepancy" ##------------------------------------------------------------ elif convmeth=="scipy": t0=time.time() ## Do convolution using scipy imgarr = numpy.array(imgarr, dtype="float64") g_sc = convolve(imgarr, kernel, mode="valid") if vb: print "DeconvolveToTargetPSF.py: deconvolve_image: SciPy convolution took",\ round(time.time()-t0,2),"seconds." else: print "LINE #"+str(lineno())+": convmeth error, abort." return ##------------------------------------------------------------ ## Reshape if g_sc.shape[0]!=scene_dim[0] or g_sc.shape[1]!=scene_dim[1]: if vb: print "DeconvolveToTargetPSF.py: deconvolve_image: reshaping." try: g_sc = g_sc.reshape(scene_dim) except ValueError: print "DeconvolveToTargetPSF.py: deconvolve_image: output has wrong shape. Investigate." ##------------------------------------------------------------ ## Filter out (computer) noise g_sc[g_sc<cutoff] = 0.0 ## Outfile name imagedir,imagename = os.path.split(imagefile) info = imagename[imagename.find("CFHT"):imagename.find("sci")+3] outfile = imagedir+"/gDeconvolved_"+info ## Rescale (linear stretch) if 1: ## Scaling parameters vmin,vmax = stretch_params(g_sc) ## Stretch g_sc = linear_rescale(g_sc, vmin, vmax) ## Modify filename outfile = outfile+"_rescaled" ## Delete pre-existing images if os.path.isfile(outfile+".fits"): os.remove(outfile+".fits") if os.path.isfile(outfile+".png"): os.remove(outfile+".png") ## Save image as FITS and as PNG makeFITS(outfile+".fits", g_sc) scipy.misc.imsave(outfile+".png", g_sc) if vb: print "DeconvolveToTargetPSF.py: deconvolve_image: image saved to",outfile+".fits" return None
def deconvolve_image(imagefile, kernel, vb=False): ##------------------------------------------------------------ ## Read in image ## Determine image file type and get pixels try: imgext = os.path.splitext(imagefile)[1] if imgext==".fits": imgarr = fits_pix(imagefile) elif imgext==".png": assert False, "Cannot handle PNG format." ## For some reason the image is flipped at this point, so un-flip imgarr = imgarr[::-1,:] ## Or, if the imagefile is already an array except AttributeError: imgarr = imagefile ##------------------------------------------------------------ ## Read in kernel ## Distinguish between array-kernel and file-kernel if type(kernel) is str: ## Ensure the right kernel file has been selected if "PSFtoGauss" in kernel: kernel = numpy.loadtxt(kernel) else: print "DeconvolveToTargetPSF.py: deconvolve_image: wrong kernel file. Abort." return elif type(kernel) is numpy.array: pass ## Kernel dimensions kernel_h,kernel_w = kernel.shape #scipy.misc.imsave("../doc/Images/kernel.png", kernel) ##### #scipy.misc.imsave("../doc/Images/image.png",imgarr) ##### ##------------------------------------------------------------ ## Have kernel and original image; now we need to solve the matrix equation ## Kx = b, where K is kernel, x is target image, and b is our observed image. ## FIRST, dimensions of data image should be greater than those of scene ## to ensure a stable solution. ## Pad so that the scene has same dimensions of original data. refimg_dim = imgarr.shape refimg_size = imgarr.size obsimg_dim = numpy.array(imgarr.shape) + numpy.array(kernel.shape) - 1 obsimg_size = obsimg_dim[0]*obsimg_dim[1] ## SECOND, construct matrix K from kernel array. ## kernmat should be obsimg_size by refimg_size ## What is first row of kernmat? krow = numpy.zeros(refimg_size) for i in range(kernel_h): j = i*refimg_dim[0] ## Stride number krow[j:j+kernel_w] = kernel[i,:] ## First column of kernmat (declare too large) kcol = numpy.zeros(obsimg_size); kcol[0]=krow[0] ## Create dense Toeplitz matrix (not square) ## This contains all the relevant rows; we'll chop it up later kernmat = scipy.linalg.toeplitz(kcol,krow) ## Some rows of the kernel matrix will be no good -- they represent pixel where the convolution ## oversteps the image border ## There must be a better way of doing this badrow = [numpy.arange(i*refimg_dim[0]-kernel_w+2, i*refimg_dim[0]+1) for i in range(1,refimg_dim[1])] ## Delete spurious rows kernmat = numpy.delete(kernmat, badrow, axis=0) ## Also delete end rows from declaring kcol too large ##convimgsiz is how big the kernel matrix should be if we are true to convolution convimgsiz = (refimg_dim[0]-kernel.shape[0]+1)*(refimg_dim[1]-kernel.shape[1]+1) kernmat = kernmat[:convimgsiz,:] #scipy.misc.imsave("../doc/Images/kernmat.png", kernmat) ##### ## Now we need to pad out the kernel matrix to reflect padding of the data image ## do inner bits insertionrow = numpy.arange(refimg_dim[0]-kernel.shape[0]+2, convimgsiz, refimg_dim[0]-kernel.shape[0]+1).repeat(2*(obsimg_dim[0]-imgarr.shape[0])) kernmat = numpy.insert(kernmat, insertionrow, numpy.zeros(refimg_size), axis=0) ## do ends thickpad = numpy.zeros([(obsimg_dim[0]+1)*(obsimg_dim[0]-imgarr.shape[0]),refimg_size]) kernmat = numpy.append(kernmat, thickpad, axis=0) kernmat = numpy.append(thickpad, kernmat, axis=0) #scipy.misc.imsave("../doc/Images/kernmat_pad.png", kernmat) ##### ## Don't need these any more kcol=None; krow=None; badrow=None; insertionrow=None; thickpad=None scipy.misc.imsave("kernmat.png",kernmat) ## Turn dense kernmat into a sparse matrix #kernmat = scipy.sparse.dia_matrix(kernmat) ## THIRD, construct vector b from observed image ## This is padded with zeros so to make the matrix equation well-defined imgvec = pad(obsimg_dim, imgarr).flatten() #scipy.misc.imsave("../doc/Images/image_pad.png", imgvec.reshape(obsimg_dim)) ##### ## FOURTH, solve the equation Kx = b ## The system of equations is UNDERdetermined t0=time.time() ## Decide whether to use initial guess or not if False: print "Using intital guess." ## Make initial guess; must be conformable refimg0 = shave(refimg_dim, imgarr).flatten() ## Solve matrix equation K*(dx)=res residual = imgvec-numpy.dot(kernmat,refimg0) #correction,istop,itn = scipy.sparse.linalg.lsqr(kernmat, residuals, calc_var=False)[:3] correction,resi = numpy.linalg.lstsq(kernmat, residual)[:2] ## Add initial solution to correction refimgvec = refimg0 + correction ## Tidy up correction = None; residual = None; refimg0 = None ## Or just straight solve else: ## Account for noise ##### ## Sparse method or regular #refimgvec,istop,itn,r1norm,r2norm = scipy.sparse.linalg.lsqr(kernmat, imgvec, calc_var=False)[:5] refimgvec,resi = numpy.linalg.lstsq(kernmat, imgvec)[:2] if vb: print "image_deconvolve: least-squares converged to reference image in",\ round(time.time()-t0,2),"seconds." ##------------------------------------------------------------ ## Check: reverse procedure check = False if check is True: resi = (numpy.dot(kernmat,refimgvec)-imgvec).reshape(obsimg_dim) scipy.misc.imsave("check_resi.png", resi) scipy.misc.imsave("check_recon.png", numpy.dot(kernmat,refimgvec).reshape(obsimg_dim)) ##------------------------------------------------------------ ## Reshape into an image refimg = refimgvec.reshape(refimg_dim) ##------------------------------------------------------------ ## Outfile name try: imagedir,imagename = os.path.split(imagefile) info = imagename[imagename.find("CFHT"):imagename.find("sci")+3] outfile = imagedir+"/gDeconvolved_"+info header = fits_hdr(imagefile) except (TypeError, AttributeError): ## If the input was in array format outfile = "deconvolved" header = None ##------------------------------------------------------------ ## Rescale (linear stretch) if True: ## Scaling parameters vmin,vmax = stretch_params(refimg) ## Stretch refimg = linear_rescale(refimg, vmin, vmax) ## Modify filename outfile = outfile+"_rescaled" ## Delete pre-existing images if os.path.isfile(outfile+".fits"): os.remove(outfile+".fits") if os.path.isfile(outfile+".png"): os.remove(outfile+".png") ## Save image as FITS and as PNG #makeFITS(outfile+".fits", refimg, header) #scipy.misc.imsave(outfile+".png", refimg) if vb: print "DeconvolveToTargetPSF.py: deconvolve_image: image saved to",outfile+".fits" return refimg
def deconvolve_image(imagefile, kernel, vb=False): ##------------------------------------------------------------ ## Read in image ## Determine image file type and get pixels try: imgext = os.path.splitext(imagefile)[1] if imgext == ".fits": imgarr = fits_pix(imagefile) elif imgext == ".png": assert False, "Cannot handle PNG format." ## For some reason the image is flipped at this point, so un-flip imgarr = imgarr[::-1, :] ## Or, if the imagefile is already an array except AttributeError: imgarr = imagefile ##------------------------------------------------------------ ## Read in kernel ## Distinguish between array-kernel and file-kernel if type(kernel) is str: ## Ensure the right kernel file has been selected if "PSFtoGauss" in kernel: kernel = numpy.loadtxt(kernel) else: print "DeconvolveToTargetPSF.py: deconvolve_image: wrong kernel file. Abort." return elif type(kernel) is numpy.array: pass ## Kernel dimensions kernel_h, kernel_w = kernel.shape #scipy.misc.imsave("../doc/Images/kernel.png", kernel) ##### #scipy.misc.imsave("../doc/Images/image.png",imgarr) ##### ##------------------------------------------------------------ ## Have kernel and original image; now we need to solve the matrix equation ## Kx = b, where K is kernel, x is target image, and b is our observed image. ## FIRST, dimensions of data image should be greater than those of scene ## to ensure a stable solution. ## Pad so that the scene has same dimensions of original data. refimg_dim = imgarr.shape refimg_size = imgarr.size obsimg_dim = numpy.array(imgarr.shape) + numpy.array(kernel.shape) - 1 obsimg_size = obsimg_dim[0] * obsimg_dim[1] ## SECOND, construct matrix K from kernel array. ## kernmat should be obsimg_size by refimg_size ## What is first row of kernmat? krow = numpy.zeros(refimg_size) for i in range(kernel_h): j = i * refimg_dim[0] ## Stride number krow[j:j + kernel_w] = kernel[i, :] ## First column of kernmat (declare too large) kcol = numpy.zeros(obsimg_size) kcol[0] = krow[0] ## Create dense Toeplitz matrix (not square) ## This contains all the relevant rows; we'll chop it up later kernmat = scipy.linalg.toeplitz(kcol, krow) ## Some rows of the kernel matrix will be no good -- they represent pixel where the convolution ## oversteps the image border ## There must be a better way of doing this badrow = [ numpy.arange(i * refimg_dim[0] - kernel_w + 2, i * refimg_dim[0] + 1) for i in range(1, refimg_dim[1]) ] ## Delete spurious rows kernmat = numpy.delete(kernmat, badrow, axis=0) ## Also delete end rows from declaring kcol too large ##convimgsiz is how big the kernel matrix should be if we are true to convolution convimgsiz = (refimg_dim[0] - kernel.shape[0] + 1) * (refimg_dim[1] - kernel.shape[1] + 1) kernmat = kernmat[:convimgsiz, :] #scipy.misc.imsave("../doc/Images/kernmat.png", kernmat) ##### ## Now we need to pad out the kernel matrix to reflect padding of the data image ## do inner bits insertionrow = numpy.arange(refimg_dim[0] - kernel.shape[0] + 2, convimgsiz, refimg_dim[0] - kernel.shape[0] + 1).repeat( 2 * (obsimg_dim[0] - imgarr.shape[0])) kernmat = numpy.insert(kernmat, insertionrow, numpy.zeros(refimg_size), axis=0) ## do ends thickpad = numpy.zeros([ (obsimg_dim[0] + 1) * (obsimg_dim[0] - imgarr.shape[0]), refimg_size ]) kernmat = numpy.append(kernmat, thickpad, axis=0) kernmat = numpy.append(thickpad, kernmat, axis=0) #scipy.misc.imsave("../doc/Images/kernmat_pad.png", kernmat) ##### ## Don't need these any more kcol = None krow = None badrow = None insertionrow = None thickpad = None scipy.misc.imsave("kernmat.png", kernmat) ## Turn dense kernmat into a sparse matrix #kernmat = scipy.sparse.dia_matrix(kernmat) ## THIRD, construct vector b from observed image ## This is padded with zeros so to make the matrix equation well-defined imgvec = pad(obsimg_dim, imgarr).flatten() #scipy.misc.imsave("../doc/Images/image_pad.png", imgvec.reshape(obsimg_dim)) ##### ## FOURTH, solve the equation Kx = b ## The system of equations is UNDERdetermined t0 = time.time() ## Decide whether to use initial guess or not if False: print "Using intital guess." ## Make initial guess; must be conformable refimg0 = shave(refimg_dim, imgarr).flatten() ## Solve matrix equation K*(dx)=res residual = imgvec - numpy.dot(kernmat, refimg0) #correction,istop,itn = scipy.sparse.linalg.lsqr(kernmat, residuals, calc_var=False)[:3] correction, resi = numpy.linalg.lstsq(kernmat, residual)[:2] ## Add initial solution to correction refimgvec = refimg0 + correction ## Tidy up correction = None residual = None refimg0 = None ## Or just straight solve else: ## Account for noise ##### ## Sparse method or regular #refimgvec,istop,itn,r1norm,r2norm = scipy.sparse.linalg.lsqr(kernmat, imgvec, calc_var=False)[:5] refimgvec, resi = numpy.linalg.lstsq(kernmat, imgvec)[:2] if vb: print "image_deconvolve: least-squares converged to reference image in",\ round(time.time()-t0,2),"seconds." ##------------------------------------------------------------ ## Check: reverse procedure check = False if check is True: resi = (numpy.dot(kernmat, refimgvec) - imgvec).reshape(obsimg_dim) scipy.misc.imsave("check_resi.png", resi) scipy.misc.imsave("check_recon.png", numpy.dot(kernmat, refimgvec).reshape(obsimg_dim)) ##------------------------------------------------------------ ## Reshape into an image refimg = refimgvec.reshape(refimg_dim) ##------------------------------------------------------------ ## Outfile name try: imagedir, imagename = os.path.split(imagefile) info = imagename[imagename.find("CFHT"):imagename.find("sci") + 3] outfile = imagedir + "/gDeconvolved_" + info header = fits_hdr(imagefile) except (TypeError, AttributeError): ## If the input was in array format outfile = "deconvolved" header = None ##------------------------------------------------------------ ## Rescale (linear stretch) if True: ## Scaling parameters vmin, vmax = stretch_params(refimg) ## Stretch refimg = linear_rescale(refimg, vmin, vmax) ## Modify filename outfile = outfile + "_rescaled" ## Delete pre-existing images if os.path.isfile(outfile + ".fits"): os.remove(outfile + ".fits") if os.path.isfile(outfile + ".png"): os.remove(outfile + ".png") ## Save image as FITS and as PNG #makeFITS(outfile+".fits", refimg, header) #scipy.misc.imsave(outfile+".png", refimg) if vb: print "DeconvolveToTargetPSF.py: deconvolve_image: image saved to", outfile + ".fits" return refimg