Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Aliaksandr Halavatyi
AutoMicTools
Commits
1cf07545
Commit
1cf07545
authored
Feb 18, 2021
by
Manuel Gunkel
Browse files
added template matching utility
parent
8b826a93
Changes
2
Hide whitespace changes
Inline
Side-by-side
pom.xml
View file @
1cf07545
...
...
@@ -4,14 +4,8 @@
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<!--
<parent>
<groupId>net.imagej</groupId>
<artifactId>pom-imagej</artifactId>
<version>5.0</version>
<relativePath />
</parent>
-->
<!-- <parent> <groupId>net.imagej</groupId> <artifactId>pom-imagej</artifactId>
<version>5.0</version> <relativePath /> </parent> -->
<groupId>
embl.almf
</groupId>
<artifactId>
AutoMicTools_
</artifactId>
<version>
1.1.18-SNAPSHOT
</version>
...
...
@@ -29,14 +23,8 @@
<distribution>
repo
</distribution>
</license>
</licenses>
<!--
<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>12.0.0</version>
<relativePath />
</parent>
-->
<!-- <parent> <groupId>org.scijava</groupId> <artifactId>pom-scijava</artifactId>
<version>12.0.0</version> <relativePath /> </parent> -->
<dependencies>
<dependency>
...
...
@@ -83,7 +71,7 @@
<groupId>
com.github.ssgpers
</groupId>
<artifactId>
CommMicroscope
</artifactId>
</dependency>
<dependency>
<groupId>
de.embl.cba
</groupId>
<artifactId>
java-utils-embl
</artifactId>
...
...
@@ -125,14 +113,20 @@
<artifactId>
xmlrpc-client
</artifactId>
</dependency>
<dependency>
<groupId>
sc.fiji
</groupId>
<groupId>
sc.fiji
</groupId>
<artifactId>
TransformJ_
</artifactId>
</dependency>
<dependency>
<groupId>
org.ilastik
</groupId>
<artifactId>
ilastik4ij
</artifactId>
<artifactId>
ilastik4ij
</artifactId>
</dependency>
<!-- OPEN-CV dependency for template matching: -->
<dependency>
<groupId>
io.github.joheras
</groupId>
<artifactId>
IJ-OpenCV
</artifactId>
<version>
1.2.1
</version>
</dependency>
</dependencies>
<developers>
...
...
@@ -155,7 +149,7 @@
<timezone>
+1
</timezone>
</developer>
</developers>
<repositories>
<!-- for Tischi dependencies -->
<repository>
...
...
@@ -164,28 +158,28 @@
<url>
https://embl-cba.bintray.com/snapshots
</url>
</repository>
<repository>
<id>
imagej.public
</id>
<url>
http://maven.imagej.net/content/groups/public
</url>
</repository>
<repository>
<id>
jitpack.io
</id>
<url>
https://jitpack.io
</url>
<id>
imagej.public
</id>
<url>
http://maven.imagej.net/content/groups/public
</url>
</repository>
<repository>
<id>
jitpack.io
</id>
<url>
https://jitpack.io
</url>
</repository>
<repository>
<repository>
<id>
imagej.releases
</id>
<url>
http://maven.imagej.net/content/repositories/releases
</url>
</repository>
<repository>
<repository>
<id>
imagej.snapshots
</id>
<url>
http://maven.imagej.net/content/repositories/snapshots
</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
...
...
@@ -193,7 +187,7 @@
<artifactId>
ij
</artifactId>
<version>
1.52s
</version>
</dependency>
<dependency>
<groupId>
commons-io
</groupId>
<artifactId>
commons-io
</artifactId>
...
...
@@ -306,14 +300,14 @@
<version>
3.1.3
</version>
</dependency>
<dependency>
<groupId>
sc.fiji
</groupId>
<groupId>
sc.fiji
</groupId>
<artifactId>
TransformJ_
</artifactId>
<version>
4.0.0
</version>
</dependency>
<dependency>
<groupId>
org.ilastik
</groupId>
<artifactId>
ilastik4ij
</artifactId>
<version>
1.7.2
</version>
<groupId>
org.ilastik
</groupId>
<artifactId>
ilastik4ij
</artifactId>
<version>
1.7.2
</version>
</dependency>
<dependency>
...
...
@@ -356,55 +350,28 @@
<configuration>
<mainClass>
console.ConsoleApplication
</mainClass>
</configuration>
</plugin>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/automic-dependencies</outputDirectory>
<outputDirectory>C:\automic-dependencies</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
-->
<!--
</plugin>
<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId>
<executions> <execution> <id>copy-dependencies</id> <phase>prepare-package</phase>
<goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/automic-dependencies</outputDirectory>
<outputDirectory>C:\automic-dependencies</outputDirectory> <overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer>
</configuration> </execution> </executions> </plugin> -->
<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId>
<configuration> <archive> <manifest> <mainClass>automic.postaq.protocols.ConsoleApp</mainClass>
<addClasspath>true</addClasspath> <classpathPrefix>automic-dependencies/</classpathPrefix>
</manifest> </archive> </configuration> </plugin> -->
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>maven-jar-plugin</artifactId>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>
3.5.1
</version>
<configuration>
<archive>
<manifest>
<mainClass>automic.postaq.protocols.ConsoleApp</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>automic-dependencies/</classpathPrefix>
</manifest>
</archive>
<source>
1.8
</source>
<target>
1.8
</target>
</configuration>
</plugin>
-->
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-compiler-plugin
</artifactId>
<version>
3.5.1
</version>
<configuration>
<source>
1.8
</source>
<target>
1.8
</target>
</configuration>
</plugin>
</plugins>
</build>
...
...
src/main/java/automic/utils/matchTemplate/MatchTemplate.java
0 → 100644
View file @
1cf07545
package
automic.utils.matchTemplate
;
//Java imports:
import
java.awt.Polygon
;
import
java.io.File
;
import
java.util.ArrayList
;
//AutoMic Tools imports:
import
automic.utils.imagefiles.ImageOpenerWithBioformats
;
//ImageJ imports:
import
ij.IJ
;
import
ij.ImagePlus
;
import
ij.gui.RotatedRectRoi
;
import
ij.plugin.filter.MaximumFinder
;
import
ij.plugin.frame.RoiManager
;
import
ij.process.ImageConverter
;
import
ij.process.ImageProcessor
;
//OpenCV imports:
import
org.bytedeco.javacpp.opencv_core.Mat
;
import
org.bytedeco.javacpp.opencv_imgproc
;
import
ijopencv.ij.ImagePlusMatConverter
;
import
ijopencv.opencv.MatImagePlusConverter
;
/**
* Implements the template matching routine from OpenCV.
* Additionally, a template can be rotated and flipped horizontally or vertically. The resulting matching coordinates can afterwards be filtered.
* @author Manuel Gunkel
*
*/
public
class
MatchTemplate
{
//prominence and strict values for the maximum finder:
private
double
prominence
=
10
;
private
boolean
strict
=
false
;
/*** Method for the template matching. The following methods are available:
* 0: TM_SQDIFF
* 1: TM_SQDIFF_NORMED
* 2: TM_CCORR
* 3: TM_CCORR_NORMED
* 4: TM_CCOEFF
* 5: TM_CCOEFF_NORMED
*/
private
int
method
=
5
;
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_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'.
* @param match Image in which the temlate should be identified
* @param template Image which should be identified in the bigger 'match' image.
* @param method Method used for the template matching (0-5)
* 0: TM_SQDIFF
* 1: TM_SQDIFF_NORMED
* 2: TM_CCORR
* 3: TM_CCORR_NORMED
* 4: TM_CCOEFF
* 5: TM_CCOEFF_NORMED
* @return result Correlation image between 'match' and 'template'. If W x H are the dimensions of 'match' and
* w x h the dimensions of 'template, 'result has the dimensions (W - w + 1) x (H - h + 1).
* @throws Exception
*/
public
ImagePlus
matchTemplate
(
ImagePlus
match
,
ImagePlus
template
,
int
method
)
throws
Exception
{
//get bit depth of the images and convert:
int
matchbd
=
match
.
getBitDepth
();
int
templatebd
=
template
.
getBitDepth
();
// OpenCV can only handle 8bit or 32 bit. check if both images are 8bit, otherwise convert:
if
(!(
matchbd
==
8
&&
templatebd
==
8
))
{
match
=
MatchTemplate
.
convertTo32bit
(
match
);
template
=
MatchTemplate
.
convertTo32bit
(
template
);;
}
// Convert the ImageJ images to OpenCV images
Mat
ocv_match
=
MatchTemplate
.
convertToMat
(
match
);
Mat
ocv_template
=
MatchTemplate
.
convertToMat
(
template
);
Mat
ocv_result
=
new
Mat
();
// do the matching
opencv_imgproc
.
matchTemplate
(
ocv_match
,
ocv_template
,
ocv_result
,
method
);
//convert the result to ImagePlus:
ImagePlus
result
=
MatImagePlusConverter
.
toImagePlus
(
ocv_result
);
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.
* @return maxima Polygon containing all identified coordinates
* @throws Exception
*/
public
Polygon
getPositions
(
ImagePlus
TMimage
)
throws
Exception
{
MaximumFinder
mf
=
new
MaximumFinder
();
Polygon
maxima
=
mf
.
getMaxima
(
TMimage
.
getProcessor
(),
this
.
prominence
,
this
.
strict
);
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.
* @param template The 'template' image.
* @param pg Polygon with the identified coordinates.
* @return pg Polygon with the coordinates shifted to the original 'match' image.
* @throws Exception
*/
public
Polygon
transferPositions
(
ImagePlus
template
,
Polygon
pg
)
throws
Exception
{
double
tw
=
template
.
getWidth
();
int
dx
=
(
int
)
Math
.
ceil
(
tw
/
2
);
double
th
=
template
.
getHeight
();
int
dy
=
(
int
)
Math
.
ceil
(
th
/
2
);
pg
.
translate
(
dx
,
dy
);
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.
* @param flip_hor Flag for flipping the template horizontally.
* @param flip_ver Flag for flipping the template vertically.
* @param alpha_start First angle by which the template should be rotated.
* @param alpha_step Rotation step size.
* @param alpha_stop Last angle by which the template is rotated.
* @throws Exception
*/
public
void
multiTemplateMatch
(
ImagePlus
template_
,
ImagePlus
match_
,
boolean
flip_hor
,
boolean
flip_ver
,
double
alpha_start
,
double
alpha_step
,
double
alpha_stop
)
throws
Exception
{
//match the template unflipped:
templateMatchRotations
(
template_
,
match_
,
false
,
false
,
alpha_start
,
alpha_step
,
alpha_stop
);
//match her template flipped vertically if flag is set:
if
(
flip_ver
)
{
ImagePlus
template_fv
=
template_
.
duplicate
();
ImageProcessor
fv
=
template_fv
.
getProcessor
();
fv
.
flipVertical
();
templateMatchRotations
(
template_fv
,
match_
,
false
,
flip_ver
,
alpha_start
,
alpha_step
,
alpha_stop
);
}
//match the template flipped horizontally if flag is set:
if
(
flip_hor
)
{
ImagePlus
template_fh
=
template_
.
duplicate
();
ImageProcessor
fh
=
template_fh
.
getProcessor
();
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.
* @param flip_hor Flag for flipping the template horizontally.
* @param flip_ver Flag for flipping the template vertically.
* @param alpha_start First angle by which the template should be rotated.
* @param alpha_step Rotation step size.
* @param alpha_stop Last angle by which the template is rotated.
* @throws Exception
*/
public
void
templateMatchRotations
(
ImagePlus
template_
,
ImagePlus
match_
,
boolean
flip_hor
,
boolean
flip_ver
,
double
alpha_start
,
double
alpha_step
,
double
alpha_stop
)
throws
Exception
{
ImagePlus
res
;
ImagePlus
testimage
;
//iterate over all angles
for
(
double
aha
=
alpha_start
;
aha
<=
alpha_stop
;
aha
=
aha
+
alpha_step
)
{
testimage
=
rotateImage
(
template_
,
aha
);
res
=
matchTemplate
(
match_
,
testimage
,
this
.
method
);
Polygon
pg
=
getPositions
(
res
);
int
xpos
=
0
;
int
ypos
=
0
;
// for each point identified, write the parameters to the instances respective ArrayList
for
(
int
i
=
0
;
i
<
pg
.
npoints
;
i
++)
{
xpos
=
pg
.
xpoints
[
i
];
ypos
=
pg
.
ypoints
[
i
];
// get correlation value from the correlation image:
double
intensity
=
res
.
getProcessor
().
getValue
(
xpos
,
ypos
);
//shift coordinates to the original 'match' image:
double
tw
=
testimage
.
getWidth
();
int
dx_pos
=
(
int
)
Math
.
ceil
(
tw
/
2
);
double
th
=
testimage
.
getHeight
();
int
dy_pos
=
(
int
)
Math
.
ceil
(
th
/
2
);
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
);
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_ver
.
add
(
flip_ver
);
this
.
angle_rot
.
add
(
aha
);
}
}
}
/** Rotates an image (creates a new rotated image). Calls the ImageJ 'Rotate ...' command.
* @param img_ Image to be rotated
* @param angle Angle by which the image should be rotated.
* @return The rotated image.
* @throws Exception
*/
public
ImagePlus
rotateImage
(
ImagePlus
img_
,
double
angle
)
throws
Exception
{
ImagePlus
tmpimg
=
img_
.
duplicate
();
IJ
.
run
(
tmpimg
,
"Rotate... "
,
"angle="
+
angle
+
" grid=-2 interpolation=Bilinear enlarge"
);
return
tmpimg
;
}
/** Filters the results. Locally, only the best matching (highest value in the correlation image) position is kept.
* A global threshold for the value of the found maxima can be set.
* @param radius local radius within which only the best matching template is regarded.
* @param corrthreshold threshold for the value of the maxima in the correlation image
* @throws Exception
*/
public
void
filterResults
(
double
radius
,
double
corrthreshold
)
throws
Exception
{
this
.
isvalidint
.
clear
();
this
.
isvalidxy
.
clear
();
//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_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
;
double
dx
=
0
;
double
dy
=
0
;
boolean
local_max
=
true
;
// 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
)
{
isvalidint
.
add
(
true
);
}
else
isvalidint
.
add
(
false
);
// Check if the coordinate is a local maximum of the correlation value compare with all other coordinates:
// (somewhat brute force, could'nt think of anything clever)
for
(
int
j
=
0
;
j
<
positions_x
.
size
();
j
++)
{
dx
=
positions_x
.
get
(
i
)-
positions_x
.
get
(
j
);
dy
=
positions_y
.
get
(
i
)-
positions_y
.
get
(
j
);
r
=
Math
.
sqrt
((
dx
*
dx
+
dy
*
dy
));
if
(
r
<=
radius
)
{
if
(
intensity_match
.
get
(
j
)>
intensity_match
.
get
(
i
))
{
local_max
=
false
;
}
}
}
isvalidxy
.
add
(
local_max
);
local_max
=
true
;
// add to temp lists if both criteria are fulfilled:
if
(
isvalidint
.
get
(
i
)
&&
isvalidxy
.
get
(
i
))
{
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_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
);
}
// replace the original instance lists with the temp lists:
positions_x
=
positions_x_tmp
;
positions_y
=
positions_y_tmp
;
intensity_match
=
intensity_match_tmp
;
is_fipped_hor
=
is_fipped_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"
);
}
/***************************************************
* HELPER METHODS
* 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
;
}
// // conversion to 8bit should not be needed. otherwise reactivate:
// private static ImagePlus convertTo8bit(ImagePlus _img) {
// ImageConverter ic = new ImageConverter(_img);
// ic.convertToGray8();
// return _img;
// }
private
static
ImagePlus
convertTo32bit
(
ImagePlus
_img
)
throws
Exception
{
ImageConverter
ic
=
new
ImageConverter
(
_img
);
ic
.
convertToGray32
();
return
_img
;
}
private
static
Mat
convertToMat
(
ImagePlus
_img
)
throws
Exception
{
ImagePlusMatConverter
ic
=
new
ImagePlusMatConverter
();
Mat
cImg
=
ic
.
convert
(
_img
,
Mat
.
class
);
return
cImg
;
}
private
static
ImagePlus
setImage
(
String
imgPath
)
throws
Exception
{
File
fd
=
new
File
(
imgPath
);
ImagePlus
img
=
ImageOpenerWithBioformats
.
openImage
(
fd
);
return
img
;
}
public
double
getProminence
()
{
return
prominence
;
}
public
void
setProminence
(
double
prominence
)
{
this
.
prominence
=
prominence
;
}
public
int
getMethod
()
{
return
method
;
}
public
void
setMethod
(
int
method
)
{
this
.
method
=
method
;
}
public
boolean
isStrict
()
{
return
strict
;
}
public
void
setStrict
(
boolean
strict
)
{
this
.
strict
=
strict
;
}
/*****************************************************************************
* Main method
*****************************************************************************/
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\\FoR.tif";
// template image: wrong filetype (16 bit), needs conversion
final
String
matchPath
=
"C:\\Users\\Manu\\tmp\\Watch_TemplateMatch\\MatchMe--WholeArgo_flat.czi"
;
//final String templatePath="C:\\Users\\Manu\\Desktop\\ArgoLight\\Templates\\MatchMe--8bit.tif";
//start imageJ:
new
ij
.
ImageJ
();
IJ
.
log
(
"---Template matchin start---"
);