{"id":38008,"date":"2023-07-21T11:22:34","date_gmt":"2023-07-21T10:22:34","guid":{"rendered":"https:\/\/photonics.laser2000.co.uk\/?p=38008"},"modified":"2023-07-21T11:22:34","modified_gmt":"2023-07-21T10:22:34","slug":"autofocus-a-microscope-using-python","status":"publish","type":"post","link":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008","title":{"rendered":"Autofocus a Microscope using Python"},"content":{"rendered":"\n<p>To acquire a sharp image from a microscope requires that the sample be in focus. This is achieved by positioning the sample at the correct distance from the objective lens. The human eyes and brain are good at judging when an image is in focus, so a typical workflow here is to manually move the objective up and down, watching the resulting image until it looks good. However, this process is tedious, subjective, and requires a person to be present every time a slide or objective is changed.<\/p>\n\n\n\n<p>So why not let a computer handle it? In this article, we&#8217;ll show you how to leverage the power of a motorised focus axis by using&nbsp;<a href=\"https:\/\/opencv.org\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>OpenCV<\/strong><\/a>&nbsp;to automatically discover a good position in fewer than 100 lines of Python code. This allows you to obtain sharp images from your microscope without human intervention, even as slides are moved and objectives are switched out.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Example_Script\">Example Script<\/h3>\n\n\n\n<p>You can download the complete Python example script&nbsp;<a href=\"https:\/\/www.zaber.com\/w\/images\/c\/c2\/Zaber-autofocus-example.zip\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>here<\/strong><\/a>.<\/p>\n\n\n\n<p>The example code is all written for a&nbsp;<a href=\"https:\/\/stagingphotonics.laser2000.co.uk\/products\/manual-and-motorised-motion\/systems-controllers-and-accessories\/scanning-microscope\/motorized-inverted-microscope-platform\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Zaber Microscope<\/strong><\/a>, controlling motion with&nbsp;<a href=\"https:\/\/www.zaber.com\/software\/docs\/motion-library\/ascii\/references\/python\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Zaber Motion Library<\/strong><\/a>.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Dependencies\">Dependencies<\/h3>\n\n\n\n<p>This example uses a Teledyne FLIR BFLY-U3-23S6M-C camera. The Spinnaker SDK, Spinnaker Python package and Simple Pyspin package are used to control the camera settings and image acquisition. While different cameras will require manufacturer specific SDKs, the basic principles used in this example can be applied to any camera that provides a Python API.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"Spinnaker_SDK\">Spinnaker SDK<\/h5>\n\n\n\n<p>Download the latest version of the Spinnaker SKD and Spinnaker Python package which are available&nbsp;<a href=\"https:\/\/flir.app.boxcn.net\/v\/SpinnakerSDK\/folder\/68522911814\"><strong>here<\/strong><\/a>. Install the Spinnaker SDK, but do not install the Spinnaker Python package yet. Take note of the file name of the Spinnaker Python package you downloaded. At the time of writing, the most recent version is spinnaker_python-2.7.0.128-cp38-cp38-win_amd64.zip. The &#8220;cp38&#8221; in the file name indicates that this package is compatible with Python 3.8. This is the version of Python you should install in the next step. If you are currently using \u00b5Manager software to control a microscope with a Point Grey Research or Teledyne FLIR camera, please be aware that recent versions of Spinnaker are not compatible with \u00b5Manager. You will need to downgrade Spinnaker prior to using \u00b5Manager.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"Python\">Python<\/h5>\n\n\n\n<p>It is recommended to install the version of Python matching the version of the Spinnaker Python package you noted above.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"Python_packages\">Python packages<\/h5>\n\n\n\n<p>After installing the recommended version of Python, install the following python packages:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Spinnaker Python.<\/li>\n\n\n\n<li>Zaber Motion Library. Detailed information on how to install Zaber Motion Library for Python is available&nbsp;<a href=\"https:\/\/www.zaber.com\/software\/docs\/motion-library\/ascii\/tutorials\/install\/py\/\"><strong>here<\/strong><\/a>.<\/li>\n\n\n\n<li>OpenCV. This package is a widely used library for computer vision. It is used here to analyse the images captured by the camera. Detailed information on how to install OpenCV for Python is available&nbsp;<a href=\"https:\/\/pypi.org\/project\/opencv-python\/\"><strong>here<\/strong><\/a>.<\/li>\n\n\n\n<li>Simple Pyspin. This package provides simple, streamlined commands for controlling the basic operations of Teledyne FLIR cameras. Detailed information on how to install Simple Pyspin is available&nbsp;<a href=\"https:\/\/github.com\/klecknerlab\/simple_pyspin\/\"><strong>here<\/strong><\/a>.<\/li>\n<\/ul>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Parameters\">Parameters<\/h3>\n\n\n\n<p>The example script takes four parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>start_mm<\/code>: the position, in millimetres, to start the search at.<\/li>\n\n\n\n<li><code>end_mm<\/code>: the position, in millimeters, to end the search at.<\/li>\n\n\n\n<li><code>step size_mm<\/code>: the size of step to take between each image capture. This must be small enough that the ideal focal position isn&#8217;t completely skipped. But be careful, if this is too small, the script will take a very long time to run.<\/li>\n\n\n\n<li><code>microscope_serial_port<\/code>: the port that the Zaber Microscope is connected to. See the&nbsp;<a href=\"https:\/\/www.zaber.com\/software\/docs\/motion-library\/ascii\/howtos\/find_right_port\/\"><strong>ZML guide<\/strong><\/a>&nbsp;for help finding the port name.<\/li>\n<\/ul>\n\n\n\n<p>There are also a number of optional parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>--verbose<\/code>: The script will print out some information at each step<\/li>\n\n\n\n<li><code>--show-images<\/code>: The script will display the image, filtered image and Laplacian image for each step to debug issues. This should not be used for more than ~10 steps, as the program can run out of memory holding on to all the images<\/li>\n\n\n\n<li><code>--blur [int]<\/code>: Pass in a new value to blur with (default 9). The higher the blur parameter, the less noise will dominate the outcome<\/li>\n<\/ul>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"Initialization\">Initialisation<\/h3>\n\n\n\n<p>First, it will initialize the motor and camera:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted has-l-2-k-blue-5-background-color has-background\">   with Connection.open_serial_port(microscope_serial_port) as connection, Camera() as cam:\n       # Initialize control of the the vertical axis of the microscope\n       z_axis = connection.get_device(3).get_axis(1)\n<\/pre>\n\n\n\n<p><br>In the example code, I&#8217;ll be using the following pyspin and ZML functions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>cam.get_array<\/code>: returns an image from the camera in a format that OpenCV can use<\/li>\n\n\n\n<li><code>z_axis.move_absolute<\/code>: moves the Z axis of the microscope to a specified position<\/li>\n<\/ul>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"The_Main_Loop\">The Main Loop<\/h3>\n\n\n\n<p>This is the primary control loop of the program:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted has-l-2-k-blue-5-background-color has-background\">       best_focus_score = 0\n       best_focus_score = 0\n       best_focus_position = 0\n       # How many steps to take to achieve the desired step size, +1 to check end_mm\n       steps = math.ceil((end_mm - start_mm)\/step_size_mm) + 1\n       for step in range(0, steps):\n           position = min(start_mm + step * step_size_mm, end_mm)\n           z_axis.move_absolute(position, Units.LENGTH_MILLIMETRES)\n           image = get_image(cam)\n           focus_score = calculate_focus_score(image, blur, position)\n           if focus_score &gt; best_focus_score:\n               best_focus_position = position\n               best_focus_score = focus_score\n<\/pre>\n\n\n\n<p><br>It begins by setting the best focus score to 0, and then stepping the axis forward&nbsp;<code>step_size_mm<\/code>&nbsp;at a time. At each step it takes an image, calculates its focus score (discussed in the next section) and then, if this is better than the previous best, saves this focus score and position. After this loop is complete, the best focus score found will be stored in&nbsp;<code>best_focus_score<\/code>, and the position it was found at in&nbsp;<code>best_focus_position<\/code>.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"The_Focus_Score\">The Focus Score<\/h3>\n\n\n\n<p>One of the simpler ways to quantify the focus of an image is to take the variance of the Laplacian. The code for doing so with OpenCV is shown here:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def calculate_focus_score(image, blur, position):\n   image_filtered = cv.medianBlur(image, blur)\n   laplacian = cv.Laplacian(image_filtered, cv.CV_64F)\n   focus_score = laplacian.var()\n   return focus_score\n<\/pre>\n\n\n\n<p><br>Going line by line, this function:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/docs.opencv.org\/4.x\/d4\/d13\/tutorial_py_filtering.html\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Applies Filtering<\/strong><\/a>: A filter that removes random noise from the image, without degrading edges.<\/li>\n\n\n\n<li>Takes the Laplacian: An image processing technique comparable to differentiating in 2 dimensions. It will be large at points where adjacent pixels have very different intensities (such as at edges) and small when adjacent pixels have similar intensities. In general, a well focused image will have more pronounced edges, leading to sharp peaks in the Laplacian. For example, here are two images and their corresponding Laplacian:<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image alignright size-full\"><img decoding=\"async\" src=\"https:\/\/stagingphotonics.laser2000.co.uk\/wp-content\/uploads\/2023\/07\/250px-Autofocus_blurry_image.png\" alt=\"\" class=\"wp-image-37990\"\/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image alignleft size-full\"><img decoding=\"async\" src=\"https:\/\/stagingphotonics.laser2000.co.uk\/wp-content\/uploads\/2023\/07\/250px-Autofocus_weak_edges.png\" alt=\"\" class=\"wp-image-37989\"\/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p class=\"has-text-align-center has-small-font-size\">A blurry image results in weakly detected edges<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image alignright size-full\"><img decoding=\"async\" src=\"https:\/\/stagingphotonics.laser2000.co.uk\/wp-content\/uploads\/2023\/07\/250px-Autofocus_focused_image.png\" alt=\"\" class=\"wp-image-37988\"\/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image alignleft size-full\"><img decoding=\"async\" src=\"https:\/\/stagingphotonics.laser2000.co.uk\/wp-content\/uploads\/2023\/07\/250px-Autofocus_defined_edges.png\" alt=\"\" class=\"wp-image-37987\"\/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p class=\"has-text-align-center has-small-font-size\">A more focused image, showing more defined lines in the Laplacian<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Calculates Variance: A statistical measure of how much a series diverges from the average. If the Laplacian has well defined peaks, these result in a higher variance, as there will be many points well outside the average, thus a greater value for the variance of the Laplacian indicates a better focus.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img decoding=\"async\" src=\"https:\/\/stagingphotonics.laser2000.co.uk\/wp-content\/uploads\/2023\/07\/Autofocus.gif\" alt=\"An animation showing a series of filtered images captured by stepping through a section, the corresponding Laplacian images, and a chart showing the variance of each. The peak of the variance represents the most in-focus position.\" class=\"wp-image-37986\"\/><figcaption class=\"wp-element-caption\">An animation showing a series of filtered images captured by stepping through a section, the corresponding Laplacian images, and a chart showing the variance of each. The peak of the variance represents the most in-focus position.<\/figcaption><\/figure>\n\n\n\n<p><br>All of these are standard functions in&nbsp;<a href=\"https:\/\/opencv.org\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>OpenCV<\/strong><\/a>, allowing this focus score function to be written in just four lines of code.<\/p>\n\n\n\n<p>This method is inspired by Blur Detection with OpenCV. See more details see:&nbsp;<a href=\"https:\/\/pyimagesearch.com\/2015\/09\/07\/blur-detection-with-opencv\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>https:\/\/pyimagesearch.com\/2015\/09\/07\/blur-detection-with-opencv\/<\/strong><\/a>.<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"Troubleshooting_Tips\">Troubleshooting Tips<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If you encounter an error from when running the example script, check the COM Port number and the device order with Zaber Launcher. On a Zaber MVR microscope, the Z focus stage is the X-LDA025 stage. Zaber launcher should be closed after you have finished checking, or your script will not connect to it.<\/li>\n\n\n\n<li>Use an objective lens with a larger depth of field. An objective with a lower numerical aperture will increase the depth of field and help achieve a sharp focus, though increased sharpness may come at the expense of decreased signal to noise ratio on thicker samples.<\/li>\n\n\n\n<li>Add a fiducial marker in the desired focal plane of your sample to provide sharp, easily detected edges<\/li>\n\n\n\n<li>High magnification objectives are very sensitive to vibrations of the sample. If the microscope is not mounted to a stable base, vibrations will result in blurry images even if the focus position is correct. Allowing enough time for the system to settle after movements of the focus stage is also critical to achieving sharp images with high magnification objectives.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>To acquire a sharp image from a microscope requires that the sample be in focus. This is achieved by positioning the sample [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":38753,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[17,29],"tags":[],"class_list":["post-38008","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blogs","category-motion-control"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v22.6 (Yoast SEO v27.7) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Autofocus a Microscope using Python - Laser 2000<\/title>\n<meta name=\"description\" content=\"Autofocus a microscope using Python to acquire a sharp image from a microscope requires that the sample be in focus.\" \/>\n<meta name=\"robots\" content=\"noindex, follow\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Autofocus a Microscope using Python\" \/>\n<meta property=\"og:description\" content=\"Autofocus a microscope using Python to acquire a sharp image from a microscope requires that the sample be in focus.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008\" \/>\n<meta property=\"og:site_name\" content=\"Laser 2000\" \/>\n<meta property=\"article:published_time\" content=\"2023-07-21T10:22:34+00:00\" \/>\n<meta name=\"author\" content=\"ashish.khanna.uk@gmail.com\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"ashish.khanna.uk@gmail.com\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008\"},\"author\":{\"name\":\"ashish.khanna.uk@gmail.com\",\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/#\\\/schema\\\/person\\\/f260f7a829ec1e4f3ddb78199afd3883\"},\"headline\":\"Autofocus a Microscope using Python\",\"datePublished\":\"2023-07-21T10:22:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008\"},\"wordCount\":1245,\"image\":{\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008#primaryimage\"},\"thumbnailUrl\":\"\",\"articleSection\":[\"Blogs\",\"Motion Control\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008\",\"url\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008\",\"name\":\"Autofocus a Microscope using Python - Laser 2000\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008#primaryimage\"},\"thumbnailUrl\":\"\",\"datePublished\":\"2023-07-21T10:22:34+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/#\\\/schema\\\/person\\\/f260f7a829ec1e4f3ddb78199afd3883\"},\"description\":\"Autofocus a microscope using Python to acquire a sharp image from a microscope requires that the sample be in focus.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008#primaryimage\",\"url\":\"\",\"contentUrl\":\"\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?p=38008#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Autofocus a Microscope using Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/#website\",\"url\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/\",\"name\":\"Laser 2000\",\"description\":\"Your Partner for Photonics Solutions\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/#\\\/schema\\\/person\\\/f260f7a829ec1e4f3ddb78199afd3883\",\"name\":\"ashish.khanna.uk@gmail.com\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/41fd2f83ee145e22b51c92ad64c83a4d91c0a30bf6c146f6e1bc5bac28e55c70?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/41fd2f83ee145e22b51c92ad64c83a4d91c0a30bf6c146f6e1bc5bac28e55c70?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/41fd2f83ee145e22b51c92ad64c83a4d91c0a30bf6c146f6e1bc5bac28e55c70?s=96&d=mm&r=g\",\"caption\":\"ashish.khanna.uk@gmail.com\"},\"sameAs\":[\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\"],\"url\":\"https:\\\/\\\/stagingphotonics.laser2000.co.uk\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Autofocus a Microscope using Python - Laser 2000","description":"Autofocus a microscope using Python to acquire a sharp image from a microscope requires that the sample be in focus.","robots":{"index":"noindex","follow":"follow"},"og_locale":"en_GB","og_type":"article","og_title":"Autofocus a Microscope using Python","og_description":"Autofocus a microscope using Python to acquire a sharp image from a microscope requires that the sample be in focus.","og_url":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008","og_site_name":"Laser 2000","article_published_time":"2023-07-21T10:22:34+00:00","author":"ashish.khanna.uk@gmail.com","twitter_card":"summary_large_image","twitter_misc":{"Written by":"ashish.khanna.uk@gmail.com","Estimated reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008#article","isPartOf":{"@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008"},"author":{"name":"ashish.khanna.uk@gmail.com","@id":"https:\/\/stagingphotonics.laser2000.co.uk\/#\/schema\/person\/f260f7a829ec1e4f3ddb78199afd3883"},"headline":"Autofocus a Microscope using Python","datePublished":"2023-07-21T10:22:34+00:00","mainEntityOfPage":{"@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008"},"wordCount":1245,"image":{"@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008#primaryimage"},"thumbnailUrl":"","articleSection":["Blogs","Motion Control"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008","url":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008","name":"Autofocus a Microscope using Python - Laser 2000","isPartOf":{"@id":"https:\/\/stagingphotonics.laser2000.co.uk\/#website"},"primaryImageOfPage":{"@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008#primaryimage"},"image":{"@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008#primaryimage"},"thumbnailUrl":"","datePublished":"2023-07-21T10:22:34+00:00","author":{"@id":"https:\/\/stagingphotonics.laser2000.co.uk\/#\/schema\/person\/f260f7a829ec1e4f3ddb78199afd3883"},"description":"Autofocus a microscope using Python to acquire a sharp image from a microscope requires that the sample be in focus.","breadcrumb":{"@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008#primaryimage","url":"","contentUrl":""},{"@type":"BreadcrumbList","@id":"https:\/\/stagingphotonics.laser2000.co.uk\/?p=38008#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/stagingphotonics.laser2000.co.uk\/"},{"@type":"ListItem","position":2,"name":"Autofocus a Microscope using Python"}]},{"@type":"WebSite","@id":"https:\/\/stagingphotonics.laser2000.co.uk\/#website","url":"https:\/\/stagingphotonics.laser2000.co.uk\/","name":"Laser 2000","description":"Your Partner for Photonics Solutions","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/stagingphotonics.laser2000.co.uk\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/stagingphotonics.laser2000.co.uk\/#\/schema\/person\/f260f7a829ec1e4f3ddb78199afd3883","name":"ashish.khanna.uk@gmail.com","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/41fd2f83ee145e22b51c92ad64c83a4d91c0a30bf6c146f6e1bc5bac28e55c70?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/41fd2f83ee145e22b51c92ad64c83a4d91c0a30bf6c146f6e1bc5bac28e55c70?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/41fd2f83ee145e22b51c92ad64c83a4d91c0a30bf6c146f6e1bc5bac28e55c70?s=96&d=mm&r=g","caption":"ashish.khanna.uk@gmail.com"},"sameAs":["https:\/\/stagingphotonics.laser2000.co.uk"],"url":"https:\/\/stagingphotonics.laser2000.co.uk\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/38008","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=38008"}],"version-history":[{"count":0,"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/38008\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=\/"}],"wp:attachment":[{"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=38008"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=38008"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/stagingphotonics.laser2000.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=38008"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}