;+ ; :NAME: ; RMS_EDGE ; ; :PURPOSE: ; This function accepts two images, original and altered. The ; two images must have the same dimensions. The original image ; is converted to luminance, and then an edge mask is ; calculated. The edge mask is found by applying a gradient ; operator, applying a threshold, and then dilating the result. ; The edge mask is applied to both input images, and the RMS ; deviation is found for each channel separately. ; ; :CATEGORY: ; Statistics. ; ; :CALLING SEQUENCE: ; Result = RMS_EDGE( original, altered ) ; ; :INPUTS: ; original ; A color or greyscale image to serve as the reference. ; mean ; A color or greyscale image to be compared to the reference. ; ; :KEYWORD PARAMETERS: ; None ; ; :RETURN VALUE: ; Result is either a scalar (if provided input were greyscale ; images) or a 3-element vecotr (if provided input were color ; images) containing the individual band RMS value in the vicinity ; of edges. ; ; :ERROR CHECKING: ; RETURN, -1 ; if no significant edges with magnitude greater than the ; threshold could be found ; ; :SIDE EFFECTS: ; None ; ; :MODIFICATION HISTORY: ; Written by: Juliet Bernstein ; December, 2007 Original code ; September, 2012 Converted to a general-purpose routine (Carl Salvaggio) ; ; :DISCLAIMER: ; This source code is provided "as is" and without warranties as to performance ; or merchantability. The author and/or distributors of this source code may ; have made statements about this source code. Any such statements do not ; constitute warranties and shall not be relied on by the user in deciding ; whether to use this source code. ; ; This source code is provided without any express or implied warranties ; whatsoever. Because of the diversity of conditions and hardware under which ; this source code may be used, no warranty of fitness for a particular purpose ; is offered. The user is advised to test the source code thoroughly before ; relying on it. The user must assume the entire risk of using the source code. ;- FUNCTION RMS_EDGE, original, altered ;+ ; If the provided images are of different dimensions terminate execution ;- dimensions = SIZE( original ) IF ( TOTAL( dimensions - SIZE( altered ) ) NE 0 ) THEN BEGIN MESSAGE, 'Provided images do not have the same dimensions' ENDIF ;+ ; Prepare an image from which to compute the edges (luminance for a color ; input or direct greyscale input) ;- IF ( dimensions[0] GT 2 ) THEN BEGIN numberBands = dimensions[1] numberSamples = dimensions[2] numberLines = dimensions[3] R = FLOAT( REFORM( original[0,*,*] ) ) G = FLOAT( REFORM( original[1,*,*] ) ) B = FLOAT( REFORM( original[2,*,*] ) ) gray = BYTE( 0.299*R + 0.587*G + 0.114*B ) ENDIF ELSE BEGIN numberBands = 1; numberSamples = dimensions[1] numberLines = dimensions[2] gray = original ENDELSE ;+ ; Compute a Sobel gradient to locate the edges on the greyscale image ;- edges = SOBEL(gray) ;+ ; Threshold and normalize the edge image ;- threshold = 0.2 * MAX( edges ) thresholded = edges GT threshold ;+ ; Grow the edges using a morphological dilation ;- radius = 2 structureElement = SHIFT( DIST( 2*radius + 1 ), radius, radius ) LE radius dilateImg = REPLICATE( MIN( thresholded ), numbersamples+2, numberlines+2 ) dilateImg[1,1] = thresholded dilateImg = DILATE( dilateImg, structureElement ) dilated = dilateImg[ 1:numbersamples, 1:numberlines ] ;+ ; Find the locations and number of edge pixels ;- index = WHERE( dilated, count ) IF ( count NE 0 ) THEN BEGIN ;+ ; Compute the RMS error at the edge pixels for each channel ;- rms = DBLARR( numberbands ) FOR i = 0, numberbands-1 DO BEGIN origband = REFORM( original[i,*,*] ) alteredband = REFORM( altered[i,*,*] ) error = FLOAT( origband[index] ) - FLOAT( alteredband[index] ) rms[i] = SQRT( MEAN( error * error ) ) ENDFOR ENDIF ELSE BEGIN ;+ ; If the magnitude of no edges exceed threshold terminate execution ;- MESSAGE, 'There are no significant edges in the provided image' ENDELSE ;+ ; Return the RMS error in the vicinity of the edges ;- RETURN, rms END