Commit 55b09ee8 authored by Manuel Gunkel's avatar Manuel Gunkel
Browse files

updated template matching utility

parent 1cf07545
......@@ -11,6 +11,7 @@ import automic.utils.imagefiles.ImageOpenerWithBioformats;
//ImageJ imports:
import ij.IJ;
import ij.ImagePlus;
import ij.gui.Roi;
import ij.gui.RotatedRectRoi;
import ij.plugin.filter.MaximumFinder;
import ij.plugin.frame.RoiManager;
......@@ -50,18 +51,12 @@ public class MatchTemplate {
public ArrayList<Integer> positions_x = new ArrayList<>();
public ArrayList<Integer> positions_y = new ArrayList<>();
public ArrayList<Double> intensity_match = new ArrayList<>();
public ArrayList<Boolean> is_fipped_hor = new ArrayList<>();
public ArrayList<Boolean> is_flipped_hor = new ArrayList<>();
public ArrayList<Boolean> is_flipped_ver = new ArrayList<>();
public ArrayList<Double> angle_rot = new ArrayList<>();
public ArrayList<Boolean> isvalidxy = new ArrayList<>();
public ArrayList<Boolean> isvalidint = new ArrayList<>();
public ArrayList<String> ROIs = new ArrayList<>();
private RoiManager rm = new RoiManager();
/*** Todo:
*save ROIs as ArrayList
*/
/***
* Implementation of the OpenCV template matching routine. Images are converted, 'match' should be larger than 'template'.
......@@ -104,6 +99,7 @@ public class MatchTemplate {
return result;
}
/**
* Implements the ImageJ Find Maxima command on the resulting correlation image in order to get the positions of the template
* @param TMimage Correlation image resulting from the matchTemplate call.
......@@ -118,6 +114,7 @@ public class MatchTemplate {
return maxima;
}
/**
* Shift the positions of the identified coordinates back to the 'match' image. For this, the dimensions of the 'template'
* image need to be known, since the correlation image is reduced by this size.
......@@ -133,10 +130,10 @@ public class MatchTemplate {
int dy = (int) Math.ceil(th/2);
pg.translate(dx,dy);
return pg;
return pg;
}
/** Rotates the template by the given angles and performs a template match each time. Is repeated with flipped images if the flags are set.
* @param template_ The 'template' image.
* @param match_ The 'match' image.
......@@ -167,9 +164,9 @@ public class MatchTemplate {
fh.flipHorizontal();
templateMatchRotations(template_fh, match_, flip_hor, false, alpha_start, alpha_step, alpha_stop);
}
// match_.show();
}
/** Rotates the template by the given angles and performs a template match each time.
* @param template_ The 'template' image.
* @param match_ The 'match' image.
......@@ -207,20 +204,11 @@ public class MatchTemplate {
xpos = xpos+dx_pos;
ypos = ypos +dy_pos;
//get coordinates for the rotated ROI and set the rotated ROI:
double alpharoi = aha*Math.PI/180;
int a = template_.getWidth()/2;
int b = template_.getHeight();
double dx = Math.cos(alpharoi)*a;
double dy = -Math.sin(alpharoi)*a;
RotatedRectRoi nuroirot = new RotatedRectRoi(xpos-dx, ypos+dy, xpos+dx, ypos-dy, b);
//add all parameters to the respective ArrayList:
this.rm.add(match_, nuroirot, i);
//add all parameters to the respective ArrayList:
this.positions_x.add(xpos);
this.positions_y.add(ypos);
this.intensity_match.add(intensity);
this.is_fipped_hor.add(flip_hor);
this.is_flipped_hor.add(flip_hor);
this.is_flipped_ver.add(flip_ver);
this.angle_rot.add(aha);
}
......@@ -247,20 +235,17 @@ public class MatchTemplate {
*/
public void filterResults(double radius, double corrthreshold) throws Exception {
//clear any previous filters:
this.isvalidint.clear();
this.isvalidxy.clear();
//temporary Array lists for the filtered results:
//initialize temporary Array lists for the filtered results:
ArrayList<Integer> positions_x_tmp = new ArrayList<>();
ArrayList<Integer> positions_y_tmp = new ArrayList<>();
ArrayList<Double> intensity_match_tmp = new ArrayList<>();
ArrayList<Boolean> is_fipped_hor_tmp = new ArrayList<>();
ArrayList<Boolean> is_flipped_hor_tmp = new ArrayList<>();
ArrayList<Boolean> is_flipped_ver_tmp = new ArrayList<>();
ArrayList<Double> angle_rot_tmp = new ArrayList<>();
// names of the ROIs to be kept
ArrayList<String> ROIs_tmp = new ArrayList<>();
// integer index of the ROIs to be kept
ArrayList<Integer> ROI_ind = new ArrayList<>();
//initialize variables;
double r = 0;
......@@ -270,7 +255,6 @@ public class MatchTemplate {
// Iterate over all coordinates
for (int i = 0; i<positions_x.size(); i++) {
this.ROIs.add(this.rm.getName(i));
// Check if the correlation value is above the threshold:
if (this.intensity_match.get(i) >= corrthreshold) {
......@@ -298,12 +282,10 @@ public class MatchTemplate {
positions_x_tmp.add(positions_x.get(i));
positions_y_tmp.add(positions_y.get(i));
intensity_match_tmp.add(intensity_match.get(i));
is_fipped_hor_tmp.add(is_fipped_hor.get(i));
is_flipped_hor_tmp.add(is_flipped_hor.get(i));
is_flipped_ver_tmp.add(is_flipped_ver.get(i));
angle_rot_tmp.add(angle_rot.get(i));
ROIs_tmp.add(ROIs.get(i));
}
else ROI_ind.add(i);
}
......@@ -311,14 +293,40 @@ public class MatchTemplate {
positions_x = positions_x_tmp;
positions_y = positions_y_tmp;
intensity_match = intensity_match_tmp;
is_fipped_hor = is_fipped_hor_tmp;
is_flipped_hor = is_flipped_hor_tmp;
is_flipped_ver = is_flipped_ver_tmp;
angle_rot = angle_rot_tmp;
ROIs = ROIs_tmp;
int[] ROI_selected = MatchTemplate.convertIntegers(ROI_ind);
rm.setSelectedIndexes(ROI_selected);
rm.runCommand("Delete");
angle_rot = angle_rot_tmp;
}
public int getBestFitIndex() {
double max_val = 0;
int index = 0;
for (int i = 0; i<positions_x.size(); i++) {
if (intensity_match.get(i) > max_val) {
max_val = intensity_match.get(i);
index = i;
};
}
return index;
}
public Roi[] generateRois(ImagePlus match_, ImagePlus template_) throws Exception {
//get coordinates for the rotated ROI and set the rotated ROI:
Roi[] rois =new Roi[this.positions_x.size()];
for (int i=0; i < this.positions_x.size() ; i++) {
double alpharoi = this.angle_rot.get(i)*Math.PI/180;
int xpos = this.positions_x.get(i);
int ypos = this.positions_y.get(i);
int a = template_.getWidth()/2;
int b = template_.getHeight();
double dx = Math.cos(alpharoi)*a;
double dy = Math.sin(alpharoi)*a;
RotatedRectRoi nuroirot = new RotatedRectRoi(xpos-dx, ypos-dy, xpos+dx, ypos+dy, b);
rois[i] = nuroirot;
}
return rois;
}
/***************************************************
......@@ -326,14 +334,14 @@ public class MatchTemplate {
* converters, setters and getters are defined here.
**************************************************/
private static int[] convertIntegers(ArrayList<Integer> integers) throws Exception {
int[] ret = new int[integers.size()];
for (int i=0; i < ret.length; i++)
{
ret[i] = integers.get(i).intValue();
}
return ret;
}
// private static int[] convertIntegers(ArrayList<Integer> integers) throws Exception {
// int[] ret = new int[integers.size()];
// for (int i=0; i < ret.length; i++)
// {
// ret[i] = integers.get(i).intValue();
// }
// return ret;
// }
// // conversion to 8bit should not be needed. otherwise reactivate:
// private static ImagePlus convertTo8bit(ImagePlus _img) {
......@@ -390,7 +398,7 @@ public class MatchTemplate {
public static void main(String[] args)throws Exception{
// match image: right filetype (8bit)
final String templatePath="C:\\Users\\Manu\\Desktop\\ArgoLight\\Templates\\Argolight_Letters_8bit.tif";
final String templatePath="C:\\Users\\Manu\\Desktop\\ArgoLight\\Templates\\Argolight_Letters_16bit.tif";
//final String templatePath="C:\\Users\\Manu\\Desktop\\ArgoLight\\Templates\\FoR.tif";
// template image: wrong filetype (16 bit), needs conversion
......@@ -410,9 +418,15 @@ public class MatchTemplate {
mt.setStrict(true);
mt.multiTemplateMatch( template_example, match_example, true, true, 0,20,40);
mt.filterResults(50, 0.2);
Roi[] rois = mt.generateRois(match_example, template_example);
template_example.show();
match_example.show();
RoiManager rm = new RoiManager();
for (int i =0; i < rois.length; i++) {
rm.addRoi(rois[i]);
}
IJ.log("---Template matching end---");
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment