The ZPL macro keyword IMAGEEXTRACT allows users to extract portions of an image and save them into separate files. The keyword IMAGECOMBINE allows users to combine different images into a single file. An example macro (IMAGE_MANIPULATE.ZPL) which demonstrates how to use these features is provided in the .ZIP file located at the end of this article. The test image file used by this macro (Campus.BMP) is also provided in the .ZIP file. Before running the macro, start by placing the image file in the directory C:\Program Files\ZEMAX\IMAFiles\ (if you are running ZEMAX from a different directory, please place the image file in the corresponding \ZEMAX\IMAFiles\ directory on your machine, and then modify the macro to specify the correct location of this directory on your machine).
The macro can then be run from any ZEMAX lens file (e.g. the default LENS.ZMX file which comes up when you first open the ZEMAX application). The macro first reads in the input image file, and determines how many pixels are in this file using the ZPL functions PIXX and PIXY:
! Read in the input file
A$ = "C:\Program Files\ZEMAX\IMAFiles\Campus.BMP"
! Determine how many pixels are in the input file
A_PIXX = PIXX(A$)
A_PIXY = PIXY(A$)
PRINT "Number of X pixels = ", A_PIXX
PRINT "Number of Y pixels = ", A_PIXY
Files are then defined for the 4 images that will be extracted from the input file in this case:
! Define 4 files corresponding to the 4 slices that the input file will be cut in to
A1$ = "C:\Program Files\ZEMAX\IMAFiles\Campus1.BMP"
A2$ = "C:\Program Files\ZEMAX\IMAFiles\Campus2.BMP"
A3$ = "C:\Program Files\ZEMAX\IMAFiles\Campus3.BMP"
A4$ = "C:\Program Files\ZEMAX\IMAFiles\Campus4.BMP"
The IMAGEEXTRACT keyword is then used to split the input image into 4 sections along the horizontal direction and store each image section into a corresponding BMP file:
! Splice the input file into 4 even pieces in the X direction
DIVX = 4.0
IMAGEEXTRACT A$, A1$, 1, 1, A_PIXX/DIVX, A_PIXY
IMAGEEXTRACT A$, A2$, 1.0*A_PIXX/DIVX + 1.0, 1, A_PIXX/DIVX, A_PIXY
IMAGEEXTRACT A$, A3$, 2.0*A_PIXX/DIVX + 1.0, 1, A_PIXX/DIVX, A_PIXY
IMAGEEXTRACT A$, A4$, 3.0*A_PIXX/DIVX + 1.0, 1, A_PIXX/DIVX, A_PIXY
Each of the split image files may be viewed and manipulated individually. For example, while the original BMP image looks like:
the first slice along the horizontal direction looks like:
The IMAGECOMBINE keyword is then used to re-form the original image from the 4 pieces:
! Combine the slices back into a single image
A12$ = "C:\Program Files\ZEMAX\IMAFiles\CampusInput_12.BMP"
A34$ = "C:\Program Files\ZEMAX\IMAFiles\CampusInput_34.BMP"
A_ALL$ = "C:\Program Files\ZEMAX\IMAFiles\CampusInput_ALL.BMP"
M$ = "LEFTRIGHT"
IMAGECOMBINE A1$, A2$, A12$, M$ # Combine input files 1+2
IMAGECOMBINE A3$, A4$, A34$, M$ # Combine input files 3+4
IMAGECOMBINE A12$, A34$, A_ALL$, M$ # Combine input files 1+2+3+4
= all
This is done in three steps, since IMAGECOMBINE can only be used to combine two images at a time. The “mode$” parameter is set as “LEFTRIGHT” because the original image was split in the horizontal direction. The recombined image is stored in the file CampusInput_ALL.BMP, and looks identical to the original image. If we had mistakenly set the “mode$” parameter to “TOPBOTTOM”, the sliced images would have been stacked vertically, as seen here. (click on link to observe the image in a separate window).
The individual image slices generated with the IMAGEEXTRACT keyword in the previous section can be used by any image analysis feature in ZEMAX. For example, say that a scanning system was being used to view the full input image, but it could only do so in terms of the slices generated in the previous section (i.e. because the scanner has a limited field of view). In that case, although each slice comes from a different part of the image, the scanner will view each slice in the center of its field of view. To reconstruct the full image that will be formed by the scanner, we can pass each of the individual image slices through the Geometric Bitmap Image Analysis feature, and then use the IMAGECOMBINE keyword to merge the resultant files. A macro (GBIA_SCAN_TEST.ZPL) which illustrates how this would be done is provided in the .ZIP file located at the end of this article.
The sample macro is intended to work with a scanning system design (Scanning_system.ZMX) which is also included in the .ZIP file located at the end of this article. In this file, the Geometric Bitmap Image Analysis (GBIA) feature is used to show both the source bitmap file as well as an image of the full source file as it is traced through the system. The settings for the GBIA feature in this latter case are:
Hit the “Save” button above to save these settings to a configuration file, which will be named Scanning_system.CFG. Then move this configuration file to the directory C:\Temp\, so that it can be used with the macro. You may choose to keep this file in another directory – however, if you do so, you will need to change the directory names provided in the macro.
The settings provided by the GBIA feature include saving the result to a new bitmap file. This bitmap file will be located in the directory \ZEMAX\IMAFiles\, just as the input file was located in this directory. A comparison between the input and output BMP files shows them to be nearly identical. The output file looks slightly grainier (by a very faint amount), but this could easily be improved by increasing the number of rays traced per pixel (at the expense of longer computational time).
The settings provided in the configuration file will be used by the macro to trace the individual image slices through the system. The macro starts by reading in the full input file, defining files for the slices to be formed using IMAGEEXRACT, and defining output files for the slices that will result from tracing the input slices through the GBIA feature. The input slices are then formed using IMAGEEXTRACT, in exactly the same way as was done in the earlier sample macro.
Although the configuration file will contain many of the default settings that are necessary in this case, the defaults are reinforced – and two of them are modified – using the MODIFYSETTINGS keyword:
! Specify default settings for GBIA feature using MODIFYSETTINGS
! keyword
N_SURF = NSUR()
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_FIELDSIZE, 2.26
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_RAYS, 200
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_XPIX, A_PIXX/DIVX
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_YPIX, A_PIXY
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_XSIZ, 0.05
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_YSIZ, 0.05
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_SURFACE, N_SURF
The settings which are modified are the settings for the number of pixels in X and Y – the new values represent the actual pixel size in X and Y of each input slice.
Each of the input slices is then traced through the system with the GBIA feature, using the same steps: 1. Provide the input file name and the output file name to the GBIA feature using MODIFYSETTINGS; 2. Run the GBIA feature using the keyword GETTEXTFILE:
! Run 1st slice through GBIA feature by executing 2 steps:
! 1. Provide settings for input and output BMP files using
! MODIFYSETTINGS keyword
! 2. Run analysis feature using GETTEXTFILE keyword ("type"
! is "Ibm" for GBIA feature)
! Note: While IMAGEEXTRACT & IMAGECOMBINE require full path
! in file name, GBIA requires that only the file name
! is provided, so this is given explicitly here (rather
! than using string definitions for file names provided
! above)
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_INPUT, "Campus1.BMP"
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_OUTPUT, "Campus1_output.BMP"
C$ = $TEMPFILENAME()
GETTEXTFILE C$, Ibm, "C:\Temp\Scanning_system.CFG", 1
! Repeat for other slices
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_INPUT, "Campus2.BMP"
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_OUTPUT, "Campus2_output.BMP"
C$ = $TEMPFILENAME()
GETTEXTFILE C$, Ibm, "C:\Temp\Scanning_system.CFG", 1
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_INPUT, "Campus3.BMP"
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_OUTPUT, "Campus3_output.BMP"
C$ = $TEMPFILENAME()
GETTEXTFILE C$, Ibm, "C:\Temp\Scanning_system.CFG", 1
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_INPUT, "Campus4.BMP"
MODIFYSETTINGS "C:\Temp\Scanning_system.CFG", GBM_OUTPUT, "Campus4_output.BMP"
C$ = $TEMPFILENAME()
GETTEXTFILE C$, Ibm, "C:\Temp\Scanning_system.CFG", 1
The output images are then merged together using the IMAGECOMBINE keyword, using the same three steps as in the earlier sample macro:
! Combine the output slices
O12$ = "C:\Program Files\ZEMAX\IMAFiles\CampusOutput_12.BMP"
O34$ = "C:\Program Files\ZEMAX\IMAFiles\CampusOutput_34.BMP"
O_ALL$ = "C:\Program Files\ZEMAX\IMAFiles\CampusOutput_ALL.BMP"
M$ = "LEFTRIGHT"
IMAGECOMBINE O1$, O2$, O12$, M$ # Combine output files 1+2
IMAGECOMBINE O3$, O4$, O34$, M$ # Combine output files 3+4
IMAGECOMBINE O12$, O34$, O_ALL$, M$ # Combine output files 1+2+3+4
= all
The resultant image looks like:
This is nearly identical to the input image. However, if you look closely at this image, “seams” (which look like dashed blue lines) can be observed at the locations where the output slices have been merged:
These seams arise from the presence of slight distortion in the output images, which are a result of each input slice being traced through the center of the field of view of the scanning system. For example, although the center of the first input slice (representing the far left slice of the input image) is located off-axis, when this slice is traced through the system its center is placed on-axis. Thus, each slice only “experiences” those distortions associated with the center of the lens. Any corrections that the lens would make to eliminate distortion for off-axis points is effectively not being utilized, resulting in residual distortion for the output slices. While this distortion is small, it is a real effect of scanning a full image piecewise through the system.