import pickle
import matplotlib.pyplot as plt
import os
from astropy.io import fits
import numpy as np
import pandas as pd
from multiprocessing import Pool,cpu_count
from matplotlib import widgets
def fitsData(fitsName):
with fits.open(fitsName) as hdul:
data1=hdul[0].data
shape=data1.shape
data1=data1.reshape(shape[-1],shape[-2])
return data1
def loadPKL():
"""读取当前目录下所有pkl并将所有元素放在一个列表中"""
rho=[]
for i in os.listdir():
if i[-3:]=='pkl':
with open(i,'rb') as file:
data=pickle.load(file)
for i in data:
rho.append(i)
rho=sorted(rho,key=lambda x:x[-1],reverse=True)
return rho
def plotBox(x,y,width,height,ax):
"""定义画方框的函数,依次对应方框左下角横纵坐标,宽度,高度以及对应的ax"""
ax.hlines(y=[y, y+height]
, xmin=x
, xmax=x+width
,colors='red'
)
ax.vlines(x=[x,x+width]
, ymin=y
, ymax=y+height
,colors='red'
)
def plotContour(data,base,levels,ax):
shape=data.shape
y,x=np.mgrid[0:shape[1],0:shape[0]]
levels=[base*2**(0.5*i) for i in range(1,levels)]
ax.invert_yaxis()
ax.contour(x,y,data,levels=levels)
def preCrossCorrelation(data1,data2):
"""data1的左上角沿着data2的rowNumber行做相关,每一行的相关数据存储在一个pkl中"""
shape=data1.shape
subMean1=data1.mean()
subMean2=data2.mean()
sum1=(data1-subMean1)*(data2-subMean2)
sum2=(data2-subMean2)**2
sum3=(data1-subMean1)**2
rho=sum1.sum()/((sum2.sum()*sum3.sum()))**0.5
return rho
def crossCorrelation(data1,data2):
shape1=data1.shape
shape2=data2.shape
Rho=[]
for row in range(shape2[0]-shape1[0]):
for column in range(shape2[1]-shape1[1]):
subData2=data2[row:row+shape1[0],column:column+shape1[1]]
rho=preCrossCorrelation(data1,subData2)
Rho.append((row,column,rho))
print('第{}行完成'.format(row))
with open('data.pkl','wb') as file:
pickle.dump(Rho,file)
class FitsGUI():
def __init__(self,data1,data2):
"""data1代表第一个图(模板图),data2代表第二个图(搜索图)"""
self.data1=data1
self.data2 = data2
self.shape1=self.data1.shape
self.shape2 = self.data1.shape
################################################################################################################
"""
figure大小设置为10*10,分为四块,下面两块用来显示数据1与数据2,对应的ax为4*4,左侧与下侧空隙均为0.5.
一开始图1与2显示自己对应的fits,ax3用来显示最终相关的结果
"""
self.fig=plt.figure(figsize=(10,10))
self.ax1=self.fig.add_axes([0.5/10,0.5/10,4/10,4/10])
self.ax2=self.fig.add_axes([5.5/10,0.5/10,4/10,4/10])
self.ax3=self.fig.add_axes([5.5/10,5.5/10,4/10,4/10])
plotContour(self.data1,base=0.001,levels=20,ax=self.ax1)
plotContour(self.data2,base=0.005,levels=20,ax=self.ax2)
###############################################################################
""""
滑块长度均为4,宽度为0.15,用来移动方框的滑块的长度设置为图片的长度
"""
##############################################
"""图1滑块设置,用来控制图1中方框左下角点的坐标"""
self.ax1XSliderAxes = self.fig.add_axes([0.5/10, 4.75/10, 4/10, 0.15/10])
self.ax1XSlider = widgets.Slider(ax=self.ax1XSliderAxes, valmin=0, valmax=self.shape1[1], valstep=1, label='X')
self.ax1YSliderAxes = self.fig.add_axes([4.75 / 10, 0.5 / 10, 0.15 / 10, 4 / 10])
self.ax1YSlider = widgets.Slider(ax=self.ax1YSliderAxes, valmin=0, valmax=self.shape1[0], valstep=1, label='Y'
,orientation='vertical')
#############################################
"""设置用来控制方框大小的滑块,这两个滑块放在图片左上方,分别代表方框的宽和高,上面控制方框高度,下面控制宽度,宽与高的最大值与图片长度相同"""
self.BoxWidthAxes=self.fig.add_axes([0.5/10, 9.2 / 10, 4 / 10, 0.15 / 10])
self.BoxWidthSlider=widgets.Slider(ax=self.BoxWidthAxes, valmin=0, valmax=self.shape2[1], valstep=1
, label='Width')
self.BoxHeightAxes = self.fig.add_axes([0.5 / 10, 9.65 / 10, 4 / 10, 0.15 / 10])
self.BoxHeightSlider = widgets.Slider(ax=self.BoxHeightAxes, valmin=0, valmax=self.shape2[0], valstep=1
,label='Height')
#############################################
"""所有滑块的变化都对应函数sliderChange"""
self.ax1XSlider.on_changed(self.sliderChange)
self.ax1YSlider.on_changed(self.sliderChange)
self.BoxHeightSlider.on_changed(self.sliderChange)
self.BoxWidthSlider.on_changed(self.sliderChange)
###############################################################################
"""选定好区域后,点击开始互相关按钮,开始计算最终成图"""
self.startbuttonAxes=self.fig.add_axes([2/10, 8 / 10, 1 / 10, 0.5 / 10])
self.startButton=widgets.Button(ax=self.startbuttonAxes,label='START')
self.startButton.on_clicked(self.buttonClick)
plt.show()
def sliderChange(self,val):
self.ax1.cla()
self.ax2.cla()
plotContour(self.data1,base=0.001,levels=20,ax=self.ax1)
plotContour(self.data2,base=0.005,levels=20,ax=self.ax2)
plotBox(ax=self.ax1,x=self.ax1XSlider.val,y=self.ax1YSlider.val,height=self.BoxHeightSlider.val
,width=self.BoxWidthSlider.val)
# print('数据1从第{}到第{}行,第{}列到第{}列'.format(self.ax1YSlider.val
# ,self.ax1YSlider.val+self.BoxHeightSlider.val
# ,self.ax1XSlider.val
# ,self.ax1XSlider.val+self.BoxWidthSlider.val))
self.subData1=self.data1[self.ax1YSlider.val:self.ax1YSlider.val+self.BoxHeightSlider.val
,self.ax1XSlider.val:self.ax1XSlider.val+self.BoxWidthSlider.val]
self.subShape=self.subData1.shape
def buttonClick(self,click):
crossCorrelation(data1=self.subData1,data2=self.data2)
with open('data.pkl','rb') as file:
data=pickle.load(file)
rho=sorted(data,key=lambda x:x[-1],reverse=True)[0]
row=rho[0]
column=rho[1]
plotBox(x=column,y=row,width=self.subShape[1],height=self.subShape[0],ax=self.ax2)
print(row,column,rho[2])
if __name__=='__main__':
data2=fitsData('22.fits')
data1=fitsData('43.fits')
FitsGUI(data1,data2)
with open('data.pkl','rb') as file:
data=pickle.load(file)
rho=sorted(data,key=lambda x:x[-1],reverse=True)
print(rho[0])
NCC算法fits对准
最新推荐文章于 2024-04-24 13:35:29 发布