def main(): """ Displayes the image file given as first parameter on the command line. """ if len(sys.argv) > 1: fn = sys.argv[1] print 'loading %s ...' % fn img = TIFF(fn) bit = img.depth else: print __doc__ print 'USAGE: %s [image filename]\n' % sys.argv[0] sys.exit(1) print("Minimum and maximum pixel values in the image: Min: %d Max: %d" % img.minmax) print("Rescaling to fill full 16bit space.") img.data = img.rescale() # determine screen size (see http://stackoverflow.com/a/3949983/183995 ) root = Tkinter.Tk() screen_width, screen_height = root.winfo_screenwidth(), root.winfo_screenheight() small = img while small.dimensions[0] > screen_height or small.dimensions[1] > screen_width: small.scale_down_to_half() def onmouse(event, x, y, flags, param): h, w = img.dimensions hs, ws = small.dimensions x, y = int(1.0*x*h/hs), int(1.0*y*h/hs) show_zoom(x,y) zoom_window_size = 466 zoom_factor = 3 zoom = np.zeros((zoom_window_size, zoom_window_size),img.data.dtype) def show_zoom(x,y): h, w = img.dimensions img_box = rectangle() img_box.pos = coordinates(0,0) img_box.dim = coordinates(w,h) box = img_box.get_rectangle_inside(zoom_window_size/zoom_factor, coordinates(x,y)) f, t = box.corners() #zoom = cv2.getRectSubPix(img, (800, 600), (x+0.5, y+0.5)) #cv2.GetSubRect(img, (60, 70, 32, 32)) #zoom = cv2.getRectSubPix(img, (200, 200), (x, y)) #zoom = img[f.y:t.y, f.x:t.x] ## http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html#resize cv2.resize(img.data[f.y:t.y, f.x:t.x], dsize=(zoom_window_size,zoom_window_size), dst=zoom, interpolation=cv2.INTER_NEAREST) cv2.imshow('Detail', zoom) cv2.namedWindow("Detail") cv2.moveWindow("Detail", 5, 50+small.dimensions[0]) cv2.imshow('Overview', small.data) cv2.moveWindow("Overview", 5, 20) show_zoom(0,0) cv2.setMouseCallback('Overview', onmouse) cv2.waitKey()
def read_image(self, imgfile, bgfile=None): """ imgfile and bgfile should be ('/path/to/folder','filename.tif') """ self.imgfile, self.bgfile = imgfile, bgfile self.img = TIFF(os.path.join(imgfile)) if bgfile: self.img.data -= TIFF(os.path.join(bgfile)).data self.minmax = self.img.minmax self.percentiles = self.img.percentiles([1,5,99,99.995]) self.blobs = find_blobs(self.img.data)
class MeasurementPoint(object): """ This class holds all data associated with a single measurement point. This includes an XML file, the image from the spectrometer and a background reference image. """ PD_SCOPE_CHANNEL = 0 ION_SCOPE_CHANNEL = 1 collection = None def __init__(self, date, avgnum, xmlfile, imgfile, bgfile=None): #print("Reading XML file %s" % xmlfile) self.date = date self.avgnum = avgnum self.read_xml(xmlfile) self.read_image(imgfile,bgfile) def read_xml(self, xmlfile): """ xmlfile should be ('/path/to/folder','filename.xml') """ self.xmlfile = xmlfile f = open(xmlfile, "r") tree = parse(f) self.xml = tree.getroot() f.close() def read_image(self, imgfile, bgfile=None): """ imgfile and bgfile should be ('/path/to/folder','filename.tif') """ self.imgfile, self.bgfile = imgfile, bgfile self.img = TIFF(os.path.join(imgfile)) if bgfile: self.img.data -= TIFF(os.path.join(bgfile)).data self.minmax = self.img.minmax self.percentiles = self.img.percentiles([1,5,99,99.995]) self.blobs = find_blobs(self.img.data) def display_image(self, rescale=False, rescale_to_global_minmax=False, rescale_to_percentile_and_max=False): """ Displayes the spectrometer image using OpenCV's function :py:func:`cv2.imshow` """ if rescale: i = self.img if rescale_to_global_minmax: print("Rescaling to global min and max values (%d,%d)" % self.collection.minmax) img_data = i.rescale(self.collection.minmax) elif rescale_to_percentile_and_max: print("Rescaling image using 5 percent percentile to local maximum value: (%d,%d)." % (self.percentiles[5], i.minmax[1])) img_data = i.rescale((self.percentiles[5], i.minmax[1])) else: img_data = i.rescale(i.minmax) else: img_data = self.img.data cv2.imshow('test',img_data) return cv2.waitKey() def __str__(self): return "MeasurementPoint: (date: %s, xml: %s, image: %s, bgimage: %s)" % (self.date, self.xmlfile, self.imgfile, self.bgfile) def dump_xml_structure(self, level=0): """ Returns a human readable dump of the xml structure. Implemented as a recursive function. Therefore call without providing the `level` argument.""" output = '' for element in self.xml: output += ''.join(['--' for i in range(level)]) output += "> " + element.tag if element.text != None: content = element.text.replace("\n"," ") output += " : " if len(content) < 20: output += content else: output += content[:20] + " ..." output += "\n" output += self.dump_xml_structure(element, level+1) return output def get_stage_positions(self): raise NotImplementedError def get_photodiode_scope_channel(self): return self.get_scope_channel(self.PD_SCOPE_CHANNEL) def get_ion_scope_channel(run): return self.get_scope_channel(self.ION_SCOPE_CHANNEL) def get_scope_channel(run, channel_no): for scope in run: if scope.tag == 'NI_TCP_Scope': for channel in scope: if channel.tag == 'CH' + str(channel_no): data = channel.text data = [float(value) for value in data.split()] return data def calculate_ion_signal(self): ion_signal_point = 0.0 for ion_signal_point in self.get_ion_scope_channel(): ion_signal += ion_signal_point return ion_signal