; docformat = 'rst' ; ; NAME: ; cropFrame ; PURPOSE: ; Extract a rectangular region out of a larger array ; ;+ ; :Description: ; Extract a rectangular region out of a larger array ; ; :Categories: ; Images ; ; :Returns: A small rectangular frame within a frame. ; ; :Examples: ; ; :Params: ; im: in, required, type=array ; Frame to be cropped ; xy: in, required, type=fltarr(2) ; Position of the center of the region of interest ; dim: in, required, type=int/intarr(2) ; Dimension of the region of interest ; ; :Keywords: ; header: in, optional, type=string ; Image FITS header (used for rotation) ; angle: in, optional, type=float ; Orientation of the region of interest (direct sense, radian) ; ; :Uses: ; hRot, grabXY ; ; :Author: ; B.Carry (OCA) ; ; :History: ; Change History:: ; Original Version written in April 2014, B. Carry (IMCCE) ; 2015-Apr. - B.Carry (IMCCE) - Changed angle parameter to keyword ; 2015-Apr. - B.Carry (IMCCE) - Added header keyword for rotations ; 2017 Mar. - B.Carry (OCA) - Added idl2 compilation option ; 2017 June - B.Carry (OCA) - Now works if crop dimensions are larger than original frame ; 2017 June - B.Carry (OCA) - Now works if crop dimensions are larger than original frame ; 2018 Mar. - B.Carry (OCA) - Corrected a bug occurring in some case when the crop was larger than the original frame ;- function cropFrame, im, xy, dim, angle=angle, header=header, $ missing=missing, missindex=missindex, $ starAlign=starAlign, subFrame=subFrame COMPILE_OPT hidden, idl2 ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- I -- Initialization And Input Verification -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--I.1-- Input Syntax Verification ----------------------------------------------------------- if N_PARAMS() lt 3 then begin message, /IOERROR, 'Syntax : CROPPED = cropFrame( FRAME, XY, DIM [,ANGLE])' stop endif ;--I.2-- Analysis of Input Parameters -------------------------------------------------------- if n_elements(xy) ne 2 then begin message, /ioError, 'XY must be a 2-elements vector' stop endif if n_elements(dim) eq 1 then dimCROP=[dim,dim] else dimCROP=dim if not keyword_set(angle) then angle=0 missTag = -12345678 if not keyword_set(missing) then missing = 0 ;--I.3-- Size Exception ---------------------------------------------------------------------- dimIMG = size(im) if dimCROP[0] gt dimIMG[1] or $ dimCROP[1] gt dimIMG[2] then begin larger = fltarr( dimCROP[0], dimCROP[1] ) ;--I.3.1-- Compute the position of the four corners x1 = dimCROP[0]/2. - xy[0] x2 = dimIMG[1] + x1 -1 y1 = dimCROP[1]/2. - xy[1] y2 = dimIMG[2] + y1 -1 ;--I.3.2-- Indice ranges for image (int) and larger (ext) ext={x1:0, x2:dimCROP[0]-1, y1:0, y2:dimCROP[1]-1} int={x1:0, x2:dimIMG[1] -1, y1:0, y2:dimIMG[2] -1} ;--I.3.3-- X Range when Image is Fully Within Larger if x1 ge 0 and x2 lt dimCROP[0] then begin ext.x1 = x1 int.x1 = 0 ext.x2 = x2 int.x2 = dimIMG[1]-1 ;--I.3.4-- X Range when Image is *NOT* Fully Within Larger endif else begin subX = 0 ;--I.3.4/A-- Safe Bail if x1 lt 0 and x2 ge dimCROP[0] then begin print, 'should never happen!!!!' stop endif else begin ;--I.3.4/B-- Image Starts LEFT from larger if x1 lt 0 then begin subX = abs(x1) ext.x1 = 0 int.x1 = subX ext.x2 = dimIMG[1]-subX ;--I.3.4/C-- Image ends RIGHT from larger endif else begin subX = x2-dimCROP[0] ext.x1 = dimCROP[0]-dimIMG[1]+subX int.x1 = 0 int.x2 = dimIMG[1]-subX endelse endelse endelse ;--I.3.5-- Y Range when Image is Fully Within Larger if y1 ge 0 and y2 lt dimCROP[1] then begin ext.y1 = y1 int.y1 = 0 ext.y2 = y2 int.y2 = dimIMG[2]-1 ;--I.3.6-- X Range when Image is *NOT* Fully Within Larger endif else begin subY = 0 ;--I.3.6/A-- Safe Bail if y1 lt 0 and y2 ge dimCROP[1] then begin print, 'should never happen!!!!' stop endif else begin ;--I.3.6/B-- Image Starts BELOW larger if y1 lt 0 then begin subY = abs(y1) ext.y1 = 0 int.y1 = subY ext.y2 = dimIMG[2]-subY ;--I.3.6/C-- Image ends ABOVE larger endif else begin subY = y2-dimCROP[1] ext.y1 = dimCROP[1]-dimIMG[2]+subY int.y1 = 0 int.y2 = dimIMG[2]-subY endelse endelse endelse ; window, 2 ; cgplot, /iso, 0,0, xr=dimCROP[0]*[-0.2,1.2], yr=dimCROP[1]*[-0.2,1.2] ; cgPlot, /OverPlot, $ ; [0, dimCROP[0], dimCROP[0], 0, 0], $ ; [0, 0, dimCROP[1],dimCROP[1], 0] ; cgPlot, /OverPlot, dimCROP[0]/2, dimCROP[1]/2, psym=4 ; cgPlot, /OverPlot, $ ; [0, dimIMG[1], dimIMG[1], 0, 0] - xy[0] + dimCROP[0]/2., $ ; [0, 0, dimIMG[2],dimIMG[2], 0] - xy[1] + dimCROP[1]/2., color='cornflower blue' larger[ext.x1:ext.x2, ext.y1:ext.y2 ] = im[int.x1:int.x2, int.y1:int.y2 ] ; iX = dimCROP[0]/2.-xy[0] ; iY = dimCROP[1]/2.-xy[1] ; larger[iX:iX+dimIMG[1]-1, iY:iY+dimIMG[2]-1 ] = im im = larger xy = dimCROP/2. endif ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- II -- Rotation and Cropping -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--II.1-- Rotate and Center the Image ---------------------------------------------------- ;--II.1.1-- Use Header Astrometry if keyword_set(header) then begin ; angle *=0.5 ;-visiblement pour Keck 2002!!???? check_fits, im, header, /Update, /Silent hRot, im, header, rotated, header,angle/!DTOR, xy[0], xy[1], 2, cubic=-0.5, missing=missTag ;--II.1.2-- Use Angle on command-line endif else begin rotated = rot( im, angle/!DTOR, 1.0, xy[0], xy[1], cubic=-0.5, missing=missTag ) endelse ;--II.1.3-- Fill Missing part with Input Value (or 0 by Default) missIndex = where( rotated eq missTag ) if missIndex[0] ne -1 then rotated[missIndex]=missing ;--II.2-- Fine Tuning of Position -------------------------------------------------------- if keyword_set(starAlign) then begin if keyword_set(subFrame) then centXY = grabXY( rotated, /AUTO, /peak2D, subFrame=subFrame ) $ else centXY = grabXY( rotated, /AUTO, /peak2D ) shifted = shift( rotated, dimIMG[1]/2.-centXY[0], dimIMG[2]/2.-centXY[1] ) endif else shifted=rotated ;--II.3-- Crop the Frame ----------------------------------------------------------------- if dimCROP[0] gt dimIMG[1] or $ dimCROP[1] gt dimIMG[2] then crop = shifted else $ crop = shifted[ dimIMG[1]/2.-dimCROP[0]/2.: dimIMG[1]/2.+dimCROP[0]/2.-1, $ dimIMG[2]/2.-dimCROP[1]/2.: dimIMG[2]/2.+dimCROP[1]/2.-1 ] ;--II.4-- Return to Higher Level --------------------------------------------------------- return, crop end