#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~# #Load libraries: import numpy as np import os import glob import fnmatch from scipy import misc import matplotlib.pyplot as plt import matplotlib.image as mpimg from multiprocessing import Pool #Input parameter: ##Initial and last image number: Ni=1 Nl=965 ##Number of processor for post-processing parallelization: NbProc=5 #~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~# #Rename file and create time vectors: print('... is sorting pictures') ##Count the number of pictures in the folder to get the number of keeped steps: NbStp=len(fnmatch.filter(os.listdir('.'), '*.jpg'))/2 ##Initialise time vector: timePic=np.zeros(NbStp) ##Create picture vector: null=os.system('mkdir picturePl') null=os.system('mkdir pictureWh') ##Loop over picture names: cnt=0 for it1 in range(Ni,Nl+1): try: ###Find picture names: namCurPl=glob.glob('%04d'%it1+'_*_Pl.jpg')[0] namCurWh=glob.glob('%04d'%it1+'_*_Wh.jpg')[0] ###Extract time: timePic[cnt]=int(namCurPl[namCurPl.index('_')+1:namCurPl.index('_')+(namCurPl[namCurPl.index('_')+1:-1]).index('_')+1]) ###Rename pictures: null=os.system('mv '+namCurPl+' picturePl/'+'%04d'%cnt+'.jpg') null=os.system('mv '+namCurWh+' pictureWh/'+'%04d'%cnt+'.jpg') ###Increment: cnt+=1 except: print('Picture '+'%04d'%it1+' is missing') ##Save time vector: timePic-=np.amin(timePic) np.savetxt('time.txt',timePic,delimiter='\n') #~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~# #Rotate pictures: print('... is rotating pictures') ##Function to rotate pictures: def RotatePicture(iPct): print(iPct) null=os.system('convert picturePl/'+'%04d'%iPct+'.jpg -rotate 90 picturePl/'+'%04d'%iPct+'.jpg') null=os.system('convert pictureWh/'+'%04d'%iPct+'.jpg -rotate 90 pictureWh/'+'%04d'%iPct+'.jpg') return 0 ##Parallelization of the rotation: p=Pool(NbProc) null=p.map(RotatePicture,range(NbStp)) p.close() #~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~# #Reframe pictures: ##Measure picture size: pict1=misc.imread('picturePl/'+'%04d'%0+'.jpg')[:,:,1] #current row,col=pict1.shape ##Function to measure the shift: def MeasurePictureShift(iPct): global row, col print(iPct) ###Load pictures: pict1=misc.imread('picturePl/'+'%04d'%iPct+'.jpg')[:,:,1] pict2=misc.imread('picturePl/'+'%04d'%(iPct+1)+'.jpg')[:,:,1] ###Compute Fourier transform: pict1FFT=np.fft.fft2(pict1) pict2FFT=np.conjugate(np.fft.fft2(pict2)) ###Convolute: pictCCor=np.real(np.fft.ifft2((pict1FFT*pict2FFT))) ###Compute the shift: pictCCorShift=np.fft.fftshift(pictCCor) yShift,xShift=np.unravel_index(np.argmax(pictCCorShift),(row,col)) yShift=yShift-int(row/2) xShift=xShift-int(col/2) a=np.argmax(pictCCorShift) ###return the shifts: return xShift, yShift, a ##Parallelization of the shift computation: print('... is centering pictures (measure displacement)') p=Pool(NbProc) xShiftVec0,yShiftVec0,test0=zip(*p.map(MeasurePictureShift,range(NbStp-1))) xShiftVec0=np.array(xShiftVec0); yShiftVec0=np.array(yShiftVec0); test0=np.array(test0) p.close() ##Detect picture problems and fix it: ###Peak a threshold on image correlation if needed: plt.plot(np.abs(test0-np.mean(test0)),'o',markersize=5) plt.xlabel('step') plt.ylabel('correlation') plt.title('Select a maximum acceptable value') X=plt.ginput(1,timeout=-1) plt.close() II1=np.hstack((np.where(np.abs(test0-np.mean(test0))>X[0][1])[0],10000000)) ###Peak a threshold on image shift if needed: plt.plot(np.abs(xShiftVec0),'o',markersize=5) plt.xlabel('step') plt.ylabel('image shift') plt.title('Select a maximum acceptable value') X=plt.ginput(1,timeout=-1) plt.close() II2=np.hstack((np.where(np.abs(xShiftVec0)>X[0][1])[0],10000000)) II=np.unique(np.hstack((II1,II2))) ###Solve problems if necessary: if len(II)>1: print('Problem with following pictures: '+str(II)[1:-2]) III=np.hstack((np.array([-1]),np.where(np.diff(II)>1)[0])) for it_III in range(len(III)-1): it_ref=II[III[it_III]+1] I_mod=np.array(range(it_ref+1,II[III[it_III+1]]+1)) for it_mod in I_mod: os.system('rm -rf pictureWh/'+'%04d'%it_mod+'.jpg') os.system('cp pictureWh/'+'%04d'%it_ref+'.jpg pictureWh/'+'%04d'%it_mod+'.jpg') os.system('rm -rf picturePl/'+'%04d'%it_mod+'.jpg') os.system('cp picturePl/'+'%04d'%it_ref+'.jpg picturePl/'+'%04d'%it_mod+'.jpg') for it_II in II[0:-1]: A0=MeasurePictureShift(it_II) xShiftVec0[it_II]=A0[0] yShiftVec0[it_II]=A0[1] test0[it_II]=A0[2] ##Add the shifts: xShiftVec=np.zeros(NbStp) yShiftVec=np.zeros(NbStp) for it in range(1,NbStp): xShiftVec[it]=xShiftVec[it-1]+xShiftVec0[it-1] yShiftVec[it]=yShiftVec[it-1]+yShiftVec0[it-1] ##Computation of the new image size: MaxSft=np.amax(xShiftVec)+1 MinSft=np.amin(xShiftVec)-1 colN=int(col-MaxSft+MinSft) rowN=row ##Rescale vectors: xShiftVecN=(MaxSft-xShiftVec).astype(int) ##Function to reframe the pictures: def ReframePicture(iPct): print(iPct) ###Load pictures: pict0=misc.imread('picturePl/'+'%04d'%iPct+'.jpg') pict1=misc.imread('pictureWh/'+'%04d'%iPct+'.jpg') ###Crop pictures: pictF0=pict0[:,xShiftVecN[iPct]:xShiftVecN[iPct]+colN,:] pictF1=pict1[:,xShiftVecN[iPct]:xShiftVecN[iPct]+colN,:] ###Save picture: misc.imsave('picturePl/'+'%04d'%iPct+'.jpg',pictF0) misc.imsave('pictureWh/'+'%04d'%iPct+'.jpg',pictF1) ##Parallelization of the cropping: print('... is centering pictures (crop)') p=Pool(NbProc) null=p.map(ReframePicture,range(NbStp)) p.close() ##Select the area of interest: ###Open the last picture: pict1=mpimg.imread('pictureWh/'+'%04d'%(NbStp-1)+'.jpg') ###Define selection functions: def line_select_callback(eclick,erelease): global x1, y1, x2, y2 x1,y1=eclick.xdata,eclick.ydata x2,y2=erelease.xdata,erelease.ydata def toggle_selector(event): print(' Key pressed.') if event.key in ['Q', 'q'] and toggle_selector.RS.active: print(' RectangleSelector deactivated.') toggle_selector.RS.set_active(False) if event.key in ['A', 'a'] and not toggle_selector.RS.active: print(' RectangleSelector activated.') toggle_selector.RS.set_active(True) ###Select: fig,current_ax=plt.subplots() plt.imshow(pict1,cmap=plt.cm.Greys) plt.title('select area to consider, close to validate') toggle_selector.RS=RectangleSelector(current_ax,line_select_callback,drawtype='box',useblit=True,button=[1,3],minspanx=5,minspany=5,spancoords='pixels',interactive=True) plt.connect('key_press_event',toggle_selector) plt.show() plt.close() ##Function to crop the pictures: def CropPicture(iPct): global x1, y1, x2, y2 print(iPct) ###Load pictures: pict0=misc.imread('picturePl/'+'%04d'%iPct+'.jpg') pict1=misc.imread('pictureWh/'+'%04d'%iPct+'.jpg') ###Crop pictures: pictF0=pict0[int(y1):int(y2),int(x1):int(x2),:] pictF1=pict1[int(y1):int(y2),int(x1):int(x2),:] ###Save picture: misc.imsave('picturePl/'+'%04d'%iPct+'.jpg',pictF0) misc.imsave('pictureWh/'+'%04d'%iPct+'.jpg',pictF1) ##Parallelization of the cropping: print('... is cropping pictures') p=Pool(NbProc) null=p.map(CropPicture,range(NbStp)) p.close() #~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~# #Create movies: ##Create picture vector: null=os.system('mkdir tmpPl') null=os.system('mkdir tmpWh') ##function to plot the pictures with the time: def PlotPicture(iPct): global timePic print(iPct) ###Load the time: t0=timePic[iPct] h0,m0=divmod(t0,60) j0,h0=divmod(h0,24) ###Load pictures: pict0=mpimg.imread('picturePl/'+'%04d'%iPct+'.jpg') pict1=mpimg.imread('pictureWh/'+'%04d'%iPct+'.jpg') ###Plot picture: plt.imshow(pict0) plt.axis('off') plt.title('%02d'%j0+'days '+'%02d'%h0+'hours - '+str(iPct)) plt.savefig('tmpPl/'+'%04d'%iPct+'.png',dpi=200) plt.close() plt.imshow(pict1) plt.axis('off') plt.title('%02d'%j0+'days '+'%02d'%h0+'hours - '+str(iPct)) plt.savefig('tmpWh/'+'%04d'%iPct+'.png',dpi=200) plt.close() ##Parallelization of the cropping: print('... is plotting pictures') p=Pool(1) null=p.map(PlotPicture,range(NbStp)) p.close() ##Make movies: print('... is making the movie') null=os.system('ffmpeg -r 15 -y -f image2 -i tmpPl/%04d.png -qscale 1 Pl.avi') null=os.system('ffmpeg -r 15 -y -f image2 -i tmpWh/%04d.png -qscale 1 Wh.avi') ##Remove folders: null=os.system('rm -f -R tmpPl') null=os.system('rm -f -R tmpWh')