Commit d0583386 authored by Andrey Filippov's avatar Andrey Filippov

Before removing old image pane generation

parent 1e63c534
...@@ -162,6 +162,7 @@ public class CuasMotion { ...@@ -162,6 +162,7 @@ public class CuasMotion {
(1 << ANNOT_TRV), (1 << ANNOT_TRV),
(1 << ANNOT_ID) | (1 << ANNOT_ID) |
(1 << ANNOT_DISP) |
(1 << ANNOT_RANGE) | (1 << ANNOT_RANGE) |
(1 << ANNOT_TRANG) | (1 << ANNOT_TRANG) |
(1 << ANNOT_AGL) | (1 << ANNOT_AGL) |
...@@ -169,7 +170,8 @@ public class CuasMotion { ...@@ -169,7 +170,8 @@ public class CuasMotion {
(1 << ANNOT_ELNOAGL) | (1 << ANNOT_ELNOAGL) |
(1 << ANNOT_VS) | (1 << ANNOT_VS) |
(1 << ANNOT_GS) | (1 << ANNOT_GS) |
(1 << ANNOT_HDG), (1 << ANNOT_HDG)|
(1 << ANNOT_SCORE),
(1 << ANNOT_ID) | (1 << ANNOT_ID) |
(1 << ANNOT_RANGE) | (1 << ANNOT_RANGE) |
...@@ -4008,7 +4010,8 @@ public class CuasMotion { ...@@ -4008,7 +4010,8 @@ public class CuasMotion {
return iclt_fimg[0][0].clone(); return iclt_fimg[0][0].clone();
} }
public ImagePlus convertToRgbAnnotateTargets( @Deprecated
public ImagePlus convertToRgbAnnotateTargets_old(
CLTParameters clt_parameters, CLTParameters clt_parameters,
final double input_range, // 5 final double input_range, // 5
final boolean scale2x, final boolean scale2x,
...@@ -4160,7 +4163,6 @@ public class CuasMotion { ...@@ -4160,7 +4163,6 @@ public class CuasMotion {
final int num_scenes = fpixels.length; final int num_scenes = fpixels.length;
final int num_pixels = fpixels[0].length; final int num_pixels = fpixels[0].length;
final int num_seq = targets60hz.length; final int num_seq = targets60hz.length;
// final int height = num_pixels/width;
ImagePlus imp = ShowDoubleFloatArrays.makeArrays( ImagePlus imp = ShowDoubleFloatArrays.makeArrays(
fpixels, // float[][] pixels, fpixels, // float[][] pixels,
width_src, // int width, width_src, // int width,
...@@ -4225,19 +4227,14 @@ public class CuasMotion { ...@@ -4225,19 +4227,14 @@ public class CuasMotion {
color_stack.addSlice(cp_labels[i],color_processors[i]); color_stack.addSlice(cp_labels[i],color_processors[i]);
} }
imp = new ImagePlus(imp_title, color_stack); // imp.getTitle(),stack); imp = new ImagePlus(imp_title, color_stack); // imp.getTitle(),stack);
final int width = imp.getProcessor().getWidth(); final int width = imp.getProcessor().getWidth();
final int height = imp.getProcessor().getHeight(); final int height = imp.getProcessor().getHeight();
// imp.show();
final Color fcolor = annotate_color_mono; final Color fcolor = annotate_color_mono;
final ImageStack fstack_scenes = imp.getImageStack(); final ImageStack fstack_scenes = imp.getImageStack();
final int posX= width - scale * 119; // 521; final int posX= width - scale * 119; // 521;
final int posY= height + scale * 1; // 513; final int posY= height + scale * 1; // 513;
final Font font = new Font("Monospaced", Font.PLAIN, scale * 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 Font font_target = new Font(font_name, font_type, scale * font_size);
// final boolean target_text_transparent = true;
final int nSlices = fstack_scenes.getSize(); final int nSlices = fstack_scenes.getSize();
if (annotate_mono) { if (annotate_mono) {
ai.set(0); ai.set(0);
...@@ -4432,141 +4429,684 @@ public class CuasMotion { ...@@ -4432,141 +4429,684 @@ public class CuasMotion {
return imp; return imp;
} }
public static ColorProcessor getIconColorProcessor( public ImagePlus convertToRgbAnnotateTargets(
int target_type, // Target location matching UAS flight log: 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe CLTParameters clt_parameters,
boolean scale2x) { final boolean clean_pass,
String resource_name = TARGET_ICONS[target_type][scale2x? 1 : 0]; final double input_range, // 5
final boolean scale2x,
final int target_type, // = 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe
final int known_type, // 2; // Target location matching UAS flight log: 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe
final double known_err, // 20; // Maximal distance between the detected target and UAS log position (in raw image pixels);
final float [][] fpixels,
final double [][][] targets60hz,
final boolean change_color,
final boolean show_disp, // true; // Show disparity (corrected) near target (*** not in clean***)
final boolean show_rng, // true; // Show distance to target (range) in meters
final boolean show_inf, // true; // Show distance greater than max (or negativce) as infinity
final boolean show_inf_gt, // false; // Use ">max" instead of infinity symbol
final boolean show_true_rng,// show true range (from the flight log)
final boolean show_mismatch,
final boolean show_score,
final boolean show_uas,
final int frame0,
final int frame_step,
final int width_src,
final String title,
final String [] titles,
final UasLogReader uasLogReader,
final int debugLevel) {
final boolean annot_missing = clt_parameters.imp.cuas_annot_missing; // false; // make a parameter.Reserve a line for requested but missing parameters
// final boolean clean_pass = false; // (add it)
int annot_mode0 = clt_parameters.imp.cuas_annot_sel[CuasMotion.ANNOT_IMAGE_PANE_INDX];
if (clean_pass) {
annot_mode0 &= clt_parameters.imp.cuas_annot_sel[ANNOT_CLEAN_VIEW_INDX]; //ANNOT_CLEAN;
}
final int annot_mode = annot_mode0;
System.out.println(String.format("Image annotation mode 0x%04x (0x%04x & 0x%04x)",
annot_mode, clt_parameters.imp.cuas_annot_sel[CuasMotion.ANNOT_RADAR_PANE_INDX],clt_parameters.imp.cuas_annot_sel[ANNOT_CLEAN_VIEW_INDX]));
// parentCLT
final GeometryCorrection gc = parentCLT.getGeometryCorrection();
String uas_log_path = null;
boolean annotate_uas = show_uas && (uasLogReader != null);
if (annotate_uas) {
String resource_name = ICON_BLUE;
URL resourceUrl = CuasMotion.class.getClassLoader().getResource("graphics/"+resource_name); URL resourceUrl = CuasMotion.class.getClassLoader().getResource("graphics/"+resource_name);
Path undetected_resourcePath = null; Path resourcePath = null;
try { try {
undetected_resourcePath = Paths.get(resourceUrl.toURI()); resourcePath = Paths.get(resourceUrl.toURI());
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
String path = undetected_resourcePath.toString(); uas_log_path = resourcePath.toString();
ColorProcessor cp = null; System.out.println("uas_log_path="+uas_log_path);
}
final double [] camera_atr = uasLogReader.getCameraATR();
final ErsCorrection ersCorrection = parentCLT.getErsCorrection();
// prepare target icons
ColorProcessor cp_target_icon = getIconColorProcessor(
target_type, // int target_type, // Target location matching UAS flight log: 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe
scale2x); // boolean scale2x)
ColorProcessor cp_uas_icon = getIconColorProcessor(
known_type, // uas_type, // int target_type, // Target location matching UAS flight log: 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe
scale2x); // boolean scale2x)
final int target_icon_width = cp_target_icon.getWidth();
final int uas_icon_width = cp_uas_icon.getWidth();
final int [] target_icon_pixels = (int[]) cp_target_icon.getPixels();
final int [] uas_icon_pixels = (int[]) cp_uas_icon.getPixels();
final int [][] target_icon_rgba = splitColorIcon(target_icon_pixels);
final int [][] uas_icon_rgba = splitColorIcon(uas_icon_pixels);
final int scale = scale2x? 2 : 1;
final Thread[] threads = ImageDtt.newThreadArray(QuadCLT.THREADS_MAX);
final AtomicInteger ai = new AtomicInteger(0);
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 boolean annotate = clt_parameters.imp.cuas_annotate;
final Color text_color = clt_parameters.imp.cuas_text_color;
final Color text_bg_color = clt_parameters.imp.cuas_text_bg;
final Color selected_color = clt_parameters.imp.cuas_selected_color;
final boolean transparent_other = clt_parameters.imp.cuas_transparent;
final boolean transparent_uas = clt_parameters.imp.cuas_transparent_uas;
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 int space_before_text = 2 * scale;
final double rng_limit = clt_parameters.imp.cuas_rng_limit;
final double font_ratio = clt_parameters.imp.cuas_font_spacing; // 1.2; // if 0 - will use default spacing ( ~=1.5)
final int tileSize = GPUTileProcessor.DTT_SIZE;
ColorProcessor uaslog_cp = null;
if (uas_log_path != null) {
try { try {
cp = new ColorProcessor(ImageIO.read(new File(path))); uaslog_cp = new ColorProcessor(ImageIO.read(new File(uas_log_path)));
} catch (IOException e1) { } catch (IOException e1) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e1.printStackTrace(); e1.printStackTrace();
} }
return cp;
} }
final int uaslog_width = (uaslog_cp != null) ? uaslog_cp.getWidth() : 0;
public static int [][] splitColorIcon(int [] icon){ final int uaslog_height = (uaslog_cp != null) ? uaslog_cp.getHeight() : 0;
final int [][] icon_rgba = new int [icon.length][4]; final int [] uaslog_pixels = (uaslog_cp != null) ? ((int []) uaslog_cp.getPixels()) : null;
for (int i = 0; i < icon_rgba.length; i++) { final int [][] uaslog_rgba = (uaslog_cp != null) ? (new int [uaslog_pixels.length][4]) : null;
for (int s = 0; s < 4; s++) { if (uaslog_cp != null) {
icon_rgba[i][s] = (icon[i] >> (8 * s)) & 0xff; for (int i = 0; i < uaslog_rgba.length; i++) {
for (int s = 0; s <4; s++) {
uaslog_rgba[i][s] = (uaslog_pixels[i] >> (8 * s)) & 0xff;
} }
} }
return icon_rgba; }
if (uaslog_pixels != null) {
System.out.println("uaslog_width="+uaslog_width+",uaslog_height="+uaslog_height);
} }
public static void imprintPixelIcon(
int [][] icon,
int [] icon_pix,
int icon_width,
int [] image,
int width,
int xc,
int yc) {
int icon_height = icon.length/icon_width;
int height = image.length/width;
int xl = xc - icon_width/2;
int yt = yc - icon_height/2;
int xr = xc + icon_width/2;
int yb = yc + icon_height/2;
if ((xl < 0) || (yt < 0) || (xr >= width) || (yb >= height)) { final int num_scenes = fpixels.length;
System.out.println("imprintPixelIcon(): outside of the window: xc="+xc+", yc="+yc+", width="+width+", height="+height); final int num_pixels = fpixels[0].length;
return; // final int num_seq = targets60hz.length;
final int num_seq = targets.length;
ImagePlus imp = ShowDoubleFloatArrays.makeArrays(
fpixels, // float[][] pixels,
width_src, // int width,
num_pixels/width_src, // int height,
title, // String title,
titles); // String [] titles)
imp.getProcessor().setMinAndMax(-input_range/2, input_range/2);
String imp_title = imp.getTitle();
int width_new = scale * imp.getWidth();
int height_new = scale * imp.getHeight();
if (scale2x) {
ImageStack stack = imp.getStack();
String [] labels = new String [stack.getSize()];
for (int i = 0; i < labels.length; i++) {
labels[i] = stack.getSliceLabel(i+1);
} }
final FloatProcessor [] stackfp = new FloatProcessor[stack.getSize()];
for (int y = 0; y < icon_height; y++) { for (int i = 0; i < stackfp.length; i++) {
int py = yt + y; stackfp[i] = (FloatProcessor) stack.getProcessor(i+1);
if ((py >= 0) && (py < height)) {
for (int x = 0; x< icon_width; x++) {
int px = xl +x;
int dpix = x + y * icon_width;
int ipix = px + py*width;
if ((px >=0) && (px < width)) {
int alpha = icon[dpix][3];
if (alpha > 0) { // alpha
int dp = icon_pix[x + y * icon_width];
if (alpha == 255) {
image[ipix] = dp;
} else {
double k = alpha/255.0;
int img_pix = image[ipix];
int new_pix = 0xff000000;
for (int c = 0; c < 3; c++) {
int rgb = (img_pix >> (8 * c)) & 0xff;
rgb = (int) Math.round((1-k)*rgb + k* icon[dpix][c]);
if (rgb > 255) rgb = 255;
new_pix |= (rgb << (8*c));
} }
image[ipix] = new_pix; System.out.println("stackfp.length="+stackfp.length);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSlice = ai.getAndIncrement(); nSlice < stackfp.length; nSlice = ai.getAndIncrement()) {
stackfp[nSlice] = (FloatProcessor) stackfp[nSlice].resize(stackfp[nSlice].getWidth() * 2, stackfp[nSlice].getHeight()*2);
} }
} }
};
} }
ImageDtt.startAndJoin(threads);
stack = new ImageStack(width_new,height_new);
for (int i = 0; i < stackfp.length; i++) {
stack.addSlice(labels[i],stackfp[i]);
} }
imp = new ImagePlus(imp_title, stack); // imp.getTitle(),stack);
} }
final FloatProcessor [] float_processors = new FloatProcessor[imp.getStack().getSize()];
final ColorProcessor [] color_processors = new ColorProcessor[float_processors.length];
final String [] cp_labels = new String [imp.getStack().getSize()];
for (int i = 0; i < float_processors.length; i++) {
float_processors[i] = (FloatProcessor) imp.getStack().getProcessor(i+1);
cp_labels[i] = imp.getStack().getSliceLabel(i+1);
} }
return; ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSlice = ai.getAndIncrement(); nSlice < float_processors.length; nSlice = ai.getAndIncrement()) {
ImagePlus imp1 = new ImagePlus(cp_labels[nSlice],float_processors[nSlice]);
ImageConverter imageConverter = new ImageConverter(imp1);
imageConverter.convertToRGB();
color_processors[nSlice] = (ColorProcessor) imp1.getProcessor();
} }
public static ImagePlus generateRadarImage(
CLTParameters clt_parameters,
int annot_mode, // specify bits
QuadCLT scene,
double [][][] targets,
UasLogReader uasLogReader, // contains camera orientation (getCameraATR())
String title,
String [] key_titles, // corresponding to top targets dimension
ImagePlus imp_lwir, // all titles, one per frame
int debugLevel) {
ImageStack stack_lwir = imp_lwir.getStack();
String [] scene_titles = new String[stack_lwir.getSize()];
for (int i = 0; i < stack_lwir.getSize(); i++) {
scene_titles[i] = stack_lwir.getSliceLabel(i+1);
} }
return generateRadarImage( };
clt_parameters,
annot_mode, // int annot_mode, // specify bits
scene, // QuadCLT scene,
targets,
uasLogReader, // contains camera orientation (getCameraATR())
title,
key_titles, // corresponding to top targets dimension
scene_titles, // all titles, one per frame
debugLevel);
} }
ImageDtt.startAndJoin(threads);
public static ImagePlus generateRadarImage( ImageStack color_stack = new ImageStack(width_new,height_new);
CLTParameters clt_parameters, for (int i = 0; i < color_processors.length; i++) {
int annot_mode, // specify bits color_stack.addSlice(cp_labels[i],color_processors[i]);
QuadCLT scene, }
double [][][] targets, imp = new ImagePlus(imp_title, color_stack); // imp.getTitle(),stack);
UasLogReader uasLogReader, // contains camera orientation (getCameraATR()) final int width = imp.getProcessor().getWidth();
String title, final int height = imp.getProcessor().getHeight();
String [] key_titles, // corresponding to top targets dimension final Color fcolor = annotate_color_mono;
String [] scene_titles, // all titles, one per frame final ImageStack fstack_scenes = imp.getImageStack();
int debugLevel) { final int posX= width - scale * 119; // 521;
final int num_seq = key_titles.length; final int posY= height + scale * 1; // 513;
final int num_tiles = targets[0].length; final Font font = new Font("Monospaced", Font.PLAIN, scale * 12);
final int sensor_width = scene.getGeometryCorrection().getSensorWH()[0]; final Font font_target = new Font(font_name, font_type, scale * font_size);
final int tileSize = GPUTileProcessor.DTT_SIZE; final int nSlices = fstack_scenes.getSize();
final int tilesX = sensor_width/tileSize; if (annotate_mono) {
final double ifov = scene.getGeometryCorrection().getIFOV(); ai.set(0);
final double radar_range = clt_parameters.imp.cuas_radar_range; for (int ithread = 0; ithread < threads.length; ithread++) {
final String font_name = clt_parameters.imp.cuas_font_name; threads[ithread] = new Thread() {
final int font_size_radar = clt_parameters.imp.cuas_font_size; // 7; // public void run() {
final double font_ratio_radar = 1.2; // if 0 - will use default spacing ( ~=1.5) for (int nSlice = ai.getAndIncrement(); nSlice < nSlices; nSlice = ai.getAndIncrement()) {
String scene_title = fstack_scenes.getSliceLabel(nSlice+1);
ImageProcessor ip = fstack_scenes.getProcessor(nSlice+1);
ip.setColor(fcolor); // Color.BLUE);
ip.setFont(font);
if (annotate_transparent_mono) {
ip.drawString(scene_title, posX, posY); // transparent
} else {
ip.drawString(scene_title, posX, posY, Color.BLACK); // transparent
}
}
}
};
}
ImageDtt.startAndJoin(threads);
}
ImageStack stack = imp.getStack();
int [][] ipixels = new int [num_scenes][];
for (int i = 0; i < num_scenes; i++) {
ipixels[i] = (int[]) stack.getPixels(i+1);
}
// final int num_seq = targets60hz.length;
final int half_step0 = -(frame_step+1)/2;
final int half_step1 = frame_step + half_step0;
ai.set(0);
final AtomicInteger amax = new AtomicInteger(-1);
final int [] uas_tiles = new int[num_seq];
Arrays.fill(uas_tiles, -1);
final int [][] local_tiles = new int [num_seq][];
final int num_tiles = targets[0].length; // java.lang.NullPointerException
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
for (int nSeq = ai.getAndIncrement(); nSeq < targets.length; nSeq = ai.getAndIncrement()) {
double [][] targets_seq = targets[nSeq];
/// key - local target_id > 0
/// Key 0 - special case: tiles where UAS log data is stored (may be the same or different than detected tiles
/// value - tile index
HashMap<Integer,Integer> local_tiles_map = new HashMap<Integer,Integer>(); //
int max_ltarg = -1;
for (int ntile = 0; ntile < num_tiles; ntile++) {
double [] target = targets_seq[ntile];
if (target != null) {
if (!Double.isNaN(target[CuasMotionLMA.RSLT_FL_PX])) {
local_tiles_map.put(0, ntile); // flight log data
max_ltarg = Math.max(max_ltarg, 0);
}
if (!Double.isNaN(target[CuasMotionLMA.RSLT_GLOBAL])) {
int ltarg = (int) target[CuasMotionLMA.RSLT_GLOBAL];
max_ltarg = Math.max(max_ltarg, ltarg);
local_tiles_map.put(ltarg, ntile); // target data
}
}
}
amax.getAndAccumulate(max_ltarg, Math::max);
local_tiles[nSeq] = new int[max_ltarg+1];
Arrays.fill(local_tiles[nSeq],-1);
for (int i = 0; i <= max_ltarg; i++) if (local_tiles_map.containsKey(i)) {
local_tiles[nSeq][i] = local_tiles_map.get(i);
}
}
}
};
}
ImageDtt.startAndJoin(threads);
final int [][] ltargets_first_last = new int [amax.get()][]; // correct
for (int nseq = 0; nseq < num_seq; nseq++) if ((local_tiles[nseq] != null) && (local_tiles[nseq].length > 0)){ // no if is not needed - bug fixed
uas_tiles[nseq] = local_tiles[nseq][0];
}
for (int ltarg = 1; ltarg <= ltargets_first_last.length; ltarg++) { // 0 - for UAS log
int indx_first, indx_last;
for (indx_first = 0; (indx_first < num_seq) && ((local_tiles[indx_first].length <= ltarg ) || (local_tiles[indx_first][ltarg] < 0)); indx_first++);
if (indx_first < num_seq) {
for (indx_last = num_seq - 1; (indx_last >= 0) && ((local_tiles[indx_last].length <= ltarg ) || (local_tiles[indx_last][ltarg] < 0)); indx_last--); // Index 5 out of bounds for length 5
ltargets_first_last[ltarg-1] = new int[] {indx_first,indx_last};
}
}
for (int nscene = 0; nscene < num_scenes; nscene++) {
color_processors[nscene].setFont(font_target); // to calculate text boxes, later will need to set it for all processors
}
// mark UAS log and targets on the radar
// color_processors[0].setFont(font_target); // to calculate text boxes, later will need to set it for all processors
ai.set(0);
int [] scene_indices = getSceneIndices(
slice_titles, // String [] key_titles, // corresponding to top targets dimension
scene_titles); // String [] scene_titles) { // all titles, one per frame
// final double kpix = radar_height/radar_range;
final Rectangle full_wnd = new Rectangle(0,0,width,height);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int [] conflict_pix = new int [width * height];
ColorProcessor conflict_cp = new ColorProcessor(width, height, conflict_pix);
for (int nSeq = ai.getAndIncrement(); nSeq < (targets.length - 1); nSeq = ai.getAndIncrement()) {
Arrays.fill(conflict_pix, 0);
// for now only for targets longer that 1 series
int nscene0 = scene_indices[nSeq];
int nscene1 = scene_indices[nSeq+1];
double kscene = 1.0/(nscene1-nscene0);
// plot UAS
double [] uas_target0= null, uas_target1=null;
if ((uas_tiles[nSeq] >= 0) && (uas_tiles[nSeq+1] >= 0)) {
uas_target0= targets[nSeq][uas_tiles[nSeq]];
uas_target1= targets[nSeq+1][uas_tiles[nSeq+1]];
for (int nscene = nscene0; nscene < nscene1; nscene++) { // threads collide if <=
double uk = (nscene - nscene0) * kscene; // 0 when nscene=nscene0
double upx = interpolate(uas_target0[CuasMotionLMA.RSLT_FL_PX], uas_target1[CuasMotionLMA.RSLT_FL_PX], uk);
double upy = interpolate(uas_target0[CuasMotionLMA.RSLT_FL_PY], uas_target1[CuasMotionLMA.RSLT_FL_PY], uk);
/// double disparity = interpolate(uas_target0[CuasMotionLMA.RSLT_FL_DISP],uas_target1[CuasMotionLMA.RSLT_FL_DISP],uk);
int xc = (int) Math.round(scale * upx);
int yc = (int) Math.round(scale * upy);
int xl = xc - uaslog_width/2;
int yt = yc - uaslog_height/2;
for (int y = 0; y < uaslog_height; y++) {
int py = yt + y;
if ((py >= 0) && (py < height)) {
for (int x = 0; x< uaslog_width; x++) {
int px = xl +x;
int dpix = x + y * uaslog_width;
int ipix = px + py*width;
if ((px >=0) && (px < width)) {
int alpha = uaslog_rgba[dpix][3];
if (alpha > 0) { // alpha
int dp = uaslog_pixels[x + y * uaslog_width];
if (alpha == 255) {
ipixels[nscene][ipix] = dp;
} else {
double k = alpha/255.0;
int img_pix = ipixels[nscene][ipix];
int new_pix = 0xff000000;
for (int c = 0; c < 3; c++) {
int rgb = (img_pix >> (8 * c)) & 0xff;
rgb = (int) Math.round((1-k)*rgb + k* uaslog_rgba[dpix][c]);
if (rgb > 255) rgb = 255;
new_pix |= (rgb << (8*c));
}
ipixels[nscene][ipix] = new_pix;
}
}
}
}
}
}
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
int [] conflict_pix = new int [width * height];
ColorProcessor conflict_cp = new ColorProcessor(width, height, conflict_pix);
for (int nSeq = ai.getAndIncrement(); nSeq < (num_seq - 1); nSeq = ai.getAndIncrement()) {
int frame_center = frame0 + nSeq * frame_step;
Arrays.fill(conflict_pix, 0);
// for now only for targets longer that 1 series
int nscene0 = scene_indices[nSeq];
int nscene1 = scene_indices[nSeq+1];
double kscene = 1.0/(nscene1-nscene0);
// int get number of visible targets for this scene sequence
int num_visible = 0;
int [] target_ids = new int [local_tiles[nSeq].length]; // ltargets_first_last.length];
for (int i = 1; i < local_tiles[nSeq].length; i++) {
if ((local_tiles[nSeq][i] > 0) && (i < local_tiles[nSeq + 1].length) && (local_tiles[nSeq + 1][i] > 0)) { // visible in both this and next
num_visible++;
int ntile = local_tiles[nSeq][i]; // 1- based 0 - uas log
double [] target = targets[nSeq][ntile];
target_ids[i] = (int) target[CuasMotionLMA.RSLT_TARGET_ID]; // i was out of range
}
}
Integer [] targets_order_integer = new Integer [num_visible];
int indx = 0;
for (int i = 1; i < local_tiles[nSeq].length; i++) {
if ((local_tiles[nSeq][i] > 0) && (i < local_tiles[nSeq + 1].length) && (local_tiles[nSeq + 1][i] > 0)) { // visible in both this and next
targets_order_integer[indx++] = i;
}
}
Arrays.sort(targets_order_integer, new Comparator<Integer>() { //
@Override
public int compare(Integer lhs, Integer rhs) {
return Integer.compare(target_ids[lhs], target_ids[rhs]);
}
});
// 0-based indices, 0-based values.
final int [] targets_order = Arrays.stream(targets_order_integer).mapToInt(Integer::intValue).toArray();
// plot targets
// now target_coord is ordered from highest priority to the lowest
double [][][] target_coord = new double [local_tiles[nSeq].length-1][][]; // save centers of targets and text coordinates
Rectangle [][] annot_boxes = new Rectangle[local_tiles[nSeq].length-1][]; // order will match target_coord order
String [][] annots = new String [local_tiles[nSeq].length-1][];
double [] uas_target0= null, uas_target1=null;
if ((uas_tiles[nSeq] >= 0) && (uas_tiles[nSeq+1] >= 0)) {
uas_target0= targets[nSeq][uas_tiles[nSeq]];
uas_target1= targets[nSeq+1][uas_tiles[nSeq+1]];
}
// prepare and save annotations to later make then non-conficting
for (int iltarget = 0; iltarget < targets_order.length; iltarget ++) {
int ltarget = targets_order[iltarget]; // + 1;
if ( (local_tiles[nSeq].length > ltarget) &&
(local_tiles[nSeq+1].length > ltarget) &&
(local_tiles[nSeq][ltarget] >=0) &&
(local_tiles[nSeq+1][ltarget]>=0)) {
int ntile0 = local_tiles[nSeq ][ltarget];
int ntile1 = local_tiles[nSeq+1][ltarget];
double [] target0= targets[nSeq ][ntile0];
double [] target1= targets[nSeq+1][ntile1];
double px0 = (ntile0 % tilesX +0.5) * tileSize + target0[CuasMotionLMA.RSLT_X]; // ignoring velocities
double py0 = (ntile0 / tilesX +0.5) * tileSize + target0[CuasMotionLMA.RSLT_Y];
/// double range0= target0[CuasMotionLMA.RSLT_RANGE_LIN];
double px1 = (ntile1 % tilesX +0.5) * tileSize + target1[CuasMotionLMA.RSLT_X];
double py1 = (ntile1 / tilesX +0.5) * tileSize + target1[CuasMotionLMA.RSLT_Y];
/// double range1= target0[CuasMotionLMA.RSLT_RANGE_LIN];
/// double disparity0 = Double.NaN;
/// double disparity1 = Double.NaN;
/// double radar_x0, radar_y0, radar_x1, radar_y1;
/// boolean infinity_mode = false;
// target_coord[ltarget-1] = new double [nscene1-nscene0+1][2];
target_coord[iltarget] = new double [nscene1-nscene0+1][4];
annot_boxes[iltarget] = new Rectangle[nscene1-nscene0+1];
annots[iltarget] = new String[nscene1-nscene0+1];
int target_id = target_ids[targets_order[iltarget]];
boolean is_uas = target_id == CuasMultiSeries.TARGET_INDEX_UAS;
int icon_width = is_uas ? uas_icon_width: target_icon_width;
for (int nscene = nscene0; nscene < nscene1; nscene++) { // threads collide if <= (when drawing, here just not needed)
double k = (nscene - nscene0) * kscene; // 0 when nscene=nscene0
double px = scale * interpolate(px0, px1, k);
double py = scale * interpolate(py0, py1, k);
String annot_txt = getAnnotationText(
clt_parameters, // CLTParameters clt_parameters,
annot_mode, // int annot_mode,
annot_missing, // boolean reserve_missing_fields, // make a parameter.Reserve a line for requested but missing parameters
ntile0, // int ntile0,
ntile1, // int ntile1,
target0, // double [] target0,
target1, // double [] target1,
uas_target0, // double [] uas_target0,
uas_target1, // double [] uas_target1,
k, // double k,
camera_atr, // double [] camera_atr,
ersCorrection, // ErsCorrection ersCorrection)
Double.NaN); // double fps); // if NaN, will use default 60Hz. Used only for omegas
target_coord[iltarget][nscene-nscene0][0] = px; // null pointer
target_coord[iltarget][nscene-nscene0][1] = py;
Rectangle text_box = getStringBounds(color_processors[nscene], annot_txt, font_ratio);
// Rectangle abs_box = annot_boxes[iltarget][nscene-nscene0];
double text_left =px + icon_width/2 + space_before_text;
double text_top = py;
target_coord[iltarget][nscene-nscene0][2] = text_left;
target_coord[iltarget][nscene-nscene0][3] = text_top;
annots[iltarget][nscene-nscene0] = annot_txt;
annot_boxes[iltarget][nscene-nscene0] = text_box;
}
}
}
// print annotations
for (int iltarget = targets_order.length - 1; iltarget >=0; iltarget --) {
int target_id = target_ids[targets_order[iltarget]];
boolean is_uas = target_id == CuasMultiSeries.TARGET_INDEX_UAS;
boolean target_text_transparent = is_uas ? transparent_uas : transparent_other;
int icon_width = is_uas ? uas_icon_width: target_icon_width;
for (int nscene = nscene0; nscene < nscene1; nscene++) { // threads collide if <=
color_processors[nscene].setColor(is_uas ? selected_color: text_color);
String annot_txt=annots[iltarget][nscene-nscene0];
/*
int text_left = (int)Math.round(target_coord[iltarget][nscene-nscene0][0] + icon_width/2 + space_before_text);
int text_top = (int)Math.round(target_coord[iltarget][nscene-nscene0][1]);
*/
int text_left = (int)Math.round(target_coord[iltarget][nscene-nscene0][2]);
int text_top = (int)Math.round(target_coord[iltarget][nscene-nscene0][3]);
Rectangle abs_box = annot_boxes[iltarget][nscene-nscene0];
abs_box.x += text_left;
abs_box.y += text_top;
if (full_wnd.contains(abs_box) ) {
Color bg_color = target_text_transparent ? null : text_bg_color; // Color.BLACK;
drawString(
color_processors[nscene], // ImageProcessor ip,
annot_txt, // String txt,
text_left, // int left,
text_top, // int top,
bg_color, // Color bgColor, // null - transparent
font_ratio); // double ratio) { // NaN or 0 - standard
}
}
}
// plot icons
for (int iltarget = 0; iltarget < targets_order.length; iltarget ++) {
int target_id = target_ids[targets_order[iltarget]];
boolean is_uas = target_id == CuasMultiSeries.TARGET_INDEX_UAS;
int [] icon_pixels = is_uas ? uas_icon_pixels : target_icon_pixels;
int [][] icon_rgba = is_uas ? uas_icon_rgba : target_icon_rgba;
int icon_width = is_uas ? uas_icon_width: target_icon_width;
for (int nscene = nscene0; nscene < nscene1; nscene++) {
int ixc= (int) Math.round(target_coord[iltarget][nscene-nscene0][0]);
int iyc= (int) Math.round(target_coord[iltarget][nscene-nscene0][1]);
imprintPixelIcon(
icon_rgba, // int [][] icon,
icon_pixels, // int [] icon_pix,
icon_width, // int icon_width,
ipixels[nscene], // int [] image,
width, // int width,
ixc, // int xc,
iyc); // int yc)
}
}
}
}
};
}
ImageDtt.startAndJoin(threads);
return imp;
}
public static ColorProcessor getIconColorProcessor(
int target_type, // Target location matching UAS flight log: 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe
boolean scale2x) {
String resource_name = TARGET_ICONS[target_type][scale2x? 1 : 0];
URL resourceUrl = CuasMotion.class.getClassLoader().getResource("graphics/"+resource_name);
Path undetected_resourcePath = null;
try {
undetected_resourcePath = Paths.get(resourceUrl.toURI());
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String path = undetected_resourcePath.toString();
ColorProcessor cp = null;
try {
cp = new ColorProcessor(ImageIO.read(new File(path)));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return cp;
}
public static int [][] splitColorIcon(int [] icon){
final int [][] icon_rgba = new int [icon.length][4];
for (int i = 0; i < icon_rgba.length; i++) {
for (int s = 0; s < 4; s++) {
icon_rgba[i][s] = (icon[i] >> (8 * s)) & 0xff;
}
}
return icon_rgba;
}
public static void imprintPixelIcon(
int [][] icon,
int [] icon_pix,
int icon_width,
int [] image,
int width,
int xc,
int yc) {
int icon_height = icon.length/icon_width;
int height = image.length/width;
int xl = xc - icon_width/2;
int yt = yc - icon_height/2;
int xr = xc + icon_width/2;
int yb = yc + icon_height/2;
if ((xl < 0) || (yt < 0) || (xr >= width) || (yb >= height)) {
System.out.println("imprintPixelIcon(): outside of the window: xc="+xc+", yc="+yc+", width="+width+", height="+height);
return;
}
for (int y = 0; y < icon_height; y++) {
int py = yt + y;
if ((py >= 0) && (py < height)) {
for (int x = 0; x< icon_width; x++) {
int px = xl +x;
int dpix = x + y * icon_width;
int ipix = px + py*width;
if ((px >=0) && (px < width)) {
int alpha = icon[dpix][3];
if (alpha > 0) { // alpha
int dp = icon_pix[x + y * icon_width];
if (alpha == 255) {
image[ipix] = dp;
} else {
double k = alpha/255.0;
int img_pix = image[ipix];
int new_pix = 0xff000000;
for (int c = 0; c < 3; c++) {
int rgb = (img_pix >> (8 * c)) & 0xff;
rgb = (int) Math.round((1-k)*rgb + k* icon[dpix][c]);
if (rgb > 255) rgb = 255;
new_pix |= (rgb << (8*c));
}
image[ipix] = new_pix;
}
}
}
}
}
}
return;
}
public static ImagePlus generateRadarImage(
CLTParameters clt_parameters,
int annot_mode, // specify bits
QuadCLT scene,
double [][][] targets,
UasLogReader uasLogReader, // contains camera orientation (getCameraATR())
String title,
String [] key_titles, // corresponding to top targets dimension
ImagePlus imp_lwir, // all titles, one per frame
int debugLevel) {
ImageStack stack_lwir = imp_lwir.getStack();
String [] scene_titles = new String[stack_lwir.getSize()];
for (int i = 0; i < stack_lwir.getSize(); i++) {
scene_titles[i] = stack_lwir.getSliceLabel(i+1);
}
return generateRadarImage(
clt_parameters,
annot_mode, // int annot_mode, // specify bits
scene, // QuadCLT scene,
targets,
uasLogReader, // contains camera orientation (getCameraATR())
title,
key_titles, // corresponding to top targets dimension
scene_titles, // all titles, one per frame
debugLevel);
}
public static ImagePlus generateRadarImage(
CLTParameters clt_parameters,
int annot_mode, // specify bits
QuadCLT scene,
double [][][] targets,
UasLogReader uasLogReader, // contains camera orientation (getCameraATR())
String title,
String [] key_titles, // corresponding to top targets dimension
String [] scene_titles, // all titles, one per frame
int debugLevel) {
final int num_seq = key_titles.length;
final int num_tiles = targets[0].length;
final int sensor_width = scene.getGeometryCorrection().getSensorWH()[0];
final int tileSize = GPUTileProcessor.DTT_SIZE;
final int tilesX = sensor_width/tileSize;
final double ifov = scene.getGeometryCorrection().getIFOV();
final double radar_range = clt_parameters.imp.cuas_radar_range;
final String font_name = clt_parameters.imp.cuas_font_name;
final int font_size_radar = clt_parameters.imp.cuas_font_size; // 7; //
final double font_ratio_radar = clt_parameters.imp.cuas_font_spacing; // 1.2; // if 0 - will use default spacing ( ~=1.5)
final int font_type = clt_parameters.imp.cuas_font_type; final int font_type = clt_parameters.imp.cuas_font_type;
final Color text_color = clt_parameters.imp.cuas_text_color; final Color text_color = clt_parameters.imp.cuas_text_color;
final Color selected_color = text_color; // clt_parameters.imp.cuas_selected_color; final Color selected_color = text_color; // clt_parameters.imp.cuas_selected_color;
...@@ -5680,35 +6220,7 @@ public class CuasMotion { ...@@ -5680,35 +6220,7 @@ public class CuasMotion {
final float [][] fpixels, final float [][] fpixels,
double [][][] target_sequence, // non-overlap only if consider marked stronger tiles double [][][] target_sequence, // non-overlap only if consider marked stronger tiles
final int debugLevel) { final int debugLevel) {
/* /// String model_prefix = parentCLT.getImageName()+getParametersSuffixRslt(clt_parameters,null);
generateExtractFilterMovingTargets( // move parameters to clt_parameters
clt_parameters, // CLTParameters clt_parameters,
video_pass, // final boolean video_pass, // if clt_parameters.cuas_clean_video=true, video_pass=0 - output TIFFS, but no video. If video_pass==1 - only video with no debug
batch_mode, // final boolean batch_mode,
parentCLT, //QuadCLT parentCLT, //
fpixels, // final float [][] fpixels,
target_sequence, // double [][][] target_sequence, // non-overlap only if consider marked stronger tiles
this, // CuasMotion cuasMotion,
uasLogReader, // UasLogReader uasLogReader,
scene_titles, // String [] scene_titles, // recreate slice_titles from scene titles?
slice_titles, // String [] slice_titles,
debugLevel); // final int debugLevel)
}
public static void generateExtractFilterMovingTargets( // move parameters to clt_parameters
CLTParameters clt_parameters,
final boolean video_pass, // if clt_parameters.cuas_clean_video=true, video_pass=0 - output TIFFS, but no video. If video_pass==1 - only video with no debug
final boolean batch_mode,
QuadCLT parentCLT, //
final float [][] fpixels,
double [][][] target_sequence, // non-overlap only if consider marked stronger tiles
CuasMotion cuasMotion,
UasLogReader uasLogReader,
String [] scene_titles, // recreate slice_titles from scene titles?
String [] slice_titles,
final int debugLevel) {
*/
String model_prefix = parentCLT.getImageName()+getParametersSuffixRslt(clt_parameters,null);
boolean clean_video = clt_parameters.imp.cuas_clean_video; //true;// save video without any debug information for targets, output in TIFF files. False - same output for video and TIFFs boolean clean_video = clt_parameters.imp.cuas_clean_video; //true;// save video without any debug information for targets, output in TIFF files. False - same output for video and TIFFs
final int corr_offset = clt_parameters.imp.cuas_corr_offset; final int corr_offset = clt_parameters.imp.cuas_corr_offset;
...@@ -5865,6 +6377,7 @@ public class CuasMotion { ...@@ -5865,6 +6377,7 @@ public class CuasMotion {
ImagePlus imp_color = convertToRgbAnnotateTargets( ImagePlus imp_color = convertToRgbAnnotateTargets(
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
video_pass, // final boolean clean_pass,
input_range, // final double input_range, // 5 input_range, // final double input_range, // 5
scale2x, // boolean scale2x, scale2x, // boolean scale2x,
target_type, // final int target_type, // = 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe target_type, // final int target_type, // = 0; // 0 - unknown, 1 - known, 2 - friend, 3 - foe
...@@ -5906,8 +6419,10 @@ public class CuasMotion { ...@@ -5906,8 +6419,10 @@ public class CuasMotion {
// int annot_mode = 0xffffffbf; // int annot_mode = 0xffffffbf;
int annot_mode = clt_parameters.imp.cuas_annot_sel[CuasMotion.ANNOT_RADAR_PANE_INDX]; int annot_mode = clt_parameters.imp.cuas_annot_sel[CuasMotion.ANNOT_RADAR_PANE_INDX];
if (video_pass) { if (video_pass) {
annot_mode &= ANNOT_DEFAULTS[ANNOT_CLEAN_VIEW_INDX]; //ANNOT_CLEAN; annot_mode &= clt_parameters.imp.cuas_annot_sel[ANNOT_CLEAN_VIEW_INDX]; //ANNOT_CLEAN;
} }
System.out.println(String.format("Radar annotation mode 0x%04x (0x%04x & 0x%04x)",
annot_mode, clt_parameters.imp.cuas_annot_sel[CuasMotion.ANNOT_RADAR_PANE_INDX],clt_parameters.imp.cuas_annot_sel[ANNOT_CLEAN_VIEW_INDX]));
ImagePlus img_radar = generateRadarImage( ImagePlus img_radar = generateRadarImage(
clt_parameters, clt_parameters,
annot_mode, // -1, // int annot_mode, // specify bits annot_mode, // -1, // int annot_mode, // specify bits
......
...@@ -297,7 +297,7 @@ public class CuasMultiSeries { ...@@ -297,7 +297,7 @@ public class CuasMultiSeries {
// //
ImagePlus imp_radar = testGenerateRadarImage( ImagePlus imp_radar = testGenerateRadarImage(
clt_parameters, // CLTParameters clt_parameters, clt_parameters, // CLTParameters clt_parameters,
45, // 3, // 15, // int nser, 15, // 45, // 3, // 15, // int nser,
uasLogReader, // UasLogReader uasLogReader, // contains camera orientation (getCameraATR()) uasLogReader, // UasLogReader uasLogReader, // contains camera orientation (getCameraATR())
debugLevel); // int debugLevel) { debugLevel); // int debugLevel) {
return; return;
......
...@@ -241,6 +241,7 @@ public class CuasRanging { ...@@ -241,6 +241,7 @@ public class CuasRanging {
targets = disparity_targets; targets = disparity_targets;
System.out.println("processMovingTargetsMulti(): re-using target disparities from "+disparity_path+", generating radar mode images"); System.out.println("processMovingTargetsMulti(): re-using target disparities from "+disparity_path+", generating radar mode images");
} }
cuasMotion.setTargets(targets);
} else { } else {
cuasMotion.processMovingTargetsMulti( // will remove rendering cuasMotion.processMovingTargetsMulti( // will remove rendering
batch_mode, // final boolean batch_mode, batch_mode, // final boolean batch_mode,
...@@ -326,8 +327,8 @@ public class CuasRanging { ...@@ -326,8 +327,8 @@ public class CuasRanging {
cuasMotion.getTilesX()); // int tilesX) { cuasMotion.getTilesX()); // int tilesX) {
center_CLT.saveImagePlusInModelDirectory(imp_with_range); // ImagePlus imp) center_CLT.saveImagePlusInModelDirectory(imp_with_range); // ImagePlus imp)
} }
} else if (recalc_target_id){// if (disparity_targets == null) { } else if (recalc_target_id){// if (disparity_targets == null) { // at com.elphel.imagej.cuas.CuasMotion$46.run(CuasMotion.java:7269)
cuasMotion.recalcOmegas( cuasMotion.recalcOmegas( // does not work -
false, // boolean recalc, false, // boolean recalc,
targets, // final double [][][] target_single_in, targets, // final double [][][] target_single_in,
batch_mode, // boolean batch_mode, batch_mode, // boolean batch_mode,
......
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