01_RescaleRename_multi.py 8.81 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#~/"\~#

#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
36
for it1 in range(Ni,Nl+1):
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
    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):
61
    print(iPct)
62 63 64 65 66 67
    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)
68
null=p.map(RotatePicture,range(NbStp))
69 70 71 72 73 74 75 76 77 78 79 80
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
81
    print(iPct)
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    ###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)
104
xShiftVec0,yShiftVec0,test0=zip(*p.map(MeasurePictureShift,range(NbStp-1)))
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
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)
150
for it in range(1,NbStp):
151 152 153 154 155 156 157 158 159 160 161 162 163 164
    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):
165
    print(iPct)
166 167 168 169 170 171 172 173 174 175 176 177 178
    ###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)
179
null=p.map(ReframePicture,range(NbStp))
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
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
213
    print(iPct)
214 215 216 217 218 219 220 221 222 223 224 225 226
    ###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)
227
null=p.map(CropPicture,range(NbStp))
228 229 230 231 232 233 234 235 236 237 238 239 240
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 
241
    print(iPct)
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
    ###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)
264
null=p.map(PlotPicture,range(NbStp))
265 266 267 268 269 270 271 272 273 274 275 276 277 278
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')