This commit is contained in:
alexgobbo
2024-09-20 12:06:58 +02:00
parent 0692cd7cdc
commit 2c69347d7f
9 changed files with 95 additions and 47 deletions

View File

@@ -46,7 +46,7 @@
"simpleEditor" : false,
"hideEditorLineNumbers" : false,
"hideEditorContextMenu" : false,
"consoleLocation" : "Left",
"consoleLocation" : "Status",
"dataPanelLocation" : null,
"openDataFilesInDocTab" : false,
"noVariableEvaluationPropagation" : false,

View File

@@ -1,4 +1,4 @@
#Tue Sep 17 18:09:54 CEST 2024
#Fri Sep 20 10:59:23 CEST 2024
barcode_reader_scan_pucks=false
beamline_status_enabled=false
cold_position_timeout=3600

View File

@@ -1,9 +1,23 @@
#Tue Sep 17 18:09:58 CEST 2024
center_x=820.0
center_y=570.0
#Fri Sep 20 10:59:27 CEST 2024
center_x=917.0
center_y=1015.0
continuous=false
correlation_threshold=0.0
diam_dewar=null
diam_disk=null
diam_target=null
diameter_target=95
diamter_dewar=1800
diamter_disk=670
mask_dewar=null
mask_disk=null
max_detect_offset=10
modulo=3
number_images=2
offset_threshold=null
open_strategy=both
scale_x=0.3
scale_y=0.3
threshold=0.6
size_mask_dewar=0.98
size_mask_disk=0.8
threshold=0.0

View File

@@ -1,4 +1,4 @@
#Wed Sep 04 15:28:07 CEST 2024
#Fri Sep 20 09:24:26 CEST 2024
colormap=Grayscale
colormapAutomatic=true
colormapLogarithmic=false

View File

@@ -11,12 +11,20 @@ class CoverDetectionConfig(RegisterConfig):
self.center_y = 570.0
self.scale_x = 1.0
self.scale_y = 1.0
self.scale_y = 1.0
self.threshold = 0.60
self.correlation_threshold = 0.60
self.diameter_target=95
self.diamter_disk=670
self.diamter_dewar=1800
self.size_mask_disk=0.8
self.size_mask_dewar=0.98
self.max_detect_offset=10
self.open_strategy = "both"
class CoverCorrelation(ReadonlyAsyncRegisterBase):
def __init__(self, name):
ReadonlyAsyncRegisterBase.__init__(self, name)
self.precision = 3
def set(self, value):
self.onReadout(value)
@@ -96,7 +104,12 @@ class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
ip = integrate(self.images)
try:
self.error = None
x,y = detect(ip)
center = (self.config.center_x, self.config.center_y)
x,y = detect(ip, center, \
diam_target=self.config.diameter_target, diam_disk= self.config.diamter_disk, diam_dewar=self.config.diamter_dewar, \
mask_disk=self.config.size_mask_disk, mask_dewar=self.config.size_mask_dewar, \
offset_threshold=self.config.max_detect_offset ,open_strategy= self.config.open_strategy)
except Exception as e:
self.error = e
x,y = -1, -1
@@ -170,7 +183,7 @@ class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
def set_correlation(self, corr):
self.corr = corr
error = corr is not None and corr < self.config.threshold
error = corr is not None and corr < self.config.correlation_threshold
if error != self.correlation_error:
self.correlation_error = error
if error:

View File

@@ -80,13 +80,19 @@ class VmbCamera (CameraBase):
self.write_parameter("BinningHorizontal", value)
def getBinningX(self):
return self.read_parameter("BinningHorizontal")
try:
return self.read_parameter("BinningHorizontal")
except:
return 1
def setBinningY(self, value):
self.write_parameter("BinningVertical", value)
def getBinningY(self):
return self.read_parameter("BinningVertical")
try:
return self.read_parameter("BinningVertical")
except:
return 1
def setROI(self, x, y, w, h):
self.write_parameter("OffsetX", 0)

View File

@@ -32,7 +32,7 @@ def rms_error(ip1, ip2):
def get_roi_img(img, img_size=1024, radius=512, offset_x=0, offset_y=0):
def get_roi_img(img, img_size=1024, radius=800, offset_x=0, offset_y=0):
x,y,w,h = int(cover_detection.config.center_x-img_size/2 + offset_x), \
int(cover_detection.config.center_y-img_size/2 + offset_y), \
img_size, img_size

View File

@@ -3,15 +3,24 @@ from ijutils import *
import ij.process.Blitter as Blitter
FILL_STRATEGY = "mask" #"mask", "bits", "none"
OPEN_STRATEGY = "both" #"black", "white", "both", "none"
DIAM_1 = 84
DIAM_2 = 550
OFFSET_THRESHOLD= 10 #PIXELS
MASK_SIZE = 0.8 # of DIAM_2
def set_circle_mask(ip, center_x, center_y, radius, bitwise=False):
w, h = ip.getWidth(), ip.getHeight()
if bitwise:
for y in range(h):
for x in range(w):
distance = math.hypot(x - center_x, y - center_y)
if distance >radius:
ip.putPixel(x, y, 0)
else:
mask = ip.createProcessor(w, h) # Creates a new blank ImageProcessor
mask.setColor(255) # Set the drawing color to white (255)
mask.fillOval(int(center_x - radius), int(center_y - radius), int(2 * radius), int(2 * radius)) # Draw the circular ROI
mask.autoThreshold() # Ensures the mask is binary (if needed)
ip.copyBits(mask, 0, 0, Blitter.AND) # Apply the mask using a bitwise AND
def detect(ip, print_table=False, output_image=False):
def detect( ip, center=None, diam_target=95, diam_disk=670, diam_dewar=1800, mask_disk=0.8, mask_dewar=0.98, offset_threshold=10,\
open_strategy = "both", print_table=False, output_image=False):
if output_image==True:
output_image= "outlines"
if ip.getProcessor().isGrayscale():
@@ -20,58 +29,55 @@ def detect(ip, print_table=False, output_image=False):
ig = grayscale(ip, in_place=False)
#Threshoolding
it = auto_threshold(ig, dark_background=True, in_place=False)
w, h = it.getWidth(), it.getHeight()
ip = it.getProcessor()
w, h = ip.getWidth(), ip.getHeight()
if center is None:
center = (int(w/2), int(h/2))
if mask_dewar>0:
set_circle_mask(ip, center_x=center[0], center_y=center[1], radius=diam_dewar*(mask_dewar/2.0), bitwise=False)
#it.show()
if OPEN_STRATEGY in ("black", "both"): #Refine inner
if open_strategy in ("black", "both"): #Refine inner (target)
binary_open(it, dark_background=True, iterations=1, count=1);
if OPEN_STRATEGY in ("white", "both"): #Refine outter
if open_strategy in ("white", "both"): #Refine outer (disk)
binary_open(it, dark_background=False, iterations=1, count=1);
#it.repaintWindow()
#Detect outer white circle
px = int(pow(DIAM_2/2,2) * math.pi)
#Detect outer white circle: disk
px = int(pow(diam_disk/2,2) * math.pi)
(res2,out2)=analyse_particles(it, px/2, px*2, \
fill_holes = True, exclude_edges = True, print_table=print_table, \
output_image = output_image, minCirc = 0.8, maxCirc = 1.0)
if res2.size() != 1:
msg = "Outter detection error: " + ("none" if res2.size()==0 else "")
msg = "Disk detection error: " + ("none" if res2.size()==0 else "")
for i in range( res2.size()):
msg = msg + "(" + str(res2.getValue("XM", 0)) + ", " + str( res2.getValue("YM", 0)) + ")"
raise Exception( msg )
x2,y2 = res2.getValue("XM", 0), res2.getValue("YM", 0)
invert(it, in_place=True)
ip = it.getProcessor()
dist = DIAM_2 * (MASK_SIZE/2.0)
if FILL_STRATEGY == "bits":
for y in range(h):
for x in range(w):
distance = math.hypot(x - x2, y - y2)
if distance >dist:
ip.putPixel(x, y, 0)
elif FILL_STRATEGY == "mask":
mask = ip.createProcessor(w, h) # Creates a new blank ImageProcessor
mask.setColor(255) # Set the drawing color to white (255)
mask.fillOval(int(x2 - dist), int(y2 - dist), int(2 * dist), int(2 * dist)) # Draw the circular ROI
mask.autoThreshold() # Ensures the mask is binary (if needed)
ip.copyBits(mask, 0, 0, Blitter.AND) # Apply the mask using a bitwise AND
px = int(pow(DIAM_1/2,2) * math.pi)
if mask_disk>0:
set_circle_mask(ip, center_x=x2, center_y=x2, radius=diam_disk*(mask_disk/2.0), bitwise=False)
#Detect inner black circle: target
px = int(pow(diam_target/2,2) * math.pi)
(res1,out1)=analyse_particles(it, px/2, px*2, \
fill_holes = FILL_STRATEGY!="none", exclude_edges = True, print_table=print_table, \
fill_holes = True, exclude_edges = True, print_table=print_table, \
output_image = output_image, minCirc = 0.8, maxCirc = 1.0)
if res1.size() != 1:
msg = "Inner detection error: " + ("none" if res1.size()==0 else "")
msg = "Target detection error: " + ("none" if res1.size()==0 else "")
for i in range( res1.size()):
msg = msg + "(" + str(res1.getValue("XM", 0)) + ", " + str( res2.res1("YM", 0)) + "), "
raise Exception( msg )
x1,y1 = res1.getValue("XM", 0), res1.getValue("YM", 0)
if abs(x1-x2) > OFFSET_THRESHOLD or abs(y1-y2) > OFFSET_THRESHOLD:
msg = "Detection offset error: " + + "(" + str(x1-x2) + ", " + str(y1-y2) + ")"
if abs(x1-x2) > offset_threshold or abs(y1-y2) > offset_threshold:
msg = "Disk/Target offset error: " + "(" + str(int(x1-x2)) + ", " + str(int(y1-y2)) + ")"
raise Exception( msg )
return x1,y1

View File

@@ -0,0 +1,9 @@
roi =get_roi_img(image.output, img_size=1800, radius=800)
img = load_image(roi, title="ip_ref")
imge =get_edge_img(roi)
imgf = image_fft(img)
imgfe = image_fft(imge)
st=create_stack([img, imge,imgf, imgfe])
st.show()