Spherisize
DigitalMicrograph Script
Take a square image, wrap it around a sphere, and then return the resulting image.
Preview
/////////////////////////////////////////////////////////////////////
// (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 ) )