However, the log data contains enormous amount of information and I have been asked about how to analyze these data by several people already, so I decided to write a Python app to extract relevant info out of the log file. This is my VERY first python app, so excuse for any inefficient programming. The reason for me to choose Python is that it is ubiquitous and seemingly popular among tinkerers.
What you can do with it? Well, the app extracts xoffset, yoffset, scale and rotate values from the log file. Here is my understanding of them.
xoffset and yoffset are translational shifts, ie, moving up/down left/right.
scale is CUMULATIVE images size change in the stack. by cumulative, it means it is not between two consecutive images in the stack, but it is between the nth image and the very first image.
rotate is rotational shift between two images, I am not sure if it is cumulative or sequential (ie, between to consecutive images).
These parameters can be used to evaluate a stacking setup. But very important usage (for me) is evaluation of telecentricity using scale factor, which seems to be rather difficult test without Zerene. For a "true" telecentric lens, the scale value should be between 0.9998 and 1.0002 between two images one DOF apart. But I have been doing at least 4 samples, some time 8, between one DOF apart.
Anyways, here is one example of output (running Ubuntu)
In above picute, it looks like I have a mis-alignment between optical axis and motion axis, the xoffset keep increasing (or decreasing as it is a negative number). See my other post on how to estimate correction.
To run the code, you must have Python (free) installed on your system and this code was developed using IDLE.
Code: Select all
# written by Peter Y Lin # rev 0.1 # use it at your own risk # # this is a Python program thst reads Console output from Zerene # stacker and writes out a .csv file that contains X, Y alignment # information so that you can use it with Excel to analyse data # # this Python app is rather simple, the input file, "zerene.txt" # must be in the same directory as the Python app and the output # file will be written to the same directory with name of # "zerene.csv" sensor_w = 5184 # sensor width in pixels sensor_h = 3456 # sensor height in pixels strXOffset = "xoffset = " # these appears in the log file for all xoffset strYOffset = "yoffset = " # these appears in the log file for all yoffset strRotate = "rotate = " strScale = "scale = " strXValue = "" strYValue = "" strRValue = "" strSValue = "" strCSV = "" sIndex = 0 eIndex = 0 # open text file for processing ftxt = open("zerene.txt", "r"); # create csv file for output fcsv = open("zerene.csv", "w"); # write out column names fcsv.write("'xoffset', 'yoffset', 'scale', 'rotate'\n\r"); for line in ftxt: strCSV = ""; sIndex = line.find(strXOffset); if sIndex >= 0 : # found beginning of xoffset, now find the end eIndex = line[sIndex+len(strXOffset):].find(","); if eIndex >= 0: # found xoffset strXValue = line[sIndex+len(strXOffset): sIndex+len(strXOffset) + eIndex]; sIndex = line.find(strYOffset); if sIndex >= 0: # found beginning of yoffset, now find the end eIndex = line[sIndex+len(strYOffset):].find(","); if eIndex >= 0: # found yoffset strYValue = line[sIndex+len(strYOffset): sIndex+len(strYOffset) + eIndex]; sIndex = line.find(strScale); if sIndex >= 0: eIndex = line[sIndex+len(strScale):].find(","); if eIndex >= 0: # found scale factor strSValue = line[sIndex+len(strScale): sIndex+len(strScale) + eIndex]; sIndex = line.find(strRotate); if sIndex >= 0: # found beginning of rotate, now find the end eIndex = line[sIndex+len(strRotate):].find("\n"); if eIndex >= 0: # found rotate strRValue = line[sIndex+len(strRotate): sIndex+len(strRotate) + eIndex]; # assemble CSV string to write out strCSV = "'" + strXValue + "','" + strYValue + "','" + strSValue + "','" + strRValue + "'\n"; # strCSV = strXValue + "," + strYValue + "," + strRValue + "\n"; print(strCSV); # write to comma separated value file fcsv.write(strCSV); ftxt.close(); fcsv.close();