///////////////////////////////////////////////////////////////////// // (c) Gatan Inc. ///////////////////////////////////////////////////////////////////// // Spherize will take a square image, wrap it around a sphere, and return the resulting image. // Note: the RGB version doesn't work that well because the range of the data changes // as its spherized - I make an OK approximation but there are better spherizing algorithms. ///////////////////////////////////////////////////////////////////// // last modified 08-July-2014 BS (comments only) /* This method performs the spherize function. It is passed a source image, it returns the spherized image */ Image Spherize( Image patternImage ) { // Get the width and height of the source, and ensure it is square number width, height GetSize( patternImage, width, height ) if ( width != height ) { Throw( "Spherize: The image has to be square." ) } // Create intermediate images Image Spherized := RealImage( "Spherized", 4, width, width ) Image illumination := RealImage( "Illumination", 4, width, width ) Image warped := RealImage( "Warped", 4, width, width ) Image zsurface := RealImage( "zSurface", 4, width, width ) // Find the centre of the source image and determine the sphere radius number center = width / 2 number radius = center * 0.7 // Specify the lighting vector components, find the resultant magnitude, and normalise number xlight = 500 number ylight = -500 number zlight = 1000 number rlight = sqrt( xlight * xlight + ylight * ylight + zlight * zlight ) xlight /= rlight ylight /= rlight zlight /= rlight // Warp the image into an evenly illuminated sphere warped = warp( patternImage, \ (icol - center) * asin(iradius/radius) * radius / (iradius + .001) + center, \ (irow - center) * asin(iradius/radius) * radius / (iradius + .001) + center ) // Now generate the z-surface i.e. as if illuminated solely from the z-direction (into the screen) zsurface = warped > 0 ? \ sqrt( radius * radius - (icol - center) * (icol -center) - (irow - center) * (irow - center)) : \ 0 // // Generate the illumination by taking the z-surface and incorporating the x and y illumination illumination = warped > 0 ? \ (icol - center) * xlight + (irow - center) * ylight + zlight * zsurface : \ 0 // Now combine the lighting and the warped image Spherized = illumination > 0 ? illumination * warped : 0 // normalize the result to 1 Spherized = Spherized - min( Spherized ) Spherized = Spherized / max( Spherized ) // And return the image return Spherized } /* This method allows Spherize to be applied to an RGB image. It is passed an RGB image and returns the spherized image, calling on the Spherize method as required */ RGBImage SpherizeRGB( RGBImage patternImage ) { // Extract the red component of the RGB image source image and call spherize, // scaling the result wrt the red source image and placing in the red channel // of an RGB image 'Spherized' RealImage temp temp = red( patternImage ) RGBImage Spherized := Spherize( temp ) * ( max( temp ) - min( temp ) ) + min( temp ) // Repeat for the green component... temp = green( patternImage ) green( Spherized ) = Spherize( temp ) * ( max( temp ) - min( temp ) ) + min( temp ) // and again for the blue component. temp = blue( patternImage ) blue( Spherized ) = Spherize( temp ) * ( max( temp ) - min( temp ) ) + min( temp ) // Return the RGB image return Spherized } // Example of use. // We use this track to determine the type of the front image. // Get front image Image frontImage := GetFrontImage() // Check if RGB - if so, call SperizeRGB IF (IsRGBDataType(frontimage, 4)) ShowImage( SpherizeRGB( frontImage ) ) // Else, call Spherize ELSE ShowImage( Spherize( frontImage ) )