Commit d7e19c40 authored by Joel Collins's avatar Joel Collins
Browse files

Included Richards autofocus plugin in defaults

parent cc36aa75
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
import numpy as np

from openflexure_microscope.api.v1.views import MicroscopeViewPlugin
from openflexure_microscope.api.utilities import JsonPayload

from flask import request, Response, escape
from flask import request, Response, escape, jsonify

import logging

@@ -17,3 +20,21 @@ class IdentifyAPI(MicroscopeViewPlugin):
        """
        data = self.microscope.plugin.default.identify()  # Call a method from our plugin, using the full route
        return Response(escape(data))

class MeasureSharpnessAPI(MicroscopeViewPlugin):
    def post(self):
        payload = JsonPayload(request)
        return jsonify({'sharpness': self.plugin.measure_sharpness()})

class AutofocusAPI(MicroscopeViewPlugin):
    def post(self):
        payload = JsonPayload(request)
        
        # Figure out the range of z values to use
        dz = payload.param("dz", default=np.linspace(-300,300,7), convert=np.array)

        print("Running autofocus...")
        task = self.microscope.task.start(self.plugin.autofocus, dz)

        # return a handle on the autofocus task
        return jsonify(task.state, 202)
+21 −0
Original line number Diff line number Diff line
import numpy as np
from scipy import ndimage

def decimate_to(shape, image):
    """Decimate an image to reduce its size if it's too big."""
    decimation = np.max(np.ceil(np.array(image.shape, dtype=np.float)[:len(shape)]/np.array(shape)))
    return image[::int(decimation), ::int(decimation), ...]

def sharpness_sum_lap2(rgb_image):
    """Return an image sharpness metric: sum(laplacian(image)**")"""
    #image_bw=np.mean(decimate_to((1000,1000), rgb_image),2)
    image_bw=np.mean(rgb_image, 2)
    image_lap=ndimage.filters.laplace(image_bw)
    return np.mean(image_lap.astype(np.float)**4)

def sharpness_edge(image):
    """Return a sharpness metric optimised for vertical lines"""
    gray = np.mean(image.astype(float), 2)
    n = 20
    edge = np.array([[-1]*n + [1]*n])
    return np.sum([np.sum(ndimage.filters.convolve(gray,W)**2) for W in [edge, edge.T]])
+38 −2
Original line number Diff line number Diff line
import time
import numpy as np

from openflexure_microscope.plugins import MicroscopePlugin
from openflexure_microscope.utilities import set_properties

from .api import IdentifyAPI
from .focus_utils import sharpness_sum_lap2
from .api import IdentifyAPI, MeasureSharpnessAPI, AutofocusAPI


class Plugin(MicroscopePlugin):
@@ -10,6 +15,8 @@ class Plugin(MicroscopePlugin):

    api_views = {
        '/identify': IdentifyAPI,
        '/measure_sharpness': MeasureSharpnessAPI,
        '/autofocus': AutofocusAPI,
    }

    def identify(self):
@@ -18,5 +25,34 @@ class Plugin(MicroscopePlugin):
        """

        response = "My parent camera is {}, and my parent stage is {}.".format(self.microscope.camera, self.microscope.stage)
        print(response)
        return response

    def autofocus(self, dz, settle=0.5, metric_fn=sharpness_sum_lap2):
        """Perform a simple autofocus routine.
        The stage is moved to z positions (relative to current position) in dz,
        and at each position an image is captured and the sharpness function 
        evaulated.  We then move back to the position where the sharpness was
        highest.  No interpolation is performed.
        dz is assumed to be in ascending order (starting at -ve values)
        """
        camera = self.microscope.camera
        stage = self.microscope.stage

        with set_properties(stage, backlash=256), stage.lock, camera.lock:
            sharpnesses = []
            positions = []
            camera.annotate_text = ""

            for i in stage.scan_z(dz, return_to_start=False):
                positions.append(stage.position[2])
                time.sleep(settle)
                sharpnesses.append(self.measure_sharpness(metric_fn))

            newposition = positions[np.argmax(sharpnesses)]
            stage.focus_rel(newposition - stage.position[2])

        return positions, sharpnesses

    def measure_sharpness(self, metric_fn=sharpness_sum_lap2):
        """Measure the sharpness of the camera's current view."""
        return metric_fn(self.microscope.camera.array(use_video_port=True, resize=(640,480)))