This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
Image_Correlator.java=enabled
|
||||
MXSC-1.14.0.jar=disabled
|
||||
MXSC-1.15.0.jar=disabled
|
||||
Commands.java=disabled
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Fri Sep 13 09:52:22 CEST 2024
|
||||
#Tue Sep 17 18:09:54 CEST 2024
|
||||
barcode_reader_scan_pucks=false
|
||||
beamline_status_enabled=false
|
||||
cold_position_timeout=3600
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
tasks/LedMonitoring=120.0;120.0
|
||||
tasks/ColdPositionTimeout=300.0;300.0
|
||||
#tasks/Reinit=30.0;30.0
|
||||
#test/TestCorrelation=1.0;1.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Fri Sep 13 10:02:48 CEST 2024
|
||||
#Tue Sep 17 18:09:58 CEST 2024
|
||||
center_x=820.0
|
||||
center_y=570.0
|
||||
continuous=false
|
||||
@@ -6,3 +6,4 @@ modulo=3
|
||||
number_images=2
|
||||
scale_x=0.3
|
||||
scale_y=0.3
|
||||
threshold=0.6
|
||||
|
||||
220
plugins/Image_Correlator.java
Normal file
220
plugins/Image_Correlator.java
Normal file
@@ -0,0 +1,220 @@
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import ij.*;
|
||||
import ij.gui.*;
|
||||
import ij.process.*;
|
||||
import ij.text.*;
|
||||
import ij.plugin.PlugIn;
|
||||
|
||||
//This plugin correlates two 8-bit images or stacks. The resultant correlation plot is a
|
||||
//stack with the same number of slices as the stack with the fewer number.
|
||||
//Many correlation plots need to be recontrasted. Pressing Apple/Shift/C will
|
||||
//bring up the Brightness/Contrast menu.
|
||||
|
||||
public class Image_Correlator implements PlugIn {
|
||||
|
||||
private static int index1;
|
||||
private static int index2;
|
||||
private static boolean displayCounts, collate;
|
||||
private ImageStack img1, img2;
|
||||
private int smallest;
|
||||
private int z1, z2, count;
|
||||
|
||||
public void run(String arg) {
|
||||
if (showDialog())
|
||||
correlate(img1, img2);
|
||||
}
|
||||
|
||||
public boolean showDialog() {
|
||||
int[] wList = WindowManager.getIDList();
|
||||
if (wList==null) {
|
||||
IJ.noImage();
|
||||
return false;
|
||||
}
|
||||
String[] titles = new String[wList.length];
|
||||
for (int i=0; i<wList.length; i++) {
|
||||
ImagePlus imp = WindowManager.getImage(wList[i]);
|
||||
if (imp!=null)
|
||||
titles[i] = imp.getTitle();
|
||||
else
|
||||
titles[i] = "";
|
||||
}
|
||||
if (index1>=titles.length)index1 = 0;
|
||||
if (index2>=titles.length)index2 = 0;
|
||||
GenericDialog gd = new GenericDialog("Image Correlator");
|
||||
gd.addChoice("Image1: ", titles, titles[index1]);
|
||||
gd.addChoice("Image2: ", titles, titles[index2]);
|
||||
gd.addCheckbox("Display Counts: ", displayCounts);
|
||||
gd.addCheckbox("Collate Z-Data (Stacks Only):", collate);
|
||||
gd.showDialog();
|
||||
if (gd.wasCanceled())
|
||||
return false;
|
||||
index1 = gd.getNextChoiceIndex();
|
||||
index2 = gd.getNextChoiceIndex();
|
||||
displayCounts = gd.getNextBoolean();
|
||||
collate = gd.getNextBoolean();
|
||||
String title1 = titles[index1];
|
||||
String title2 = titles[index2];
|
||||
//Test to find out if both images are 8-bit grayscale.
|
||||
ImagePlus sliceimg1 = WindowManager.getImage(wList[index1]);
|
||||
ImagePlus sliceimg2 = WindowManager.getImage(wList[index2]);
|
||||
if (sliceimg1.getType()!=sliceimg1.GRAY8 || sliceimg2.getType()!=sliceimg1.GRAY8) {
|
||||
IJ.showMessage("Image Correlator", "Both stacks must be 8-bit grayscale.");
|
||||
return false;
|
||||
}
|
||||
img1 = sliceimg1.getStack();
|
||||
img2 = sliceimg2.getStack();
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object[] getCorrelation(ImagePlus im1, ImagePlus im2){
|
||||
int width = im1.getWidth();
|
||||
int height = im1.getHeight();
|
||||
float[] v1, v2;
|
||||
ip1 = im1.getProcessor();
|
||||
ip2 = im2.getProcessor();
|
||||
v1 = new float[width*height];
|
||||
v2 = new float[width*height];
|
||||
ImageProcessor plot= new FloatProcessor(256, 256);
|
||||
int index = 0;
|
||||
for (int y=0; y<height; y++) {//Loop for Y-Values
|
||||
for (int x=0; x<width; x++) {//Loop for X-Values
|
||||
z1 = (int)ip1.getPixelValue(x,y); // z-value of pixel (x,y)in stack #1 on slice s
|
||||
z2 = (int)ip2.getPixelValue(x,y); // z-value of pixel (x,y)in stack #2 on slice s
|
||||
v1[index] = z1;
|
||||
v2[index] = z2;
|
||||
z2 = 255 - z2;
|
||||
index++;
|
||||
count = (int)plot.getPixelValue(z1, z2);
|
||||
count++;
|
||||
plot.putPixelValue(z1, z2, count);
|
||||
}
|
||||
}
|
||||
plot.invertLut();
|
||||
plot.resetMinAndMax();
|
||||
pcc = calculateCorrelation(v1, v2);
|
||||
ImagePlus ret = new ImagePlus("Correlation Plot", plot);
|
||||
return new Object[]{pcc,ret};
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void correlate(ImageStack img1, ImageStack img2) {
|
||||
int size1 = img1.getSize();
|
||||
int size2 = img2.getSize();
|
||||
boolean unsigned = true;
|
||||
|
||||
//Finds out which stack has fewer slices and sets it to be the
|
||||
//number of slices in the correlation plot
|
||||
if (size1<=size2)
|
||||
smallest = size1;
|
||||
if (size2<size1)
|
||||
smallest = size2;
|
||||
int width = img1.getWidth();
|
||||
int height = img1.getHeight();
|
||||
float[] v1, v2;
|
||||
|
||||
ImageStack stackplot = new ImageStack(256, 256);
|
||||
ImageProcessor ip1, ip2, plot=null;
|
||||
double pcc=0;
|
||||
|
||||
for(int i=1; i<=smallest; i++) {
|
||||
ip1 = img1.getProcessor(i);
|
||||
ip2 = img2.getProcessor(i);
|
||||
v1 = new float[width*height];
|
||||
v2 = new float[width*height];
|
||||
if (i==1 || !collate)
|
||||
plot = new FloatProcessor(256, 256);
|
||||
int index = 0;
|
||||
for (int y=0; y<height; y++) {//Loop for Y-Values
|
||||
for (int x=0; x<width; x++) {//Loop for X-Values
|
||||
z1 = (int)ip1.getPixelValue(x,y); // z-value of pixel (x,y)in stack #1 on slice s
|
||||
z2 = (int)ip2.getPixelValue(x,y); // z-value of pixel (x,y)in stack #2 on slice s
|
||||
v1[index] = z1;
|
||||
v2[index] = z2;
|
||||
z2 = 255 - z2;
|
||||
index++;
|
||||
count = (int)plot.getPixelValue(z1, z2);
|
||||
count++;
|
||||
plot.putPixelValue(z1, z2, count);
|
||||
}
|
||||
}
|
||||
plot.invertLut();
|
||||
plot.resetMinAndMax();
|
||||
pcc = calculateCorrelation(v1, v2);
|
||||
if (i==1 || !collate)
|
||||
stackplot.addSlice(IJ.d2s(pcc,6), plot);
|
||||
IJ.showProgress((double)i/smallest);
|
||||
IJ.showStatus("Correlating slice: "+ i +"/" + smallest);
|
||||
}
|
||||
IJ.showProgress(1.0);
|
||||
ImagePlus imp2 = new ImagePlus("Correlation Plot", stackplot);
|
||||
if (smallest==1)
|
||||
imp2.setTitle("Plot ("+IJ.d2s(pcc,6)+")");
|
||||
imp2.show();
|
||||
IJ.run("Enhance Contrast", "saturated=0.5");
|
||||
if (displayCounts)
|
||||
displayCounts(stackplot);
|
||||
}
|
||||
|
||||
// http://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient
|
||||
double calculateCorrelation(float[] x, float[] y) {
|
||||
double sumx = 0;
|
||||
double sumy = 0;
|
||||
int n = x.length;
|
||||
for (int i=0; i<n; i++) {
|
||||
sumx += x[i];
|
||||
sumy += y[i];
|
||||
}
|
||||
double xmean = sumx/n;
|
||||
double ymean = sumy/n;
|
||||
double sum = 0;
|
||||
for (int i=0; i<n; i++)
|
||||
sum += (x[i]-xmean)*(y[i]-ymean);
|
||||
double sumx2 = 0;
|
||||
for (int i=0; i<n; i++)
|
||||
sumx2 += sqr(x[i]-xmean);
|
||||
double sumy2 = 0;
|
||||
for (int i=0; i<n; i++)
|
||||
sumy2 += sqr(y[i]-ymean);
|
||||
return sum/(Math.sqrt(sumx2)*Math.sqrt(sumy2));
|
||||
}
|
||||
|
||||
double sqr(double x) {
|
||||
return x*x;
|
||||
}
|
||||
|
||||
boolean isStack(ImageStack i1, ImageStack i2){
|
||||
if ((i1.getSize()>1) && (i2.getSize()>1))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void displayCounts(ImageStack plot) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int count;
|
||||
int slices = plot.getSize();
|
||||
if (slices==1) {
|
||||
ImageProcessor ip = plot.getProcessor(1);
|
||||
for (int x=0; x<256; x++)
|
||||
for (int y=255; y>=0; y--) {
|
||||
count = (int)ip.getPixelValue(x,y);
|
||||
if (count>0)
|
||||
sb.append(x+"\t"+(255-y)+"\t"+count+"\n");
|
||||
}
|
||||
new TextWindow("Non-zero Counts" , "X\tY\tCount", sb.toString(), 300, 400);
|
||||
} else {
|
||||
for (int slice=1; slice<=slices; slice++) {
|
||||
ImageProcessor ip = plot.getProcessor(slice);
|
||||
for (int x=0; x<256; x++)
|
||||
for (int y=255; y>=0; y--) {
|
||||
count = (int)ip.getPixelValue(x,y);
|
||||
if (count>0)
|
||||
sb.append(x+"\t"+(255-y)+"\t"+(slice-1)+"\t"+count+"\n");
|
||||
}
|
||||
}
|
||||
new TextWindow("Non-zero Counts" , "X\tY\tZ\tCount", sb.toString(), 300, 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
run("imgproc/NewCoverDetection")
|
||||
run("imgproc/NewCoverCorrelation")
|
||||
|
||||
|
||||
class CoverDetectionConfig(RegisterConfig):
|
||||
@@ -10,7 +11,16 @@ 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
|
||||
|
||||
class CoverCorrelation(ReadonlyAsyncRegisterBase):
|
||||
def __init__(self, name):
|
||||
ReadonlyAsyncRegisterBase.__init__(self, name)
|
||||
def set(self, value):
|
||||
self.onReadout(value)
|
||||
|
||||
|
||||
class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
|
||||
|
||||
def __init__(self, name, image):
|
||||
@@ -32,13 +42,21 @@ class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
|
||||
self.error_overlay=None
|
||||
self.img_counter, self.proc_counter = 0, 0
|
||||
self.offset_px = self.offset_um = None
|
||||
self.correlation = CoverCorrelation("cover_correlation")
|
||||
self.correlation_error = False
|
||||
|
||||
def doInitialize(self):
|
||||
self.enable()
|
||||
self.clear()
|
||||
try:
|
||||
self.enable()
|
||||
self.clear()
|
||||
#self.grab_ref_image()
|
||||
except:
|
||||
traceback.print_exc()
|
||||
raise
|
||||
|
||||
def doClose(self):
|
||||
self.disable()
|
||||
def doClose(self):
|
||||
self.disable()
|
||||
self.correlation.close()
|
||||
|
||||
def set_renderer(self, renderer):
|
||||
self.clear()
|
||||
@@ -60,7 +78,8 @@ class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
|
||||
|
||||
def clear(self):
|
||||
self.set_marker(None)
|
||||
self.set_error_overlay(None)
|
||||
self.set_error_overlay(None)
|
||||
self.set_correlation(None)
|
||||
|
||||
def append(self, image):
|
||||
self.img_counter += 1
|
||||
@@ -83,7 +102,20 @@ class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
|
||||
x,y = -1, -1
|
||||
self.processing_time = time.time()-start
|
||||
self.proc_counter += 1
|
||||
|
||||
try:
|
||||
corr = get_correlation(ip.getBufferedImage())
|
||||
self.correlation.set(corr)
|
||||
self.set_correlation(corr)
|
||||
except Exception as e:
|
||||
#traceback.print_exc()
|
||||
if self.error is None:
|
||||
self.error = e
|
||||
|
||||
self.set(x, y, self.processing_time * 1000, self.error)
|
||||
|
||||
#traceback.print_exc()
|
||||
|
||||
if not self.config.continuous:
|
||||
self.images=[]
|
||||
|
||||
@@ -96,7 +128,7 @@ class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
|
||||
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')
|
||||
value = to_array([x, y, opx, opy, omx, omy, tm], 'i')
|
||||
self.onReadout(value)
|
||||
if self.renderer is not None:
|
||||
if error is None:
|
||||
@@ -122,8 +154,35 @@ class CoverDetection(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
|
||||
self.error_overlay = error_overlay
|
||||
else:
|
||||
self.error_overlay = None
|
||||
|
||||
|
||||
def grab_ref_image(self):
|
||||
if self.config.number_images>1:
|
||||
images = []
|
||||
for i in range(self.config.number_images):
|
||||
ip = load_image(ImagingUtils.grayscale(self.image.output, None))
|
||||
images.append(ip)
|
||||
self.image.waitNext(-1)
|
||||
ip = integrate(images)
|
||||
img = ip.getBufferedImage()
|
||||
else:
|
||||
img = self.image.output
|
||||
save_ref_img(img)
|
||||
|
||||
def set_correlation(self, corr):
|
||||
self.corr = corr
|
||||
error = corr is not None and corr < self.config.threshold
|
||||
if error != self.correlation_error:
|
||||
self.correlation_error = error
|
||||
if error:
|
||||
print ("Image anomally detected")
|
||||
else:
|
||||
print ("Image ok")
|
||||
if error:
|
||||
raise Exception ("Image anomally detected")
|
||||
|
||||
|
||||
|
||||
add_device(CoverDetection("cover_detection", image), force = True)
|
||||
add_device(cover_detection.correlation, force = True)
|
||||
renderer=show_panel(image)
|
||||
cover_detection.set_renderer(renderer)
|
||||
|
||||
@@ -55,16 +55,15 @@ class VmbCamera (CameraBase):
|
||||
fork(init_img)
|
||||
self.setState(State.Disabled)
|
||||
|
||||
def add_img_device(self):
|
||||
def add_dev_task():
|
||||
def add_initialized_callback(self, callback):
|
||||
def wait_init():
|
||||
try:
|
||||
self.waitStateNot(State.Disabled, -1)
|
||||
if (self.stream.state == State.Busy) and (get_context().state.isActive()):
|
||||
add_device(self.image, True)
|
||||
log("Added VmbCamera image device")
|
||||
callback()
|
||||
except Exception as e:
|
||||
log(str(e))
|
||||
fork(add_dev_task)
|
||||
fork(wait_init)
|
||||
|
||||
def getInfo(self):
|
||||
try:
|
||||
@@ -282,6 +281,10 @@ fork(start_camera_server)
|
||||
c = VmbCamera("cam", image_name="image")
|
||||
add_device(c, True)
|
||||
add_device(c.stream, True)
|
||||
c.add_img_device()
|
||||
|
||||
def initialized_callback():
|
||||
add_device(c.image, True)
|
||||
add_device(c.image.contrast, force = True)
|
||||
log("Added VmbCamera image device")
|
||||
run( "devices/CoverDetection")
|
||||
c.add_initialized_callback(initialized_callback)
|
||||
|
||||
|
||||
99
script/imgproc/NewCoverCorrelation.py
Normal file
99
script/imgproc/NewCoverCorrelation.py
Normal file
@@ -0,0 +1,99 @@
|
||||
import ch.psi.pshell.imaging.ImageBuffer as ImageBuffer
|
||||
|
||||
offset = 0
|
||||
add_mark = False
|
||||
#offset = 50
|
||||
#add_mark = True
|
||||
|
||||
|
||||
Image_Correlator = get_context().getClassByName("Image_Correlator")
|
||||
correlator = Image_Correlator()
|
||||
|
||||
def get_min(ip1):
|
||||
return ip1.getProcessor().getStatistics().min
|
||||
|
||||
def mean_abs_error(ip1, ip2):
|
||||
sum = 0.0
|
||||
for y in range(ip1.getHeight()):
|
||||
for x in range(ip1.getWidth()):
|
||||
p1 = ip1.getPixel(x, y)
|
||||
p2 = ip2.getPixel(x, y)
|
||||
sum += abs(p1 - p2)
|
||||
return sum / (ip1.height * ip1.width )
|
||||
|
||||
def rms_error(ip1, ip2):
|
||||
sum = 0.0
|
||||
for y in range(ip1.getHeight()):
|
||||
for x in range(ip1.getWidth()):
|
||||
p1 = ip1.getPixel(x, y)
|
||||
p2 = ip2.getPixel(x, y)
|
||||
sum += math.pow((p1 - p2),2)
|
||||
return sum / (ip1.height * ip1.width )
|
||||
|
||||
|
||||
|
||||
def get_roi_img(img, img_size=1024, radius=512, 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
|
||||
roi = ImagingUtils.copy(img, None, Rectangle(x,y,w,h))
|
||||
ip = load_image(roi, title="Img")
|
||||
p = ip.getProcessor()
|
||||
mask = p.createProcessor(roi.getWidth(), roi.getHeight())
|
||||
mask.setColor(255)
|
||||
cx, cy = img_size/2 - offset_x, img_size/2 - offset_y
|
||||
mask.fillOval(int(cx - radius), int(cy - radius), int(2 * radius), int(2 * radius)) # Draw the circular ROI
|
||||
mask.autoThreshold() # Ensures the mask is binary (if needed)
|
||||
p.copyBits(mask, 0, 0, Blitter.AND) # Apply the mask using a bitwise AND
|
||||
#gaussian_blur(ip)
|
||||
p.blurGaussian(1.0)
|
||||
return ip.getBufferedImage()
|
||||
|
||||
def get_edge_img(ib):
|
||||
ed = ImagingUtils.edgeDetect(ib)
|
||||
ret = load_image(ed, title="Refe")
|
||||
#auto_threshold(ret, dark_background=True)
|
||||
#binary_dilate(ret, iterations=1, count=1)
|
||||
return ret
|
||||
|
||||
def save_ref_img(img):
|
||||
path = os.path.abspath(expand_path("{images}/ip_ref_fe.png"))
|
||||
roi=get_roi_img(img, offset_x=0, offset_y=0)
|
||||
ImageBuffer.saveImage(roi, path, "png")
|
||||
|
||||
#ip_ref = load_image(roi, title="ip_ref")
|
||||
#save_image(ip_ref, path ,"png")
|
||||
#$ImagingUtils.
|
||||
#ip_ref_e =get_edge_img(roi)
|
||||
#save_image(ip_ref_e, path+"ip_ref_e.png" ,"png")
|
||||
##ip_ref_f = image_fft(ip_ref)
|
||||
#ip_ref_fe = image_fft(ip_ref_e)
|
||||
#save_image(ip_ref_fe, path+"ip_ref_fe.png" ,"png")
|
||||
|
||||
|
||||
def put_mark(ib):
|
||||
for x in range(450, 470):
|
||||
for y in range(450, 470):
|
||||
ib.setRGB(x,y, 0)
|
||||
|
||||
def get_correlation(img):
|
||||
global ip_ref_fe
|
||||
if "ip_ref_fe" not in globals() or ip_ref_fe is None:
|
||||
path = os.path.abspath(expand_path("{images}/ip_ref_fe.png"))
|
||||
roi = ImagingUtils.newImage(path)
|
||||
#ip_ref_fe=open_imagroie(path+"ip_ref_fe.png" ,"png")
|
||||
#ip_ref = load_image(roi, title="ip_ref")
|
||||
ip_ref_e =get_edge_img(roi)
|
||||
ip_ref_fe = image_fft(ip_ref_e)
|
||||
print "Opend reference image"
|
||||
|
||||
roi =get_roi_img(img, offset_x=-offset, offset_y=-offset)
|
||||
if add_mark:
|
||||
put_mark(roi)
|
||||
#ip_cur = load_image(roi, title="Ref")
|
||||
ip_cur_e =get_edge_img(roi)
|
||||
#ip_cur_f = image_fft(ip_cur)
|
||||
ip_cur_fe = image_fft(ip_cur_e)
|
||||
return correlator.getCorrelation(ip_ref_fe, ip_cur_fe)[0]
|
||||
|
||||
|
||||
@@ -110,9 +110,12 @@ set_setting(BEAMLINE_STATUS_ENABLED_PREFERENCE, is_beamline_status_enabled())
|
||||
###################################################################################################
|
||||
# Scripted devices and pseudo-devices
|
||||
###################################################################################################
|
||||
|
||||
|
||||
|
||||
|
||||
scripted_devices = ["devices/RobotSC", "devices/Wago", "devices/BarcodeReader", "devices/LaserDistance",
|
||||
"devices/LedCtrl", "devices/SmartMagnet", "devices/Gonio", "devices/VmbCamera" #"devices/HexiPosi"]"
|
||||
"devices/LedCtrl", "devices/SmartMagnet", "devices/Gonio", #"devices/HexiPosi"]"
|
||||
"devices/VmbCamera",
|
||||
]
|
||||
|
||||
for script in scripted_devices:
|
||||
@@ -122,12 +125,6 @@ for script in scripted_devices:
|
||||
run(script)
|
||||
except:
|
||||
print >> sys.stderr, traceback.format_exc()
|
||||
|
||||
|
||||
|
||||
#if is_imaging_enabled():
|
||||
if get_device("img") is not None:
|
||||
add_device(img.getContrast(), force = True)
|
||||
|
||||
|
||||
|
||||
|
||||
129
script/test/TestCorrelation.py
Normal file
129
script/test/TestCorrelation.py
Normal file
@@ -0,0 +1,129 @@
|
||||
show = False
|
||||
img_size = 1024
|
||||
RADIUS = 512
|
||||
FRAMES = 1
|
||||
offset = 0
|
||||
add_mark = False
|
||||
#offset = 50
|
||||
#add_mark = True
|
||||
|
||||
|
||||
Image_Correlator = get_context().getClassByName("Image_Correlator")
|
||||
correlator = Image_Correlator()
|
||||
|
||||
|
||||
|
||||
def get_roi_img(radius, offset_x=0, offset_y=0, frames=1):
|
||||
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
|
||||
if frames>1:
|
||||
ip = integrate_frames(samples = frames)
|
||||
roi = ImagingUtils.copy(ip.getBufferedImage(), None, Rectangle(x,y,w,h))
|
||||
else:
|
||||
roi = ImagingUtils.copy(image.output, None, Rectangle(x,y,w,h))
|
||||
ip = load_image(roi, title="Img")
|
||||
p = ip.getProcessor()
|
||||
mask = p.createProcessor(roi.getWidth(), roi.getHeight())
|
||||
mask.setColor(255)
|
||||
cx, cy = img_size/2 - offset_x, img_size/2 - offset_y
|
||||
mask.fillOval(int(cx - radius), int(cy - radius), int(2 * radius), int(2 * radius)) # Draw the circular ROI
|
||||
mask.autoThreshold() # Ensures the mask is binary (if needed)
|
||||
p.copyBits(mask, 0, 0, Blitter.AND) # Apply the mask using a bitwise AND
|
||||
#gaussian_blur(ip)
|
||||
p.blurGaussian(1.0)
|
||||
return ip.getBufferedImage()
|
||||
|
||||
def get_edge_img(ib):
|
||||
ed = ImagingUtils.edgeDetect(ib)
|
||||
ret = load_image(ed, title="Refe")
|
||||
#auto_threshold(ret, dark_background=True)
|
||||
#binary_dilate(ret, iterations=1, count=1)
|
||||
return ret
|
||||
|
||||
def put_mark(ib):
|
||||
for x in range(450, 470):
|
||||
for y in range(450, 470):
|
||||
ib.setRGB(x,y, 0)
|
||||
|
||||
|
||||
|
||||
|
||||
def load_ref_img(reload = False, frames=FRAMES):
|
||||
global ip_ref, ip_ref_e, ip_ref_f, ip_ref_fe
|
||||
if reload or "ip_ref_fe" not in globals():
|
||||
print "Loading cover reference image"
|
||||
roi =get_roi_img(RADIUS, 0, 0, frames)
|
||||
ip_ref = load_image(roi, title="Ref")
|
||||
ip_ref_e =get_edge_img(roi)
|
||||
ip_ref_f = image_fft(ip_ref)
|
||||
ip_ref_fe = image_fft(ip_ref_e)
|
||||
|
||||
load_ref_img()
|
||||
|
||||
def load_cur_img(frames=FRAMES):
|
||||
global ip_cur, ip_cur_e, ip_cur_f, ip_cur_fe
|
||||
roi =get_roi_img(RADIUS, -offset, -offset, frames)
|
||||
if add_mark:
|
||||
put_mark(roi)
|
||||
ip_cur = load_image(roi, title="Ref")
|
||||
ip_cur_e =get_edge_img(roi)
|
||||
ip_cur_f = image_fft(ip_cur)
|
||||
ip_cur_fe = image_fft(ip_cur_e)
|
||||
|
||||
load_cur_img()
|
||||
|
||||
|
||||
#show_panel(ip1e.getBufferedImage())
|
||||
#show_panel(ip2e.getBufferedImage())
|
||||
|
||||
coef_img, _ = correlator.getCorrelation(ip_ref, ip_cur)
|
||||
coef_ed, _ = correlator.getCorrelation(ip_ref_e, ip_cur_e)
|
||||
coef_fft, _ = correlator.getCorrelation(ip_ref_f, ip_cur_f)
|
||||
coef_ffte, _ = correlator.getCorrelation(ip_ref_fe, ip_cur_fe)
|
||||
|
||||
#show_panel(sub1)
|
||||
|
||||
#sub = ImagingUtils.sub(BufferedImage, BufferedImage, boolean)
|
||||
|
||||
#sub = load_image(sub, title="sub")
|
||||
#sube = load_image(sube, title="sube")
|
||||
|
||||
if show:
|
||||
st=create_stack([ip_ref, ip_cur, ip_ref_e, ip_cur_e, ip_ref_f, ip_cur_f, ip_ref_fe, ip_cur_fe])
|
||||
st.show()
|
||||
|
||||
|
||||
def get_min(ip1):
|
||||
return ip1.getProcessor().getStatistics().min
|
||||
|
||||
def mean_abs_error(ip1, ip2):
|
||||
sum = 0.0
|
||||
for y in range(ip1.getHeight()):
|
||||
for x in range(ip1.getWidth()):
|
||||
p1 = ip1.getPixel(x, y)
|
||||
p2 = ip2.getPixel(x, y)
|
||||
sum += abs(p1 - p2)
|
||||
return sum / (ip1.height * ip1.width )
|
||||
|
||||
def rms_error(ip1, ip2):
|
||||
sum = 0.0
|
||||
for y in range(ip1.getHeight()):
|
||||
for x in range(ip1.getWidth()):
|
||||
p1 = ip1.getPixel(x, y)
|
||||
p2 = ip2.getPixel(x, y)
|
||||
sum += math.pow((p1 - p2),2)
|
||||
return sum / (ip1.height * ip1.width )
|
||||
|
||||
|
||||
mean_err, mean_erre = mean_abs_error(ip_ref_f.getProcessor(), ip_cur_f.getProcessor()), mean_abs_error(ip_ref_fe.getProcessor(), ip_cur_fe.getProcessor())
|
||||
rms_err, rms_erre = rms_error(ip_ref_f.getProcessor(), ip_cur_f.getProcessor()), rms_error(ip_ref_fe.getProcessor(), ip_cur_fe.getProcessor())
|
||||
|
||||
if show:
|
||||
#print offset, coef_img, coef_ed, coef_fft, coef_ffte
|
||||
print coef_fft, coef_ffte
|
||||
print mean_err, mean_erre
|
||||
print rms_err, rms_erre
|
||||
|
||||
|
||||
|
||||
40
script/test/TestCorrelationDevices.py
Normal file
40
script/test/TestCorrelationDevices.py
Normal file
@@ -0,0 +1,40 @@
|
||||
class CoefFFT(ReadonlyRegisterBase):
|
||||
def doRead(self):
|
||||
return coef_fft
|
||||
add_device(CoefFFT(), True)
|
||||
CoefFFT.polling=1000
|
||||
|
||||
class CoefFFTE(ReadonlyRegisterBase):
|
||||
def doRead(self):
|
||||
return coef_ffte
|
||||
add_device(CoefFFTE(), True)
|
||||
CoefFFTE.polling=1000
|
||||
|
||||
class MeanErr(ReadonlyRegisterBase):
|
||||
def doRead(self):
|
||||
return mean_err
|
||||
add_device(MeanErr(), True)
|
||||
MeanErr.polling=1000
|
||||
|
||||
class MeanErrE(ReadonlyRegisterBase):
|
||||
def doRead(self):
|
||||
return mean_erre
|
||||
add_device(MeanErrE(), True)
|
||||
MeanErrE.polling=1000
|
||||
|
||||
class RmsErr(ReadonlyRegisterBase):
|
||||
def doRead(self):
|
||||
return rms_err
|
||||
add_device(RmsErr(), True)
|
||||
RmsErr.polling=1000
|
||||
|
||||
class RmsErrE(ReadonlyRegisterBase):
|
||||
def doRead(self):
|
||||
return rms_erre
|
||||
add_device(RmsErrE(), True)
|
||||
RmsErrE.polling=1000
|
||||
|
||||
|
||||
#print coef_fft, coef_ffte
|
||||
#print mean_err, mean_erre
|
||||
#print rms_err, rms_erre
|
||||
Reference in New Issue
Block a user