Fast autofocus routine

Discussions on extending SharpCap using the built in Python scripting functionality
Post Reply
JesusRL
Posts: 70
Joined: Wed Aug 05, 2020 4:36 pm
Location: Madrid

Fast autofocus routine

#1

Post by JesusRL »

Once you are in focus and after small temperature changes a fast autofocus routine based on finding the fwhm in 3 points (Actual -, actual and actual +), the associated 2nd degree curve and it's minimum

Robin if this is not implemented (surely in a more efficient way by you) in 3.3 as a sequencer step, Will I be able to call it as a scheduled script pasing a param in the new sequencer?

Code: Select all

import time
import sys
from System import Activator
from System import Type
from System.Environment import GetFolderPath, SpecialFolder
from SharpCap.Base import NotificationStatus

############ EXPOSURE SHOULD BE INTRODUCED AS EXTERNAL PARAMS
#exposure_ms = sys.argv[1]
exposure_ms = 500
#################################################
focus_steps = 500
settle_time = 2
average_frames = 10
extra_process_time_ms = 1200 

wait_fwhm = (exposure_ms + extra_process_time_ms) / 1000

SharpCap.SelectedCamera.Controls.Exposure.ExposureMs = exposure_ms
SharpCap.SelectedCamera.RestartPreview()

TemperHum = Activator.CreateInstance(Type.GetTypeFromProgID("ASCOM.OCH.ObservingConditions"))
TemperHum.Connected = True
counter = 0
while TemperHum.Temperature is 0 and counter < 5:
	time.sleep(0.01)
	counter += 1
temperature = round(TemperHum.Temperature, 2)

SharpCap.Focusers.SelectedFocuser.Connected = True
pos_2 = SharpCap.Focusers.SelectedFocuser.Position
pos_1 = pos_2 - focus_steps
pos_3 = pos_2 + focus_steps

SharpCap.Transforms.SelectTransform("FWHM Measurement")

SharpCap.ShowNotification('Acquiring FWHM Center')
fwhm_2 = 0.0
for repeats in range(average_frames):
	fwhm_2 += SharpCap.Transforms.SelectedTransform.FrameTransform.CurrentScore
	time.sleep(wait_fwhm)
fwhm_2 /= average_frames

SharpCap.ShowNotification('Moving In')
SharpCap.Focusers.SelectedFocuser.Move(pos_1)
while SharpCap.Focusers.SelectedFocuser.IsMoving:
	time.sleep(1)
	Application.DoEvents()
time.sleep(settle_time)

SharpCap.ShowNotification('Acquiring FWHM In')
fwhm_1 = 0.0
for repeats in range(average_frames):
	fwhm_1 += SharpCap.Transforms.SelectedTransform.FrameTransform.CurrentScore
	time.sleep(wait_fwhm)
	Application.DoEvents()
fwhm_1 /= average_frames

SharpCap.ShowNotification('Moving Out')
SharpCap.Focusers.SelectedFocuser.Move(pos_3)
while SharpCap.Focusers.SelectedFocuser.IsMoving:
	time.sleep(1)
	Application.DoEvents()
time.sleep(settle_time)
 
SharpCap.ShowNotification('Acquiring FWHM Out')
fwhm_3 = 0.0
for repeats in range(average_frames):
	fwhm_3 += SharpCap.Transforms.SelectedTransform.FrameTransform.CurrentScore
	time.sleep(wait_fwhm)
	Application.DoEvents()
fwhm_3 /= average_frames

if fwhm_1 < fwhm_2 < fwhm_3:
	SharpCap.ShowNotification('Focus below In point. Moving to In point.', NotificationStatus.Error)
	SharpCap.Focusers.SelectedFocuser.Move(pos_1)
	while SharpCap.Focusers.SelectedFocuser.IsMoving:
		Application.DoEvents()
		time.sleep(1)
	SharpCap.ShowNotification('Redo.', NotificationStatus.Error)

else:
	if fwhm_1 > fwhm_2 > fwhm_3:
		SharpCap.ShowNotification('Focus above Out point. Moving to Out point.', NotificationStatus.Error)
		SharpCap.Focusers.SelectedFocuser.Move(pos_3)
		while SharpCap.Focusers.SelectedFocuser.IsMoving:
			Application.DoEvents()
			time.sleep(1)
		SharpCap.ShowNotification('Redo.', NotificationStatus.Error)

	else:
		if fwhm_1 > fwhm_2 < fwhm_3:
			target = - int((pos_3**2 * (fwhm_1 - fwhm_2) + pos_2**2 * (fwhm_3 - fwhm_1) + pos_1**2 * (fwhm_2 - fwhm_3)) / (2 * (pos_3 * (fwhm_2 - fwhm_1) + pos_2 * (fwhm_1 - fwhm_3) + pos_1 * (fwhm_3 - fwhm_2))))

			archivolog = GetFolderPath(SpecialFolder.Desktop) + "\FOCUSLOG\LOG.txt" 
			logfile = open(archivolog, "a")
			logfile.write(time.strftime("%Y%m%d") + "/" + time.strftime("%H%M%S") + " - " + str(pos_2) + " > " + str(target) + " - " + str(round(temperature,2)))
			logfile.write(" - " + str(focus_steps) + " - " + str(round(fwhm_1, 2)) + " - " + str(round(fwhm_2, 2)) + " - " + str(round(fwhm_3, 2)) + "\n")
			logfile.close()

			SharpCap.ShowNotification('Moving to new focus point')
			SharpCap.Focusers.SelectedFocuser.Move(target)
			while SharpCap.Focusers.SelectedFocuser.IsMoving:
				Application.DoEvents()
				time.sleep(1)
			SharpCap.ShowNotification('New focus position: ' + str(target) + '. Focus moved ' +  str((target - pos_2)) + ' steps.')

		else:
			SharpCap.ShowNotification('Invalid data ' + str(round(fwhm_1, 2)) + " - " + str(round(fwhm_2, 2)) + " - " + str(round(fwhm_3, 2)) + '. Moving to Center point.', NotificationStatus.Error)
			SharpCap.Focusers.SelectedFocuser.Move(pos_2)
			while SharpCap.Focusers.SelectedFocuser.IsMoving:
				Application.DoEvents()
				time.sleep(1)
			SharpCap.ShowNotification('Redo.', NotificationStatus.Error)
T&R
JesusRL
Posts: 70
Joined: Wed Aug 05, 2020 4:36 pm
Location: Madrid

Re: Fast autofocus routine

#2

Post by JesusRL »

My main telescopes (C11, C8 & CN212) are focused via primary mirror movement to avoid the use of the available backfocus in extra crayford focuser and use it for ao and oag purposes.

This implies that I have some shift in the images after moving focus. I have thought on recentering the rectangle (ROI) used for fwhm calculation.

To do so I have started on trying to use OpenCVStarDetector, but once I have the results I don't know how to extract them to continue further in the function:

Code: Select all

clr.AddReference("SharpCap.ImageProcessing")
from SharpCap.ImageProcessing import OpenCVStarDetector

ocvsd = OpenCVStarDetector(1,16,1,0.0) 

def handlerR(sender, eventArgs):
	frame          = eventArgs.Frame
	rectangle      = SharpCap.Transforms.SelectionRect
	clipped        = frame.CutROI(rectangle)
	star           = ocvsd.Detect(clipped)
# HOW DO I EXTRACT VALID POSITIONING INFORMATION OF THE STAR FROM star?
	clipped.Release()	

SharpCap.SelectedCamera.FrameCaptured += handlerR
If I print star I get: List[StarInfo]([<SharpCap.ImageProcessing.StarInfo object at 0x0000000000000074 [SharpCap.ImageProcessing.StarInfo]>])

T&R
User avatar
admin
Site Admin
Posts: 13173
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: Fast autofocus routine

#3

Post by admin »

Hi,

the sequencer will not have the ability to pass parameters to Python scripts in this version, sorry. There may be a way to build a workaround by putting the value somewhere that can be written to from the sequencer and read from the python though.

A C# list is basically like an array - you can index it, call .Count to get the number of items or enumerate over it. Each item will be a simple structure containing star information.

hope this helps,

Robin
JesusRL
Posts: 70
Joined: Wed Aug 05, 2020 4:36 pm
Location: Madrid

Re: Fast autofocus routine

#4

Post by JesusRL »

Hi,

As mentioned I want to move the SelectionRect, but it does not when using:

SharpCap.Transforms.SelectionRect.X = 100

Shouldn't this set is X position?

T&R
User avatar
admin
Site Admin
Posts: 13173
Joined: Sat Feb 11, 2017 3:52 pm
Location: Vale of the White Horse, UK
Contact:

Re: Fast autofocus routine

#5

Post by admin »

Hi,

the trick for this is to replace the whole selection rectangle with the one you want. Setting the individual properties doesn't raise a notification to the main SharpCap code (and actually doesn't even set the property properly anyway, since you end up overwriting the value of a temporary copy of the property).

Code: Select all

clr.AddReference("System.Drawing")
from System.Drawing import Rectangle
SharpCap.Transforms.SelectionRect = Rectangle(10,10,10,10)
Robin
Post Reply