Commit 16b4ece4 authored by Andrey Filippov's avatar Andrey Filippov

Got GPU-processed LWIR images

parent 75da8cbd
...@@ -42,8 +42,20 @@ public class ThermalColor { ...@@ -42,8 +42,20 @@ public class ThermalColor {
double k = out_range/PALETTE_RANGE; double k = out_range/PALETTE_RANGE;
double value = (v-min)/(max-min) * (this.palette.length - 1); double value = (v-min)/(max-min) * (this.palette.length - 1);
int ivalue = (int) (value); int ivalue = (int) (value);
if (ivalue < 0) return getRGB((float) min); // this.palette[0]; if (ivalue < 0) {
if (ivalue >= (this.palette.length -1)) return getRGB((float) max); // this.palette[this.palette.length -1]; // return getRGB((float) min); // this.palette[0];
return new float[] {
(float) this.palette[0][0],
(float) this.palette[0][1],
(float) this.palette[0][2]};
}
if (ivalue >= (this.palette.length -1)) {
// return getRGB((float) max); // this.palette[this.palette.length -1];
return new float[] {
(float) this.palette[this.palette.length -1][0],
(float) this.palette[this.palette.length -1][1],
(float) this.palette[this.palette.length -1][2]};
}
double a = (value-ivalue); // 0..1 double a = (value-ivalue); // 0..1
float [] rslt = { float [] rslt = {
(float) (k*((1 - a) * this.palette[ivalue][0] + a * this.palette[ivalue+1][0])), (float) (k*((1 - a) * this.palette[ivalue][0] + a * this.palette[ivalue+1][0])),
......
...@@ -1346,7 +1346,7 @@ public class GpuQuad{ // quad camera description ...@@ -1346,7 +1346,7 @@ public class GpuQuad{ // quad camera description
cuCtxSynchronize(); cuCtxSynchronize();
// Call the kernel function // Call the kernel function
cuLaunchKernel(this.gpuTileProcessor.GPU_IMCLT_ALL_kernel, cuLaunchKernel(this.gpuTileProcessor.GPU_IMCLT_ALL_kernel, // failed with LWIR
GridFullWarps[0], GridFullWarps[1], GridFullWarps[2], // Grid dimension GridFullWarps[0], GridFullWarps[1], GridFullWarps[2], // Grid dimension
ThreadsFullWarps[0], ThreadsFullWarps[1],ThreadsFullWarps[2],// Block dimension ThreadsFullWarps[0], ThreadsFullWarps[1],ThreadsFullWarps[2],// Block dimension
0, null, // Shared memory size and stream (shared - only dynamic, static is in code) 0, null, // Shared memory size and stream (shared - only dynamic, static is in code)
...@@ -2231,7 +2231,8 @@ public class GpuQuad{ // quad camera description ...@@ -2231,7 +2231,8 @@ public class GpuQuad{ // quad camera description
copyD2H.dstPitch = width_in_bytes; copyD2H.dstPitch = width_in_bytes;
copyD2H.WidthInBytes = width_in_bytes; copyD2H.WidthInBytes = width_in_bytes;
copyD2H.Height = 3 * height; // /2; // copyD2H.Height = 3 * height; // /2;
copyD2H.Height = num_colors * height; // /2;
cuMemcpy2D(copyD2H); // run copy cuMemcpy2D(copyD2H); // run copy
......
...@@ -2260,12 +2260,34 @@ public class QuadCLT extends QuadCLTCPU { ...@@ -2260,12 +2260,34 @@ public class QuadCLT extends QuadCLTCPU {
int out_width = gpuQuad.getImageWidth() + gpuQuad.getDttSize(); int out_width = gpuQuad.getImageWidth() + gpuQuad.getDttSize();
int out_height = gpuQuad.getImageHeight() + gpuQuad.getDttSize(); int out_height = gpuQuad.getImageHeight() + gpuQuad.getDttSize();
if (isLwir() && colorProcParameters.lwir_autorange) {
double rel_low = colorProcParameters.lwir_low;
double rel_high = colorProcParameters.lwir_high;
if (!Double.isNaN(getLwirOffset())) {
rel_low -= getLwirOffset();
rel_high -= getLwirOffset();
}
double [] cold_hot = autorange(
iclt_fimg, // iclt_data, // double [][][] iclt_data, // [iQuad][ncol][i] - normally only [][2][] is non-null
rel_low, // double hard_cold,// matches data, DC (this.lwir_offset) subtracted
rel_high, // double hard_hot, // matches data, DC (this.lwir_offset) subtracted
colorProcParameters.lwir_too_cold, // double too_cold, // pixels per image
colorProcParameters.lwir_too_hot, // double too_hot, // pixels per image
1024); // int num_bins)
if (cold_hot != null) {
if (!Double.isNaN(getLwirOffset())) {
cold_hot[0] += getLwirOffset();
cold_hot[1] += getLwirOffset();
}
}
setColdHot(cold_hot); // will be used for shifted images and for texture tiles
}
/* Prepare 4-channel images*/ /* Prepare 4-channel images*/
ImagePlus [] imps_RGB = new ImagePlus[iclt_fimg.length]; ImagePlus [] imps_RGB = new ImagePlus[iclt_fimg.length];
for (int ncam = 0; ncam < iclt_fimg.length; ncam++) { for (int ncam = 0; ncam < iclt_fimg.length; ncam++) {
String title=String.format("%s%s-%02d",image_name, sAux(), ncam); String title=String.format("%s%s-%02d",image_name, sAux(), ncam);
imps_RGB[ncam] = linearStackToColor( // probably no need to separate and process the second half with quadCLT_aux imps_RGB[ncam] = linearStackToColor( // probably no need to separate and process the second half with quadCLT_aux (!)
clt_parameters, clt_parameters,
colorProcParameters, colorProcParameters,
rgbParameters, rgbParameters,
...@@ -2284,22 +2306,22 @@ public class QuadCLT extends QuadCLTCPU { ...@@ -2284,22 +2306,22 @@ public class QuadCLT extends QuadCLTCPU {
if (clt_parameters.gen_chn_img || only4slice) { // save and show 4-slice image if (clt_parameters.gen_chn_img || only4slice) { // save and show 4-slice image
// combine to a sliced color image // combine to a sliced color image
// assuming total number of images to be multiple of 4 int [] slice_seq = {0,1,3,2}; //clockwise
// int [] slice_seq = {0,1,3,2}; //clockwise if (imps_RGB.length > 4) {
// int [] slice_seq = new int[gpuQuad.getNumCams()]; //results.length]; slice_seq = new int [imps_RGB.length];
int [] slice_seq = new int[getNumSensors()]; //results.length]; for (int i = 0; i < slice_seq.length; i++) {
for (int i = 0; i < slice_seq.length; i++) { slice_seq[i] = i;
slice_seq[i] = i ^ ((i >> 1) & 1); // 0,1,3,2,4,5,7,6, ... }
} }
int width = imps_RGB[0].getWidth(); int width = imps_RGB[0].getWidth();
int height = imps_RGB[0].getHeight(); int height = imps_RGB[0].getHeight();
ImageStack array_stack=new ImageStack(width,height); ImageStack array_stack=new ImageStack(width,height);
for (int i = 0; i<slice_seq.length; i++){ for (int i = 0; i<slice_seq.length; i++){
/// if (imps_RGB[slice_seq[i]] != null) { /// if (imps_RGB[slice_seq[i]] != null) {
array_stack.addSlice("port_"+slice_seq[i], imps_RGB[slice_seq[i]].getProcessor().getPixels()); array_stack.addSlice("port_"+slice_seq[i], imps_RGB[slice_seq[i]].getProcessor().getPixels());
/// } else { /// } else {
/// array_stack.addSlice("port_"+slice_seq[i], results[slice_seq[i]].getProcessor().getPixels()); /// array_stack.addSlice("port_"+slice_seq[i], results[slice_seq[i]].getProcessor().getPixels());
/// } /// }
} }
ImagePlus imp_stack = new ImagePlus(image_name+sAux()+"-SHIFTED-D"+clt_parameters.disparity, array_stack); ImagePlus imp_stack = new ImagePlus(image_name+sAux()+"-SHIFTED-D"+clt_parameters.disparity, array_stack);
imp_stack.getProcessor().resetMinAndMax(); imp_stack.getProcessor().resetMinAndMax();
......
...@@ -5829,7 +5829,7 @@ public class QuadCLTCPU { ...@@ -5829,7 +5829,7 @@ public class QuadCLTCPU {
debugLevel); debugLevel);
for (int ii = 0; ii < clt_set.length; ii++) clt[chn*4+ii] = clt_set[ii]; for (int ii = 0; ii < clt_set.length; ii++) clt[chn*4+ii] = clt_set[ii];
} }
/* /*
if (debugLevel > 0){ if (debugLevel > 0){
sdfa_instance.showArrays(clt, sdfa_instance.showArrays(clt,
tilesX*image_dtt.transform_size, tilesX*image_dtt.transform_size,
...@@ -5837,7 +5837,7 @@ public class QuadCLTCPU { ...@@ -5837,7 +5837,7 @@ public class QuadCLTCPU {
true, true,
results[iQuad].getTitle()+"-CLT-D"+clt_parameters.disparity); results[iQuad].getTitle()+"-CLT-D"+clt_parameters.disparity);
} }
*/ */
} }
iclt_data[iQuad] = new double [clt_data[iQuad].length][]; iclt_data[iQuad] = new double [clt_data[iQuad].length][];
...@@ -5858,12 +5858,12 @@ public class QuadCLTCPU { ...@@ -5858,12 +5858,12 @@ public class QuadCLTCPU {
(tilesY + 0) * image_dtt.transform_size, (tilesY + 0) * image_dtt.transform_size,
true, true,
results[iQuad].getTitle()+"-ICLT-RGB-D"+clt_parameters.disparity); results[iQuad].getTitle()+"-ICLT-RGB-D"+clt_parameters.disparity);
*/ */
} // end of generating shifted channel images } // end of generating shifted channel images
// Use iclt_data here for LWIR autorange // Use iclt_data here for LWIR autorange
// if (colorProcParameters.isLwir() && colorProcParameters.lwir_autorange) { // if (colorProcParameters.isLwir() && colorProcParameters.lwir_autorange) {
if (isLwir() && colorProcParameters.lwir_autorange) { if (isLwir() && colorProcParameters.lwir_autorange) {
double rel_low = colorProcParameters.lwir_low; double rel_low = colorProcParameters.lwir_low;
double rel_high = colorProcParameters.lwir_high; double rel_high = colorProcParameters.lwir_high;
...@@ -5887,25 +5887,25 @@ public class QuadCLTCPU { ...@@ -5887,25 +5887,25 @@ public class QuadCLTCPU {
setColdHot(cold_hot); // will be used for shifted images and for texture tiles setColdHot(cold_hot); // will be used for shifted images and for texture tiles
} }
ImagePlus [] imps_RGB = new ImagePlus[clt_data.length]; // all 16 here ImagePlus [] imps_RGB = new ImagePlus[clt_data.length]; // all 16 here
for (int iQuad = 0; iQuad < clt_data.length; iQuad++){ for (int iQuad = 0; iQuad < clt_data.length; iQuad++){
if (!clt_parameters.gen_chn_img) continue; if (!clt_parameters.gen_chn_img) continue;
String title=String.format("%s%s-%02d",image_name, sAux(), iQuad); String title=String.format("%s%s-%02d",image_name, sAux(), iQuad);
imps_RGB[iQuad] = linearStackToColor( imps_RGB[iQuad] = linearStackToColor(
clt_parameters, clt_parameters,
colorProcParameters, colorProcParameters,
rgbParameters, rgbParameters,
title, // String name, title, // String name,
"-D"+clt_parameters.disparity, //String suffix, // such as disparity=... "-D"+clt_parameters.disparity, //String suffix, // such as disparity=...
toRGB, toRGB,
!this.correctionsParameters.jpeg, // boolean bpp16, // 16-bit per channel color mode for result !this.correctionsParameters.jpeg, // boolean bpp16, // 16-bit per channel color mode for result
!batch_mode, // true, // boolean saveShowIntermediate, // save/show if set globally !batch_mode, // true, // boolean saveShowIntermediate, // save/show if set globally
false, // boolean saveShowFinal, // save/show result (color image?) false, // boolean saveShowFinal, // save/show result (color image?)
iclt_data[iQuad], iclt_data[iQuad],
tilesX * image_dtt.transform_size, tilesX * image_dtt.transform_size,
tilesY * image_dtt.transform_size, tilesY * image_dtt.transform_size,
(scaleExposures == null) ? 1.0 : scaleExposures[iQuad], // double scaleExposure, // is it needed? (scaleExposures == null) ? 1.0 : scaleExposures[iQuad], // double scaleExposure, // is it needed?
debugLevel ); debugLevel );
} }
if (clt_parameters.gen_chn_img) { if (clt_parameters.gen_chn_img) {
...@@ -5924,7 +5924,7 @@ public class QuadCLTCPU { ...@@ -5924,7 +5924,7 @@ public class QuadCLTCPU {
if (imps_RGB[slice_seq[i]] != null) { if (imps_RGB[slice_seq[i]] != null) {
array_stack.addSlice("port_"+slice_seq[i], imps_RGB[slice_seq[i]].getProcessor().getPixels()); array_stack.addSlice("port_"+slice_seq[i], imps_RGB[slice_seq[i]].getProcessor().getPixels());
} else { // not used in lwir } else { // not used in lwir
/// array_stack.addSlice("port_"+slice_seq[i], results[slice_seq[i]].getProcessor().getPixels()); /// array_stack.addSlice("port_"+slice_seq[i], results[slice_seq[i]].getProcessor().getPixels());
} }
} }
ImagePlus imp_stack = new ImagePlus(image_name+sAux()+"-SHIFTED-D"+clt_parameters.disparity, array_stack); ImagePlus imp_stack = new ImagePlus(image_name+sAux()+"-SHIFTED-D"+clt_parameters.disparity, array_stack);
...@@ -5943,7 +5943,7 @@ public class QuadCLTCPU { ...@@ -5943,7 +5943,7 @@ public class QuadCLTCPU {
} }
if (clt_parameters.gen_4_img) { if (clt_parameters.gen_4_img) {
// Save as individual JPEG images in the model directory // Save as individual JPEG images in the model directory
String x3d_path = getX3dDirectory(); String x3d_path = getX3dDirectory();
for (int sub_img = 0; sub_img < imps_RGB.length; sub_img++){ for (int sub_img = 0; sub_img < imps_RGB.length; sub_img++){
EyesisCorrections.saveAndShow( EyesisCorrections.saveAndShow(
imps_RGB[sub_img], imps_RGB[sub_img],
...@@ -5968,7 +5968,7 @@ public class QuadCLTCPU { ...@@ -5968,7 +5968,7 @@ public class QuadCLTCPU {
} }
} }
if (texture_tiles != null){ if (texture_tiles != null){
if (clt_parameters.show_nonoverlap){// not used in lwir if (clt_parameters.show_nonoverlap){// not used in lwir
...@@ -6623,106 +6623,164 @@ public class QuadCLTCPU { ...@@ -6623,106 +6623,164 @@ public class QuadCLTCPU {
double hard_cold, double hard_cold,
double hard_hot, double hard_hot,
int num_bins) { int num_bins) {
int [] hist = new int [num_bins]; int [] hist = new int [num_bins];
double k = num_bins / (hard_hot - hard_cold); double k = num_bins / (hard_hot - hard_cold);
for (double d:data) { for (double d:data) {
int bin = (int) ((d - hard_cold)*k); int bin = (int) ((d - hard_cold)*k);
if (bin < 0) bin = 0; if (bin < 0) bin = 0;
else if (bin >= num_bins) bin = (num_bins -1); else if (bin >= num_bins) bin = (num_bins -1);
hist[bin]++; hist[bin]++;
} }
return hist; return hist;
} }
public int [] addHist( // USED in lwir public int [] getLwirHistogram( // USED in lwir
int [] this_hist, float [] data,
int [] other_hist) { double hard_cold,
for (int i = 0; i < this_hist.length; i++) { double hard_hot,
this_hist[i] += other_hist[i]; int num_bins) {
} int [] hist = new int [num_bins];
return this_hist; double k = num_bins / (hard_hot - hard_cold);
} for (double d:data) {
// get low/high (soft min/max) from the histogram int bin = (int) ((d - hard_cold)*k);
// returns value between 0.0 (low histogram limit and 1.0 - high histgram limit if (bin < 0) bin = 0;
public double getMarginFromHist( // USED in lwir else if (bin >= num_bins) bin = (num_bins -1);
int [] hist, // histogram hist[bin]++;
double cumul_val, // cummulative number of items to be ignored }
boolean high_marg) { // false - find low margin(output ~0.0) , true - find high margin (output ~1.0) return hist;
int n = 0; }
int n_prev = 0; public int [] addHist( // USED in lwir
int bin; int [] this_hist,
double s = 1.0 / hist.length; int [] other_hist) {
double v; for (int i = 0; i < this_hist.length; i++) {
if (high_marg) { this_hist[i] += other_hist[i];
for (bin = hist.length -1; bin >= 0; bin--) { }
n_prev = n; return this_hist;
n+= hist[bin]; }
if (n > cumul_val) break; // get low/high (soft min/max) from the histogram
} // returns value between 0.0 (low histogram limit and 1.0 - high histgram limit
if (n <= cumul_val) { // not used in lwir public double getMarginFromHist( // USED in lwir
v = 0.0; // cumul_val > total number of samples int [] hist, // histogram
} else { double cumul_val, // cummulative number of items to be ignored
v = s* (bin + 1 - (cumul_val - n_prev)/(n - n_prev)); boolean high_marg) { // false - find low margin(output ~0.0) , true - find high margin (output ~1.0)
} int n = 0;
int n_prev = 0;
int bin;
double s = 1.0 / hist.length;
double v;
if (high_marg) {
for (bin = hist.length -1; bin >= 0; bin--) {
n_prev = n;
n+= hist[bin];
if (n > cumul_val) break;
}
if (n <= cumul_val) { // not used in lwir
v = 0.0; // cumul_val > total number of samples
} else {
v = s* (bin + 1 - (cumul_val - n_prev)/(n - n_prev));
}
} else {
for (bin = 0; bin < hist.length; bin++) {
n_prev = n;
n+= hist[bin];
if (n > cumul_val) break;
}
if (n <= cumul_val) { // not used in lwir
v = 1.0; // cumul_val > total number of samples
} else { } else {
for (bin = 0; bin < hist.length; bin++) { v = s * (bin + (cumul_val - n_prev)/(n - n_prev));
n_prev = n; }
n+= hist[bin];
if (n > cumul_val) break;
}
if (n <= cumul_val) { // not used in lwir
v = 1.0; // cumul_val > total number of samples
} else {
v = s * (bin + (cumul_val - n_prev)/(n - n_prev));
}
}
return v;
}
public double [] autorange( // USED in lwir
double [][][] iclt_data, // [iQuad][ncol][i] - normally only [][2][] is non-null
double hard_cold,// matches data, DC (this.lwir_offset) subtracted
double hard_hot, // matches data, DC (this.lwir_offset) subtracted
double too_cold, // pixels per image
double too_hot, // pixels per image
int num_bins) {
int ncol;
for (ncol = 0; ncol < iclt_data[0].length; ncol++) {
if (iclt_data[0][ncol] != null) break;
}
too_cold *= iclt_data.length;
too_hot *= iclt_data.length;
int [] hist = null;
for (int iQuad = 0; iQuad < iclt_data.length; iQuad++) {
int [] this_hist = getLwirHistogram(
iclt_data[iQuad][ncol], // double [] data,
hard_cold,
hard_hot,
num_bins);
if (hist == null) {
hist = this_hist;
} else {
addHist(
hist,
this_hist);
}
}
double [] rel_lim = {
getMarginFromHist(
hist, // histogram
too_cold, // double cumul_val, // cummulative number of items to be ignored
false), // boolean high_marg)
getMarginFromHist(
hist, // histogram
too_hot, // double cumul_val, // cummulative number of items to be ignored
true)}; // boolean high_marg)
double [] abs_lim = {
rel_lim[0] * (hard_hot - hard_cold) + hard_cold,
rel_lim[1] * (hard_hot - hard_cold) + hard_cold,
};
return abs_lim;
} }
return v;
}
public double [] autorange( // USED in lwir
double [][][] iclt_data, // [iQuad][ncol][i] - normally only [][2][] is non-null
double hard_cold,// matches data, DC (this.lwir_offset) subtracted
double hard_hot, // matches data, DC (this.lwir_offset) subtracted
double too_cold, // pixels per image
double too_hot, // pixels per image
int num_bins) {
int ncol;
for (ncol = 0; ncol < iclt_data[0].length; ncol++) {
if (iclt_data[0][ncol] != null) break;
}
too_cold *= iclt_data.length;
too_hot *= iclt_data.length;
int [] hist = null;
for (int iQuad = 0; iQuad < iclt_data.length; iQuad++) {
int [] this_hist = getLwirHistogram(
iclt_data[iQuad][ncol], // double [] data,
hard_cold,
hard_hot,
num_bins);
if (hist == null) {
hist = this_hist;
} else {
addHist(
hist,
this_hist);
}
}
double [] rel_lim = {
getMarginFromHist(
hist, // histogram
too_cold, // double cumul_val, // cummulative number of items to be ignored
false), // boolean high_marg)
getMarginFromHist(
hist, // histogram
too_hot, // double cumul_val, // cummulative number of items to be ignored
true)}; // boolean high_marg)
double [] abs_lim = {
rel_lim[0] * (hard_hot - hard_cold) + hard_cold,
rel_lim[1] * (hard_hot - hard_cold) + hard_cold,
};
return abs_lim;
}
public double [] autorange( // USED in lwir
float [][][] iclt_data, // [iQuad][ncol][i] - normally only [][2][] is non-null
double hard_cold,// matches data, DC (this.lwir_offset) subtracted
double hard_hot, // matches data, DC (this.lwir_offset) subtracted
double too_cold, // pixels per image
double too_hot, // pixels per image
int num_bins) {
int ncol;
for (ncol = 0; ncol < iclt_data[0].length; ncol++) {
if (iclt_data[0][ncol] != null) break;
}
too_cold *= iclt_data.length;
too_hot *= iclt_data.length;
int [] hist = null;
for (int iQuad = 0; iQuad < iclt_data.length; iQuad++) {
int [] this_hist = getLwirHistogram(
iclt_data[iQuad][ncol], // double [] data,
hard_cold,
hard_hot,
num_bins);
if (hist == null) {
hist = this_hist;
} else {
addHist(
hist,
this_hist);
}
}
double [] rel_lim = {
getMarginFromHist(
hist, // histogram
too_cold, // double cumul_val, // cummulative number of items to be ignored
false), // boolean high_marg)
getMarginFromHist(
hist, // histogram
too_hot, // double cumul_val, // cummulative number of items to be ignored
true)}; // boolean high_marg)
double [] abs_lim = {
rel_lim[0] * (hard_hot - hard_cold) + hard_cold,
rel_lim[1] * (hard_hot - hard_cold) + hard_cold,
};
return abs_lim;
}
// float // float
...@@ -6747,9 +6805,14 @@ public class QuadCLTCPU { ...@@ -6747,9 +6805,14 @@ public class QuadCLTCPU {
// convert to ImageStack of 3 slices // convert to ImageStack of 3 slices
String [] sliceNames = {"red", "blue", "green"}; String [] sliceNames = {"red", "blue", "green"};
int green_index = 2; int green_index = 2;
float [][] rbg_in = {iclt_data[0],iclt_data[1],iclt_data[2]}; float [][] rbg_in;
if (iclt_data.length >= 3) {
rbg_in = new float [][] {iclt_data[0],iclt_data[1],iclt_data[2]}; // RBG or LWIR CPU
} else {
rbg_in = new float [][] {iclt_data[0],iclt_data[0],iclt_data[0]}; // after LWIR/GPU
green_index = 0;
}
float [] alpha = null; // (0..1.0) float [] alpha = null; // (0..1.0)
// float [][] rgb_in = {iclt_data[0],iclt_data[1],iclt_data[2]};
if (iclt_data.length > 3) alpha = iclt_data[3]; if (iclt_data.length > 3) alpha = iclt_data[3];
if (isLwir()) { if (isLwir()) {
String [] rgb_titles = {"red","green","blue"}; String [] rgb_titles = {"red","green","blue"};
......
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