Beispiel #1
0
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