This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#Thu Sep 12 16:17:12 CEST 2024
|
||||
#Fri Sep 13 09:52:22 CEST 2024
|
||||
barcode_reader_scan_pucks=false
|
||||
beamline_status_enabled=false
|
||||
cold_position_timeout=3600
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#Fri Sep 13 10:02:48 CEST 2024
|
||||
center_x=820.0
|
||||
center_y=570.0
|
||||
continuous=false
|
||||
modulo=3
|
||||
number_images=2
|
||||
scale_x=0.3
|
||||
scale_y=0.3
|
||||
@@ -0,0 +1,129 @@
|
||||
run("imgproc/NewCoverDetection")
|
||||
|
||||
|
||||
class CoverDetectionConfig(RegisterConfig):
|
||||
def __init__(self):
|
||||
self.number_images = 1
|
||||
self.continuous = False
|
||||
self.modulo = 1
|
||||
self.center_x = 820.0
|
||||
self.center_y = 570.0
|
||||
self.scale_x = 1.0
|
||||
self.scale_y = 1.0
|
||||
|
||||
class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
|
||||
|
||||
def __init__(self, name, image):
|
||||
ReadonlyAsyncRegisterBase.__init__(self, name, CoverDetectionConfig())
|
||||
self.image = image
|
||||
|
||||
class ImgListener (ImageListener):
|
||||
def onImage(s, origin, image, data):
|
||||
self.append(image)
|
||||
def onError(s, origin, ex):
|
||||
print ex
|
||||
|
||||
self.listener = ImgListener()
|
||||
self.enabled = False
|
||||
self.images = []
|
||||
self.processing_time = None
|
||||
self.renderer = None
|
||||
self.error = None
|
||||
self.error_overlay=None
|
||||
self.img_counter, self.proc_counter = 0, 0
|
||||
self.offset_px = self.offset_um = None
|
||||
|
||||
def doInitialize(self):
|
||||
self.enable()
|
||||
self.clear()
|
||||
|
||||
def doClose(self):
|
||||
self.disable()
|
||||
|
||||
def set_renderer(self, renderer):
|
||||
self.clear()
|
||||
self.renderer = renderer
|
||||
|
||||
def enable(self):
|
||||
if not self.enabled:
|
||||
self.enabled = True
|
||||
self.image.addListener(self.listener)
|
||||
self.img_counter, self.proc_counter = 0, 0
|
||||
self.offset_px = self.offset_um = None
|
||||
|
||||
def disable(self):
|
||||
if self.enabled:
|
||||
self.image.removeListener(self.listener)
|
||||
self.enabled = False
|
||||
self.onReadout(None)
|
||||
self.clear()
|
||||
|
||||
def clear(self):
|
||||
self.set_marker(None)
|
||||
self.set_error_overlay(None)
|
||||
|
||||
def append(self, image):
|
||||
self.img_counter += 1
|
||||
if self.img_counter % self.config.modulo == 0:
|
||||
ip = load_image(ImagingUtils.grayscale(image, None))
|
||||
self.images.append(ip)
|
||||
while len(self.images) > self.config.number_images:
|
||||
self.images.pop(0)
|
||||
if len(self.images) == self.config.number_images:
|
||||
start = time.time()
|
||||
if len(self.images) ==1:
|
||||
ip = self.images[0]
|
||||
else:
|
||||
ip = integrate(self.images)
|
||||
try:
|
||||
self.error = None
|
||||
x,y = detect(ip)
|
||||
except Exception as e:
|
||||
self.error = e
|
||||
x,y = -1, -1
|
||||
self.processing_time = time.time()-start
|
||||
self.proc_counter += 1
|
||||
self.set(x, y, self.processing_time * 1000, self.error)
|
||||
if not self.config.continuous:
|
||||
self.images=[]
|
||||
|
||||
def set(self, x, y, tm, error):
|
||||
if self.enabled:
|
||||
if error:
|
||||
self.offset_px = self.offset_um = None
|
||||
value = None
|
||||
else:
|
||||
offx, offy = x-cover_detection.config.center_x, -(y-cover_detection.config.center_y)
|
||||
self.offset_px = opx, opy = round(offx), round(offy)
|
||||
self.offset_um = omx, omy = self.config.scale_x * offx * 1000.0, self.config.scale_y * offy *1000.0
|
||||
value = to_array([x, y, opx, opy, omx, omy, tm], 'i')
|
||||
self.onReadout(value)
|
||||
if self.renderer is not None:
|
||||
if error is None:
|
||||
marker = Overlays.Crosshairs(renderer.getPenProfile(), Point(int(x),int(y)), Dimension(-1, -1))
|
||||
else:
|
||||
marker = None
|
||||
self.set_marker(marker);
|
||||
self.set_error_overlay(error)
|
||||
|
||||
def set_marker(self, marker):
|
||||
if self.renderer is not None:
|
||||
self.renderer.setMarker(marker)
|
||||
|
||||
def set_error_overlay(self, error):
|
||||
if self.renderer is not None:
|
||||
if error is None:
|
||||
error_overlay = None
|
||||
else:
|
||||
error_overlay = Overlays.Text(renderer.getPenErrorText(), str(error), Font("Verdana", Font.PLAIN, 12), Point(20, 20))
|
||||
error_overlay.setFixed(True)
|
||||
error_overlay.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT)
|
||||
renderer.updateOverlays(error_overlay, self.error_overlay)
|
||||
self.error_overlay = error_overlay
|
||||
else:
|
||||
self.error_overlay = None
|
||||
|
||||
|
||||
add_device(CoverDetection("cover_detection", image), force = True)
|
||||
renderer=show_panel(image)
|
||||
cover_detection.set_renderer(renderer)
|
||||
@@ -7,10 +7,8 @@ FILL_STRATEGY = "mask" #"mask", "bits", "none"
|
||||
OPEN_STRATEGY = "both" #"black", "white", "both", "none"
|
||||
DIAM_1 = 84
|
||||
DIAM_2 = 550
|
||||
DETECT_THRESHOLD = 10 #PIXELS
|
||||
FRAMES = 5
|
||||
OFFSET_THRESHOLD= 10 #PIXELS
|
||||
MASK_SIZE = 0.8 # of DIAM_2
|
||||
ROLLING_WINDOW = False
|
||||
|
||||
|
||||
def detect(ip, print_table=False, output_image=False):
|
||||
@@ -72,134 +70,11 @@ def detect(ip, print_table=False, output_image=False):
|
||||
|
||||
x1,y1 = res1.getValue("XM", 0), res1.getValue("YM", 0)
|
||||
|
||||
if abs(x1-x2) > DETECT_THRESHOLD or abs(y1-y2) > DETECT_THRESHOLD:
|
||||
msg = "Detection offseterror: " + + "(" + str(x1-x2) + ", " + str(y1-y2) + ")"
|
||||
if abs(x1-x2) > OFFSET_THRESHOLD or abs(y1-y2) > OFFSET_THRESHOLD:
|
||||
msg = "Detection offset error: " + + "(" + str(x1-x2) + ", " + str(y1-y2) + ")"
|
||||
raise Exception( msg )
|
||||
|
||||
return x1,y1
|
||||
|
||||
"""
|
||||
if FRAMES>1:
|
||||
ip = integrate_frames(samples = FRAMES)
|
||||
else:
|
||||
ip = load_image(image.output, title="Image")
|
||||
|
||||
try:
|
||||
x,y = detect(ip)
|
||||
print("Detected: ", (x, y))
|
||||
p = Point(int(x),int(y))
|
||||
ov = Overlays.Crosshairs(renderer.getPenProfile(), p, Dimension(-1, -1))
|
||||
renderer.setMarker(ov);
|
||||
except Exception as e:
|
||||
traceback.print_exc(e)
|
||||
print(e)
|
||||
renderer.setMarker(None)
|
||||
"""
|
||||
|
||||
error_overlay=None
|
||||
def clear_error_overlay(renderer):
|
||||
global error_overlay
|
||||
try:
|
||||
renderer.removeOverlay(error_overlay)
|
||||
except:
|
||||
pass
|
||||
error_overlay = None
|
||||
|
||||
def add_error_overlay(renderer, error):
|
||||
global error_overlay
|
||||
former = error_overlay
|
||||
error_overlay = Overlays.Text(renderer.getPenErrorText(), error, Font("Verdana", Font.PLAIN, 12), Point(20, 20))
|
||||
error_overlay.setFixed(True)
|
||||
error_overlay.setAnchor(Overlay.ANCHOR_VIEWPORT_TOP_LEFT)
|
||||
renderer.updateOverlays(error_overlay, former)
|
||||
|
||||
|
||||
class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
|
||||
|
||||
def __init__(self, name, image, renderer):
|
||||
ReadonlyAsyncRegisterBase.__init__(self, name)
|
||||
self.image = image
|
||||
|
||||
class ImgListener (ImageListener):
|
||||
def onImage(s, origin, image, data):
|
||||
self.append(image)
|
||||
def onError(s, origin, ex):
|
||||
print ex
|
||||
|
||||
self.listener = ImgListener()
|
||||
self.enabled = False
|
||||
self.images = []
|
||||
self.processing_time = None
|
||||
self.renderer = renderer
|
||||
self.error = None
|
||||
|
||||
|
||||
def doInitialize(self):
|
||||
print "Init"
|
||||
#super(ReadonlyAsyncRegisterBase, self).doInitialize()
|
||||
#ReadonlyRegisterBase.doInitialize(self)
|
||||
self.enable()
|
||||
self.clear()
|
||||
|
||||
def doClose(self):
|
||||
print 1
|
||||
self.disable()
|
||||
print 2
|
||||
#DeviceBase.doClose(self)
|
||||
#print 3
|
||||
|
||||
|
||||
def enable(self):
|
||||
if not self.enabled:
|
||||
self.enabled = True
|
||||
self.image.addListener(self.listener)
|
||||
|
||||
def disable(self):
|
||||
if self.enabled:
|
||||
self.image.removeListener(self.listener)
|
||||
self.enabled = False
|
||||
self.onReadout(None)
|
||||
self.clear()
|
||||
|
||||
def clear(self):
|
||||
if self.renderer is not None:
|
||||
renderer.setMarker(None)
|
||||
clear_error_overlay(renderer)
|
||||
|
||||
def append(self, image):
|
||||
ip = load_image(ImagingUtils.grayscale(image, None))
|
||||
self.images.append(ip)
|
||||
while len(self.images) > FRAMES:
|
||||
self.images.pop(0)
|
||||
if len(self.images) == FRAMES:
|
||||
ip = integrate(self.images)
|
||||
#print type(ip)
|
||||
start = time.time()
|
||||
try:
|
||||
self.error = None
|
||||
x,y = detect(ip)
|
||||
except Exception as e:
|
||||
self.error = e
|
||||
x,y = -1, -1
|
||||
self.processing_time = time.time()-start
|
||||
self.set(x, y, self.processing_time * 1000, self.error)
|
||||
if not ROLLING_WINDOW:
|
||||
self.images=[]
|
||||
|
||||
def set(self, x, y, tm, error):
|
||||
if self.enabled:
|
||||
value = to_array([x, y, tm], 'i')
|
||||
self.onReadout(value)
|
||||
if self.renderer is not None:
|
||||
if error is None:
|
||||
clear_error_overlay(renderer)
|
||||
marker = Overlays.Crosshairs(renderer.getPenProfile(), Point(int(x),int(y)), Dimension(-1, -1))
|
||||
else:
|
||||
add_error_overlay(renderer, str(error))
|
||||
marker = None
|
||||
renderer.setMarker(marker);
|
||||
|
||||
renderer=show_panel(image)
|
||||
add_device(CoverDetection("cover_detection", image, renderer), force = True)
|
||||
|
||||
|
||||
|
||||
@@ -1,80 +1,16 @@
|
||||
import math
|
||||
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
|
||||
DETECT_THRESHOLD = 10 #PIXELS
|
||||
FRAMES = 1
|
||||
MASK_SIZE = 0.8 # of DIAM_2
|
||||
|
||||
|
||||
renderer=show_panel(image)
|
||||
renderer.setMarker(None);
|
||||
start = time.time()
|
||||
|
||||
#Image Loading
|
||||
FRAMES =5
|
||||
if FRAMES>1:
|
||||
ig = integrate_frames(samples = FRAMES)
|
||||
ip = integrate_frames(samples = FRAMES)
|
||||
else:
|
||||
ip = load_image(image.output, title="Image")
|
||||
ig = grayscale(ip, in_place=False)
|
||||
ip = load_image(image.output, title="Image")
|
||||
|
||||
|
||||
#Threshoolding
|
||||
it = auto_threshold(ig, dark_background=True, in_place=False)
|
||||
w, h = it.getWidth(), it.getHeight()
|
||||
#it.show()
|
||||
if OPEN_STRATEGY in ("black", "both"): #Refine inner
|
||||
binary_open(it, dark_background=True, iterations=1, count=1);
|
||||
if OPEN_STRATEGY in ("white", "both"): #Refine outter
|
||||
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)
|
||||
(res2,out2)=analyse_particles(it, px/2, px*2, \
|
||||
fill_holes = True, exclude_edges = True, print_table=True, \
|
||||
output_image = "outlines", minCirc = 0.8, maxCirc = 1.0)
|
||||
|
||||
if res2.size() == 1:
|
||||
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
|
||||
|
||||
#it.show()
|
||||
px = int(pow(DIAM_1/2,2) * math.pi)
|
||||
(res1,out1)=analyse_particles(it, px/2, px*2, \
|
||||
fill_holes = FILL_STRATEGY!="none", exclude_edges = True, print_table=True, \
|
||||
output_image = "outlines", minCirc = 0.8, maxCirc = 1.0)
|
||||
|
||||
if res1.size() == res2.size() == 1:
|
||||
x1,y1 = res1.getValue("XM", 0), res1.getValue("YM", 0)
|
||||
|
||||
|
||||
if abs(x1-x2) <= DETECT_THRESHOLD and abs(y1-y2) <= DETECT_THRESHOLD:
|
||||
print("Detected: ", (x1, y1))
|
||||
renderer=show_panel(image)
|
||||
p = Point(int(x1),int(y1))
|
||||
ov = Overlays.Crosshairs(renderer.getPenProfile(), p, Dimension(-1, -1))
|
||||
renderer.setMarker(ov);
|
||||
|
||||
|
||||
|
||||
print "Processing time:", time.time()-start
|
||||
try:
|
||||
x,y = detect(ip)
|
||||
print("Detected: ", (x, y))
|
||||
p = Point(int(x),int(y))
|
||||
ov = Overlays.Crosshairs(renderer.getPenProfile(), p, Dimension(-1, -1))
|
||||
renderer.setMarker(ov);
|
||||
except Exception as e:
|
||||
traceback.print_exc(e)
|
||||
print(e)
|
||||
renderer.setMarker(None)
|
||||
|
||||
Reference in New Issue
Block a user