Commit 51c23b62 authored by Andrey Filippov's avatar Andrey Filippov

Added target annotations

parent f33de0c3
......@@ -292,6 +292,7 @@ public class CuasMotion {
boolean no_border= clt_parameters.imp.cuas_no_border; // true;
// Moving target LMA
double lma_sigma = clt_parameters.imp.cuas_lma_sigma; // = 3.0;
double wnd_pedestal = clt_parameters.imp.cuas_wnd_pedestal; // = 0.1;
double lma_r0 = clt_parameters.imp.cuas_lma_r0; // = 3.0; //maximum with with overshoot
double lma_ovrsht = clt_parameters.imp.cuas_lma_ovrsht; // = 2.0;
// CUAS Motion LMA parameters
......@@ -385,6 +386,8 @@ public class CuasMotion {
gd.addMessage("=== Moving target LMA ===");
gd.addNumericField("Weight Gaussian sigma", lma_sigma, 5,8,"pix",
"Weights to emphasize maximum center area when fitting.");
gd.addNumericField("Weight pedestal", wnd_pedestal, 5,8,"",
"Add constant to Gaussian weights.");
gd.addNumericField("Target typical radius", lma_r0, 5,8,"pix",
"Typical target radius including negative overshoot (caused by UM filter).");
gd.addNumericField("Target maximum overshoot", lma_ovrsht, 5,8,"",
......@@ -501,6 +504,7 @@ public class CuasMotion {
target_frac = IntersceneMatchParameters.stringToDouble2d(gd.getNextString());
no_border = gd.getNextBoolean();
lma_sigma = gd.getNextNumber();
wnd_pedestal = gd.getNextNumber();
lma_r0 = gd.getNextNumber();
lma_ovrsht = gd.getNextNumber();
lma_fit_xy = gd.getNextBoolean();
......@@ -578,6 +582,7 @@ public class CuasMotion {
}
clt_parameters.imp.cuas_no_border = no_border;
clt_parameters.imp.cuas_lma_sigma = lma_sigma;
clt_parameters.imp.cuas_wnd_pedestal= wnd_pedestal;
clt_parameters.imp.cuas_lma_r0 = lma_r0;
clt_parameters.imp.cuas_lma_fit_xy= lma_fit_xy;
clt_parameters.imp.cuas_lma_fit_a= lma_fit_a;
......@@ -652,6 +657,7 @@ public class CuasMotion {
System.out.println("target_frac= "+IntersceneMatchParameters.double2dToString(target_frac));
System.out.println("no_border= "+no_border);
System.out.println("lma_sigma= "+lma_sigma);
System.out.println("wnd_pedestal= "+wnd_pedestal);
System.out.println("lma_r0= "+lma_r0);
System.out.println("lma_ovrsht= "+lma_ovrsht);
System.out.println("lma_fit_xy= "+lma_fit_xy);
......@@ -1011,6 +1017,7 @@ public class CuasMotion {
final boolean no_border,
// Moving target LMA
final double lma_sigma,
final double wnd_pedestal,
final double lma_r0,
final double lma_ovrsht,
// CUAS Motion LMA parameters
......@@ -1053,7 +1060,8 @@ public class CuasMotion {
double [] pix_tile = new double [tile2 * tile2];
CuasMotionLMA cuasMotionLMA = new CuasMotionLMA(
tile2, // int width,
lma_sigma); // double sigma);
lma_sigma, // double sigma);
wnd_pedestal);
// may be faster if process only where vector_field[nseq][ntile] is not null
for (int nSeq = ai.getAndIncrement(); nSeq < num_seq; nSeq = ai.getAndIncrement()) {
for (int ntile = 0; ntile < num_tiles; ntile++) {
......@@ -2406,9 +2414,22 @@ public class CuasMotion {
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
// String diamond_path = "/media/elphel/NVME/lwir16-proc/eagle_mountain/graphics/diamond21x17.png";
final boolean annotate_mono = clt_parameters.imp.annotate_mono;
final boolean annotate_mono = clt_parameters.imp.annotate_mono;
final boolean annotate_transparent_mono = clt_parameters.imp.annotate_transparent_mono;
final Color annotate_color_mono = clt_parameters.imp.annotate_color_mono;
final Color annotate_color_mono = clt_parameters.imp.annotate_color_mono;
final boolean annotate = clt_parameters.imp.cuas_annotate;
final Color text_color = clt_parameters.imp.cuas_text_color;
final String font_name = clt_parameters.imp.cuas_font_name;
final int font_size = clt_parameters.imp.cuas_font_size;
final int font_type = clt_parameters.imp.cuas_font_type;
final double ifov = clt_parameters.imp.cuas_ifov;
final int px0 = clt_parameters.imp.cuas_px0;
final int py0 = clt_parameters.imp.cuas_py0;
final double az0 = clt_parameters.imp.cuas_az0;
final double el0 = clt_parameters.imp.cuas_el0;
final int space_before_text = 2;
ColorProcessor diamond_cp = null;
try {
diamond_cp = new ColorProcessor(ImageIO.read(new File(diamond_path)));
......@@ -2507,7 +2528,9 @@ public class CuasMotion {
final ImageStack fstack_scenes = imp.getImageStack();
final int posX= width - scale * 119; // 521;
final int posY= height + scale * 1; // 513;
final Font font = new Font("Monospaced", Font.PLAIN, scale2x? 24: 12);
final Font font = new Font("Monospaced", Font.PLAIN, scale * 12);
final Font font_target = new Font(font_name, font_type, scale * font_size);
final boolean target_text_transparent = true;
final int nSlices = fstack_scenes.getSize();
if (annotate_mono) {
ai.set(0);
......@@ -2584,6 +2607,21 @@ public class CuasMotion {
}
}
}
if (annotate) {
int text_left = xl + diamond_width + space_before_text * scale;
int text_top = yt + scale * font_size; // text start from the bottom of the first line
ImageProcessor ip = fstack_scenes.getProcessor(nscene+1);
String txt = getTargetText(
clt_parameters, // CLTParameters clt_parameters,
targets[ntarget]); // double [] target);
ip.setColor(text_color);
ip.setFont(font_target);
if (target_text_transparent) {
ip.drawString(txt, text_left, text_top); // transparent.
} else {
ip.drawString(txt, text_left, text_top, Color.BLACK); // on black background
}
}
}
}
}
......@@ -2597,6 +2635,54 @@ public class CuasMotion {
return imp;
}
public static String getTargetText(
CLTParameters clt_parameters,
double [] target) {
double target_x = target[TARGET_X];
double target_y = target[TARGET_Y];
double target_vx = target[TARGET_VX];
double target_vy = target[TARGET_VY];
String omega = "\u03A9";
double fps = 60.0;
String number_format = "%3.0f";
String omega_format = "%3.1f";
double ifov = clt_parameters.imp.cuas_ifov; // 0.05; // degree per pixel
int px0 = clt_parameters.imp.cuas_px0; // 283; // pixel with known azimuth
int py0 = clt_parameters.imp.cuas_py0; // 386; // pixel with known elevation
double az0 = clt_parameters.imp.cuas_az0; // 201.5; // degrees for cuas_px0;
double el0 = clt_parameters.imp.cuas_el0; // 0.0; // degrees for cuas_px0;
double az = (target_x - px0)*ifov+az0;
double el = -(target_y - py0)*ifov+el0;
double omega_az = target_vx * ifov * fps;
double omega_el = -target_vy * ifov * fps;
while (az < 0) {
az += 360;
}
while (az >= 360) {
az -= 360;
}
while (el < -180) {
el += 360;
}
while (el > 180) {
el -= 360;
}
String txt = "";
txt += " AZ "+String.format(number_format,az)+"\n";
txt += " EL "+ getSignedDouble(el,number_format)+"\n";
txt += omega+"AZ "+getSignedDouble(omega_az,omega_format)+"\n";
txt += omega+"EL "+getSignedDouble(omega_el,omega_format);
return txt;
}
public static String getSignedDouble(
double d,
String format) {
String s = (d > 0)? "+" : ( (d <0)? "-":" ");
return s+ String.format(format, Math.abs(d));
}
public static String saveAsVideo(
CLTParameters clt_parameters,
QuadCLT scene, // if not null - use it's model directory
......@@ -2778,6 +2864,7 @@ public class CuasMotion {
boolean no_border= clt_parameters.imp.cuas_no_border; // true;
// Moving target LMA
double lma_sigma = clt_parameters.imp.cuas_lma_sigma; // = 3.0;
double wnd_pedestal = clt_parameters.imp.cuas_wnd_pedestal; // = 3.0;
double lma_r0 = clt_parameters.imp.cuas_lma_r0; // = 3.0; //maximum with with overshoot
double lma_ovrsht = clt_parameters.imp.cuas_lma_ovrsht; // = 2.0;
// CUAS Motion LMA parameters
......@@ -3075,6 +3162,7 @@ public class CuasMotion {
no_border, // final boolean no_border,
// Moving target LMA
lma_sigma, // final double lma_sigma,
wnd_pedestal, // final double wnd_pedestal,
lma_r0, // final double lma_r0,
lma_ovrsht, // final double lma_ovrsht,
// CUAS Motion LMA parameters
......@@ -3277,7 +3365,9 @@ public class CuasMotion {
final double [][] target_frac = new double [clt_parameters.imp.cuas_target_frac.length][2];
// Moving target LMA
double lma_sigma = clt_parameters.imp.cuas_lma_sigma; // = 3.0;
double lma_sigma = clt_parameters.imp.cuas_lma_sigma; // = 3.0;
double wnd_pedestal = clt_parameters.imp.cuas_wnd_pedestal; // = 0.1;
double lma_r0 = clt_parameters.imp.cuas_lma_r0; // = 3.0; //maximum with with overshoot
double lma_ovrsht = clt_parameters.imp.cuas_lma_ovrsht; // = 2.0;
// CUAS Motion LMA parameters
......@@ -3361,6 +3451,7 @@ public class CuasMotion {
no_border, // final boolean no_border,
// Moving target LMA
lma_sigma, // final double lma_sigma,
wnd_pedestal, // final double wnd_pedestal,
lma_r0, // final double lma_r0,
lma_ovrsht, // final double lma_ovrsht,
// CUAS Motion LMA parameters
......
......@@ -64,13 +64,14 @@ public class CuasMotionLMA {
public CuasMotionLMA(
int width,
double sigma) {
double sigma,
double wnd_pedestal) {
this.width = width;
window = new double [width][width];
double k = -0.5/(sigma*sigma);
for (int i = 0; i < width; i++) {
for (int j = 0; j < width; j++) {
window[i][j] = Math.exp(k*(i*i+j*j));
window[i][j] = Math.exp(k*(i*i+j*j)) + wnd_pedestal; // will be normalized when used
}
}
}
......
......@@ -38,6 +38,7 @@ public class IntersceneMatchParameters {
public static String [] MODES_AVI = {"RAW", "JPEG", "PNG"};
public static String [] FLT_ALT_MODES = {"--- (no ALT filter)", "ALT only", "no ALT only"};
public static String [] FLT_ORIENT_MODES = {"--- (no ORIENT filter)", "ORIENT only", "no ORIENT only"};
public static Color DEFAULT_TARGET_TEXT_COLOR = new Color (0, 255, 255); // 220);
// Maybe add parameters to make sure there is enough data? Enough in each zone? Enough spread?
public boolean ims_use = true; // use IMS data
......@@ -724,6 +725,7 @@ min_str_neib_fpn 0.35
public boolean cuas_no_border = true; // exclude targets with centers on the 16x16 tile edges
// CUAS Motion LMA parameters
public double cuas_lma_sigma = 3.0;
public double cuas_wnd_pedestal = 0.1; // Add constant to Gaussian weights
public double cuas_lma_r0 = 3.0; //maximum with with overshoot
public double cuas_lma_ovrsht = 2.0;
......@@ -772,6 +774,18 @@ min_str_neib_fpn 0.35
public boolean cuas_save_color = true; // save color rendered images (same as videos)
public boolean cuas_save_video = true; // save color rendered images (same as videos)
public boolean cuas_annotate = true; // save color rendered images (same as videos)
public Color cuas_text_color = new Color (0, 255, 255);// 220);
public String cuas_font_name = "Monospaced";
public int cuas_font_size = 6; // before scaling
public int cuas_font_type = 1; // 0 - PLAIN, 1 - BOLD, 2 - ITALIC
// AZ/EL calibration
public double cuas_ifov = 0.05; // degree per pixel
public int cuas_px0 = 283; // pixel with known azimuth
public int cuas_py0 = 386; // pixel with known elevation
public double cuas_az0 = 201.5; // degrees for cuas_px0;
public double cuas_el0 = 0.0; // degrees for cuas_px0;
public boolean cuas_debug = false; // save debug images (and show them if not in batch mode)
......@@ -2226,6 +2240,8 @@ min_str_neib_fpn 0.35
gd.addMessage("=== Moving target LMA ===");
gd.addNumericField("Weight Gaussian sigma", this.cuas_lma_sigma, 5,8,"pix",
"Weights to emphasize maximum center area when fitting.");
gd.addNumericField("Weight pedestal", this.cuas_wnd_pedestal, 5,8,"",
"Add constant to Gaussian weights.");
gd.addNumericField("Target typical radius", this.cuas_lma_r0, 5,8,"pix",
"Typical target radius including negative overshoot (caused by UM filter).");
gd.addNumericField("Target maximum overshoot", this.cuas_lma_ovrsht, 5,8,"",
......@@ -2322,6 +2338,30 @@ min_str_neib_fpn 0.35
gd.addCheckbox ("Save videos", this.cuas_save_video,
"Save video with moving targets.");
gd.addMessage("=== Target Annotation ===");
gd.addCheckbox ("Annotate targets", this.cuas_annotate,
"Add textual annptations to the target icons.");
{
String scolor = String.format("%08x", getLongColor(this.cuas_text_color));
gd.addStringField ("Tast color",scolor, 8, "Any invalid hex number disables annotation");
}
gd.addStringField ("Font name", this.cuas_font_name, 20,
"Font name, currently \"Monospaced\".");
gd.addNumericField("Font size", this.cuas_font_size, 0,3,"pnt",
"Font size befoerr image scaling. Scaled images use proportionally scaled font .");
gd.addNumericField("Font type", this.cuas_font_type, 0,3,"",
"Font type: 0 - PLAIN, 1 - BOLD, 2 - ITALIC.");
gd.addNumericField("IFOV", this.cuas_ifov, 5,8,"degree/pixel",
"Angular size (degrees) of one pixel.");
gd.addNumericField("Known image pixel X coordinate", this.cuas_px0, 0,3,"",
"Image pixel X corresponding to the known azimuth.");
gd.addNumericField("Known image pixel X coordinate", this.cuas_py0, 0,3,"",
"Image pixel Y corresponding to the known elevation.");
gd.addNumericField("Known pixel azimuth", this.cuas_az0, 5,8,"degree",
"Azimuth corresponding to the known pixel X.");
gd.addNumericField("Known pixel azimuth", this.cuas_el0, 5,8,"degree",
"Elevation corresponding to the known pixel Y.");
gd.addMessage("=== Debug ===");
gd.addCheckbox ("Save/show debug images", this.cuas_debug,
"Save CUAS-related debug images and show them in non-batch mode.");
......@@ -3296,6 +3336,7 @@ min_str_neib_fpn 0.35
this.cuas_no_border = gd.getNextBoolean();
this.cuas_lma_sigma = gd.getNextNumber();
this.cuas_wnd_pedestal = gd.getNextNumber();
this.cuas_lma_r0 = gd.getNextNumber();
this.cuas_lma_ovrsht = gd.getNextNumber();
this.cuas_lma_fit_xy = gd.getNextBoolean();
......@@ -3337,6 +3378,26 @@ min_str_neib_fpn 0.35
this.cuas_save_color = gd.getNextBoolean();
this.cuas_save_video = gd.getNextBoolean();
this.cuas_annotate = gd.getNextBoolean();
{
String scolor = gd.getNextString();
long lcolor = -1;
try {
lcolor = Long.parseLong(scolor,16);
this.cuas_text_color = setLongColor(lcolor);
} catch(NumberFormatException e){
this.cuas_text_color = setLongColor(0xCCFF00);
}
}
this.cuas_font_name = gd.getNextString();
this.cuas_font_size = (int) gd.getNextNumber();
this.cuas_font_type = (int) gd.getNextNumber();
this.cuas_ifov = gd.getNextNumber();
this.cuas_px0 = (int) gd.getNextNumber();
this.cuas_py0 = (int) gd.getNextNumber();
this.cuas_az0 = gd.getNextNumber();
this.cuas_el0 = gd.getNextNumber();
this.cuas_debug = gd.getNextBoolean();
this.cuas_step_debug = gd.getNextBoolean();
......@@ -4237,6 +4298,7 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_no_border", this.cuas_no_border+""); // boolean
properties.setProperty(prefix+"cuas_lma_sigma", this.cuas_lma_sigma+""); // double
properties.setProperty(prefix+"cuas_wnd_pedestal", this.cuas_wnd_pedestal+""); // double
properties.setProperty(prefix+"cuas_lma_r0", this.cuas_lma_r0+""); // double
properties.setProperty(prefix+"cuas_lma_ovrsht", this.cuas_lma_ovrsht+""); // double
properties.setProperty(prefix+"cuas_lma_fit_xy", this.cuas_lma_fit_xy+""); // boolean
......@@ -4278,6 +4340,21 @@ min_str_neib_fpn 0.35
properties.setProperty(prefix+"cuas_save_color", this.cuas_save_color+""); // boolean
properties.setProperty(prefix+"cuas_save_video", this.cuas_save_video+""); // boolean
properties.setProperty(prefix+"cuas_annotate", this.cuas_annotate+""); // boolean
{
long lcolor_annotate = (cuas_text_color == null) ? 0xCCFF00 : getLongColor(this.cuas_text_color);
properties.setProperty(prefix+"cuas_text_color", lcolor_annotate+"");
}
properties.setProperty(prefix+"cuas_font_name", this.cuas_font_name+""); // String
properties.setProperty(prefix+"cuas_font_size", this.cuas_font_size+""); // int
properties.setProperty(prefix+"cuas_font_type", this.cuas_font_type+""); // int
properties.setProperty(prefix+"cuas_ifov", this.cuas_ifov+""); // double
properties.setProperty(prefix+"cuas_px0", this.cuas_px0+""); // int
properties.setProperty(prefix+"cuas_py0", this.cuas_py0+""); // int
properties.setProperty(prefix+"cuas_az0", this.cuas_az0+""); // double
properties.setProperty(prefix+"cuas_el0", this.cuas_el0+""); // double
properties.setProperty(prefix+"cuas_debug", this.cuas_debug+""); // boolean
properties.setProperty(prefix+"cuas_step_debug", this.cuas_step_debug+""); // boolean
......@@ -5150,6 +5227,7 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_no_border")!=null) this.cuas_no_border=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_no_border"));
if (properties.getProperty(prefix+"cuas_lma_sigma")!=null) this.cuas_lma_sigma=Double.parseDouble(properties.getProperty(prefix+"cuas_lma_sigma"));
if (properties.getProperty(prefix+"cuas_wnd_pedestal")!=null) this.cuas_wnd_pedestal=Double.parseDouble(properties.getProperty(prefix+"cuas_wnd_pedestal"));
if (properties.getProperty(prefix+"cuas_lma_r0")!=null) this.cuas_lma_r0=Double.parseDouble(properties.getProperty(prefix+"cuas_lma_r0"));
if (properties.getProperty(prefix+"cuas_lma_ovrsht")!=null) this.cuas_lma_ovrsht=Double.parseDouble(properties.getProperty(prefix+"cuas_lma_ovrsht"));
if (properties.getProperty(prefix+"cuas_lma_fit_xy")!=null) this.cuas_lma_fit_xy=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_lma_fit_xy"));
......@@ -5192,6 +5270,21 @@ min_str_neib_fpn 0.35
if (properties.getProperty(prefix+"cuas_save_color")!=null) this.cuas_save_color=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_save_color"));
if (properties.getProperty(prefix+"cuas_save_video")!=null) this.cuas_save_video=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_save_video"));
if (properties.getProperty(prefix+"cuas_annotate")!=null) this.cuas_annotate=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_annotate"));
if (properties.getProperty(prefix+"cuas_text_color")!=null) {
long lcolor_annotate = Long.parseLong(properties.getProperty(prefix+"cuas_text_color"));
if (lcolor_annotate < 0) this.cuas_text_color = setLongColor(0xCCFF00);
else this.cuas_text_color = setLongColor(lcolor_annotate);
}
if (properties.getProperty(prefix+"cuas_font_name")!= null) cuas_font_name=(String) properties.getProperty(prefix+"cuas_font_name");
if (properties.getProperty(prefix+"cuas_font_size")!=null) this.cuas_font_size=Integer.parseInt(properties.getProperty(prefix+"cuas_font_size"));
if (properties.getProperty(prefix+"cuas_font_type")!=null) this.cuas_font_type=Integer.parseInt(properties.getProperty(prefix+"cuas_font_type"));
if (properties.getProperty(prefix+"cuas_ifov")!=null) this.cuas_ifov=Double.parseDouble(properties.getProperty(prefix+"cuas_ifov"));
if (properties.getProperty(prefix+"cuas_px0")!=null) this.cuas_px0=Integer.parseInt(properties.getProperty(prefix+"cuas_px0"));
if (properties.getProperty(prefix+"cuas_py0")!=null) this.cuas_py0=Integer.parseInt(properties.getProperty(prefix+"cuas_py0"));
if (properties.getProperty(prefix+"cuas_az0")!=null) this.cuas_az0=Double.parseDouble(properties.getProperty(prefix+"cuas_az0"));
if (properties.getProperty(prefix+"cuas_el0")!=null) this.cuas_el0=Double.parseDouble(properties.getProperty(prefix+"cuas_el0"));
if (properties.getProperty(prefix+"cuas_debug")!=null) this.cuas_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_debug"));
if (properties.getProperty(prefix+"cuas_step_debug")!=null) this.cuas_step_debug=Boolean.parseBoolean(properties.getProperty(prefix+"cuas_step_debug"));
......@@ -6061,6 +6154,7 @@ min_str_neib_fpn 0.35
}
imp.cuas_no_border = this.cuas_no_border;
imp.cuas_lma_sigma = this.cuas_lma_sigma;
imp.cuas_wnd_pedestal = this.cuas_wnd_pedestal;
imp.cuas_lma_r0 = this.cuas_lma_r0;
imp.cuas_lma_ovrsht = this.cuas_lma_ovrsht;
imp.cuas_lma_fit_xy = this.cuas_lma_fit_xy;
......@@ -6103,6 +6197,19 @@ min_str_neib_fpn 0.35
imp.cuas_save_color = this.cuas_save_color;
imp.cuas_save_video = this.cuas_save_video;
imp.cuas_annotate = this.cuas_annotate;
imp.cuas_text_color= this.cuas_text_color;
imp.cuas_font_name = this.cuas_font_name;
imp.cuas_font_size = this.cuas_font_size;
imp.cuas_font_type = this.cuas_font_type;
imp.cuas_ifov = this.cuas_ifov;
imp.cuas_px0 = this.cuas_px0;
imp.cuas_py0 = this.cuas_py0;
imp.cuas_az0 = this.cuas_az0;
imp.cuas_el0 = this.cuas_el0;
imp.cuas_debug = this.cuas_debug;
imp.cuas_step_debug = this.cuas_step_debug;
......
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