; file: shift_intpx.pro = modification of IDL shift to make cyclic edges flat ; init: Oct 13 2013 Rob Rutten ; last: Oct 14 2013 Rob Rutten ; note: better see SSW (Metcalf) shift_img.pro function shift_intpx,inputarr,shiftvec,mean=mean ;+ ; NAME: ; shift_intpx ; PURPOSE: ; shift [x,y] image or [x,y,t] movie over whole (integer) pixels ; with blank-out of the cycled-in edges by the data average ; CALL: ; shiftarr=shift_intpx(inputarr,shiftvec [,mean=mean]) ; INPUTS: ; inputarr = 2D [x,y] image or 3D [x,y,t] movie, any type ; shiftvec = corresponding 2-element or 3-element integer vector ; positive shifts: new image is shifted to right, up, later ; negative shifts: new image is shifted to left, down, earlier ; KEYWORDS: ; mean=mean set intensity of shifted-in areas to mean value (default 0) ; OUTPUTS: ; shifted array, same size and type as inputarr ; NOTE: ; after writing this I found SSW shift_img.pro which admits much more ; (fractional pixel shifts, scale changes, rotation, all it-dependent) ; HISTORY: ; Oct 13 2013 RR: started ; Oct 14 2013 RR: faster with "pointer axiom" ;- ; get size sizearr=size(inputarr) ndim=sizearr[0] ; check array dimension if (ndim eq 0 or ndim gt 3) then begin print,' === shift_intpx: inputarr is not 2D or 3D' return,-1 endif ; get axis lengths nx=sizearr[1] ny=sizearr[2] if (ndim eq 3) then nz=sizearr[3] else nz=0 ; check shift vector length if (n_elements(shiftvec) ne ndim) then begin print,' === shift_intpx: shiftvec length not = inputarr dimension' return,-1 endif ; check shift vector data type sizevec=size(shiftvec) if (not (sizevec[2] eq 2 or sizevec[2] eq 3)) then begin print,' === shift_intpx: shiftvec not integer type' return,-1 endif ; get mean as blank ("grey") value if (n_elements(mean) eq 0) then $ blank=total(float(inputarr))/n_elements(inputarr) $ else blank=0 ; shift the input array with the IDL function with cyclic rotation sharr=shift(inputarr,shiftvec) ; insert the blanks using the pointer example at ;; http://www.idlcoyote.com/code_tips/asterisk.html ;; image[100,100] = Replicate(255, 10, 30) ; set pointer starts of the blanks if (shiftvec[0] gt 0) then xs=0 ; blank strip at left if (shiftvec[0] lt 0) then xs=nx+shiftvec[0] ; blank strip at right if (shiftvec[1] gt 0) then ys=0 ; blank strip at bottom if (shiftvec[1] lt 0) then ys=ny+shiftvec[1] ; blank strip at top if (nz gt 0) then begin if (shiftvec[2] gt 0) then zs=0 ; blanks images at start if (shiftvec[2] lt 0) then zs=nz+shiftvec[2] ; blank images at end endif ; insert the blanks shiftval=abs(shiftvec) if (nz eq 0) then begin if (shiftval[0] ne 0) then sharr[xs,0]=replicate(blank,shiftval[0],ny) if (shiftval[1] ne 0) then sharr[0,ys]=replicate(blank,nx,shiftval[1]) endif else begin if (shiftval[0] ne 0) then sharr[xs,0,0]=replicate(blank,shiftval[0],ny,nz) if (shiftval[1] ne 0) then sharr[0,ys,0]=replicate(blank,nx,shiftval[1],nz) if (shiftval[2] ne 0) then sharr[0,0,zs]=replicate(blank,nx,ny,shiftval[2]) endelse return, sharr end ; ================= main for testing per IDLWAVE H-c ========================= ; get demo cube path='/home/rutten/rr/edu/manuals/idl-cubes/idl-cube/' gb=readfits(path+'DOT-2005-10-14-gb.fits') ; test shifting a 3D movie cube shift=[20,-20,3] new=shift_intpx(gb,shift,/mean) showex,gb,new ; test shifting a 2D image gbim=reform(gb[*,*,0]) shiftim=[20,-20] newim=shift_intpx(gbim,shiftim) showex,gbim,newim end