Commit d531d201 authored by Andrey Filippov's avatar Andrey Filippov

merged with nc393 branch

parents 01246a62 b759e500
......@@ -2514,8 +2514,8 @@ if (PROCESS_PARAMETERS.saveSettings) saveProperties(FILE_PARAMETERS.resultsDirec
tileY = nTile /tilesX;
tileX = nTile % tilesX;
if (tileX==0) {
if (updateStatus) IJ.showStatus("Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY);
if (MASTER_DEBUG_LEVEL>2) System.out.println("Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY+" : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
if (updateStatus) IJ.showStatus("(3)Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY);
if (MASTER_DEBUG_LEVEL>2) System.out.println("(3)Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY+" : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
}
if ((tileY==yTileDebug) && (tileX==xTileDebug)) DEBUG_LEVEL=4;
......
......@@ -45,6 +45,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
......@@ -76,6 +77,7 @@ public class CalibrationHardwareInterface {
// JP46_Reader_camera JP4_INSTANCE= new JP46_Reader_camera(false);
public LaserPointers laserPointers=null;
private int masterSubCamera=0; // "master" camera index of IP in the list
private int masterPort= 0; // "master" camera port (0..3) to apply trigger to
private JP46_Reader_camera [] jp4_Instances=null;
private String [] resetURLs=null;
private String [] imageURLs=null;
......@@ -87,7 +89,8 @@ public class CalibrationHardwareInterface {
// TODO: when saving/restoring save cameraSubnet, iBaseIP, cameraIPs, so any IPs are OK through config, generate - sequential
private String cameraSubnet="192.168.0.";
private int iBaseIP=236;
private String [] cameraIPs = null;
private String [] cameraIPs = null; // since nc393 port is a part of cameraIPs[]
private int [] channelIPPort = null; // index in camareIPs (each IP/port combination) for each individual sensor
private int imgsrvPort=8081;
private String resetURLcmd="towp/save/pointers"; // advance buffer, next time will wait for the next frame acquired
// will return XML, just "trig" - 1x1 GIF
......@@ -99,6 +102,7 @@ public class CalibrationHardwareInterface {
private double lastTemperature=Double.NaN;
private int colorMode=5; // JP4
private boolean noWait= true; // when false, IRQ_SMART=3 and the frame is available only 1 frame later, when true IRQ_SMART=6, frame is available after compression end
private boolean nc393 = false;
private int debugSensorNumber=-1; // increase debug level for this particular sensor
private int JPEGquality=99; // JPEG quality
private boolean cameraAutoExposure = false;
......@@ -115,7 +119,7 @@ public class CalibrationHardwareInterface {
private double cameraRScale =1.25;
private double cameraBScale =1.5;
private double cameraGScale =1.0;
private double [] cameraExposureCorr=null; // per-camera exposure correction
private double [] cameraExposureCorr=null; // per-camera exposure correction1
private double [] cameraGainCorr = null; // per-camera gain correction;
private double [] cameraRScaleCorr = null; // per-camera R/G scale correction;
private double [] cameraBScaleCorr = null; // per-camera B/G scale correction;
......@@ -124,9 +128,10 @@ public class CalibrationHardwareInterface {
// these are initialized after being null, when the cameras are probed
private int [] cameraFrameNumber=null;
private boolean [] triggeredMode= null; // true - triggered, false - free running
private boolean [][] sensorPresent= null; // probe which sensors (of 3) are detected per system board
private boolean [][] sensorPresent= null; // probe which sensors (of 3) are detected per system board (NC393 - per board/port)
// TODO - try if skipping setting TRIG_PERIOD=0, IRQ_SMART=6 (when they are already set) will fix hanging
private int [] triggerPeriod= null;
private int [] cameraMasterPort= null;
private int [] irqSmart= null;
private int [] motorsPosition= null; // motors steps when the images were acquired (for null)
private long startTime=System.nanoTime();
......@@ -150,22 +155,29 @@ public class CalibrationHardwareInterface {
this.thisTime=this.startTime;
}
private int [][] channelMap_23_393={ // ip index, channel number, port
{0,0,3},{0,0,2},{0,0,0},{0,0,1},{1,0,3},{1,0,2},{1,0,0},{1,0,1},
{0,1,3},{0,1,2},{0,1,0},{0,1,1},{1,1,3},{1,1,2},{1,1,0},{1,1,1},
{0,2,3},{0,2,2},{0,2,0},{0,2,1},{1,2,3},{1,2,2},{1,2,0},{1,2,1},
{2,0,2},{2,0,3}};
private int [][] channelMap21={ // ip index, channel number
{0,1},{0,0},{0,2},
{1,1},{1,0},{1,2},
{2,1},{2,0},{2,2},
{3,1},{3,0},{3,2},
{4,1},{4,0},{4,2},
{5,1},{5,0},{5,2},
{6,1},{6,0},{6,2}};
{0,1,0},{0,0,0},{0,2,0},
{1,1,0},{1,0,0},{1,2,0},
{2,1,0},{2,0,0},{2,2,0},
{3,1,0},{3,0,0},{3,2,0},
{4,1,0},{4,0,0},{4,2,0},
{5,1,0},{5,0,0},{5,2,0},
{6,1,0},{6,0,0},{6,2,0}};
private int [][] channelMap1={ // ip index, channel number
// {0,-1}}; // negative channel - single camera
{0,0}}; // Try with 0
{0,0,0}}; // Try with 0
private int [][] channelMap2={ // ip index, channel number
{0,0},{0,1}};
{0,0,0},{0,1,0}};
private int [][] channelMap3={ // ip index, channel number
// {0,-1}}; // negative channel - single camera
{0,0},{1,0},{2,0}};
{0,0,0},{1,0,0},{2,0,0}};
private int [][] channelMap=null;
public int maxNumberOfThreads=100;
/**
......@@ -194,32 +206,50 @@ public class CalibrationHardwareInterface {
public int getSubChannel (int channelNumber){
return ((channelNumber>=0)&& (channelNumber<this.channelMap.length))?this.channelMap[channelNumber][1]:-1;
}
public int getSensorPort (int channelNumber){
return ((channelNumber>=0)&& (channelNumber<this.channelMap.length))?this.channelMap[channelNumber][2]:-1;
}
// not used anywhere
public int getChannel (int subCam, int subChn){
return getChannel (subCam, subChn, 0); // for compatibility with 353
}
public int getChannel (int subCam, int subChn, int port){
for (int channelNumber=0;channelNumber<this.channelMap.length;channelNumber++)
if ((this.channelMap[channelNumber][0]==subCam) && (this.channelMap[channelNumber][1]==subChn)) return channelNumber;
if ((this.channelMap[channelNumber][0]==subCam) &&
(this.channelMap[channelNumber][1]==subChn) &&
(this.channelMap[channelNumber][2]==port)) return channelNumber;
return -1;
}
private void initJP4(){
this.jp4_Instances=new JP46_Reader_camera[this.cameraIPs.length];
this.resetURLs=new String [this.cameraIPs.length];
this.imageURLs=new String [this.cameraIPs.length];
this.metaURLs= new String [this.cameraIPs.length];
this.triggerURL="http://"+this.cameraIPs[this.masterSubCamera]+":"+this.imgsrvPort+"/"+triggerURLcmd;
// this.triggerURL is already defined
// this.triggerURL="http://"+this.cameraIPs[this.masterSubCamera]+":"+(this.imgsrvPort+this.masterPort)+"/"+triggerURLcmd;
this.images= new ImagePlus[this.channelMap.length];
this.imagesIP= new ImagePlus[this.cameraIPs.length];
for (int i=0; i<this.cameraIPs.length;i++){
this.jp4_Instances[i]=new JP46_Reader_camera(false);// invisible
this.jp4_Instances[i].camera_url="http://"+this.cameraIPs[i]+":"+this.imgsrvPort+"/";
// this.jp4_Instances[i].camera_url="http://"+this.cameraIPs[i]+":"+this.imgsrvPort+"/";
this.jp4_Instances[i].camera_url="http://"+this.cameraIPs[i]+"/";
this.jp4_Instances[i].camera_img= this.imageURLcmd; // not currently used
this.jp4_Instances[i].camera_img_new=this.imageURLcmd; //"torp/wait/" will survive, only "towp/wait/" is removed for Exif re-read
this.jp4_Instances[i].ABSOLUTELY_SILENT=true;
this.resetURLs[i]="http://"+this.cameraIPs[i]+":"+this.imgsrvPort+"/"+resetURLcmd;
this.imageURLs[i]="http://"+this.cameraIPs[i]+":"+this.imgsrvPort+"/"+this.imageURLcmd;
this.metaURLs[i]= "http://"+this.cameraIPs[i]+":"+this.imgsrvPort+"/"+metaURLcmd;
// this.resetURLs[i]="http://"+this.cameraIPs[i]+":"+this.imgsrvPort+"/"+resetURLcmd;
// this.imageURLs[i]="http://"+this.cameraIPs[i]+":"+this.imgsrvPort+"/"+this.imageURLcmd;
// this.metaURLs[i]= "http://"+this.cameraIPs[i]+":"+this.imgsrvPort+"/"+metaURLcmd;
this.resetURLs[i]="http://"+this.cameraIPs[i]+"/"+resetURLcmd;
this.imageURLs[i]="http://"+this.cameraIPs[i]+"/"+this.imageURLcmd;
this.metaURLs[i]= "http://"+this.cameraIPs[i]+"/"+metaURLcmd;
this.imagesIP[i]= null;
}
for (int i=0; i<this.images.length;i++) this.images[i]= null;
}
......@@ -245,6 +275,32 @@ public class CalibrationHardwareInterface {
/**
* Initialize cameraIPs from subNet and baseIP (sequentially)
*/
private void initIPs(){
ArrayList<Integer> ip_ports_list= new ArrayList<Integer>();
for (int i=0;i<this.channelMap.length;i++) {
Integer ip_port=(this.channelMap[i][0]<<2) + this.channelMap[i][2];
if (!ip_ports_list.contains(ip_port)) ip_ports_list.add(ip_port);
}
Collections.sort(ip_ports_list);
this.cameraIPs = new String [ip_ports_list.size()];
this.channelIPPort = new int [this.channelMap.length];
for (int i = 0; i<this.cameraIPs.length; i++){
int ip_index= ip_ports_list.get(i)>>2;
int sensor_port = ip_ports_list.get(i) & 3;
this.cameraIPs[i] = this.cameraSubnet+(this.iBaseIP + ip_index) + ":"+ (this.imgsrvPort+sensor_port);
for (int j = 0; j<this.channelMap.length; j++){
if ((this.channelMap[j][0] == ip_index) && (this.channelMap[j][2] == sensor_port)) {
this.channelIPPort[j] = i;
}
}
}
this.triggerURL="http://"+this.cameraSubnet+(this.iBaseIP+this.masterSubCamera)+":"+
(this.imgsrvPort+ (this.masterPort & 3))+"/"+triggerURLcmd;
if (this.debugLevel>1) System.out.println("DEBUG393: initIPs(): this.triggerURL ="+this.triggerURL);
}
/*
//pre nc393
private void initIPs(){
if (this.debugLevel>2) System.out.println("initIPs(): this.iBaseIP=" + this.iBaseIP );
int size=0;
......@@ -252,9 +308,9 @@ public class CalibrationHardwareInterface {
size++;
this.cameraIPs=new String [size];
for (int i=0;i<size;i++) this.cameraIPs[i]=this.cameraSubnet+(this.iBaseIP+i);
this.masterSubCamera=0;
// this.masterSubCamera=0;
}
*/
/**
* Initialize default subcamera map
* @param size number of subcameras
......@@ -262,6 +318,33 @@ public class CalibrationHardwareInterface {
private void initDefaultMap(int size){
this.channelMap=new int [size][];
this.flipImages=new boolean[size];
int []port_seq={1,0,2,3};
this.masterSubCamera=0;
this.masterPort=0;
if (this.nc393){
this.imgsrvPort=2323;
this.resetURLcmd="towp/save/pointers"; // advance buffer, next time will wait for the next frame acquired
this.imageURLcmd="torp/wait/timestamp_name/bimg"; // will wait if needed. If repeated (as when reading Exif)- won't wait
this.metaURLcmd="torp/wait/meta"; // will get XML, including timestamp
if (size == 26) {
for (int i=0;i<size;i++){
this.channelMap[i]=channelMap_23_393[i].clone();
this.flipImages[i]=false;
}
this.masterSubCamera = 2;
this.masterPort=2;
} else for (int i=0;i<size;i++){
this.flipImages[i]=false;
this.channelMap[i]=new int[3];
this.channelMap[i][0]= i >> 2;
this.channelMap[i][1]= 0;
if (size <4) {
this.channelMap[i][2]= i;
} else {
this.channelMap[i][2]= port_seq[i & 3];
}
}
} else {
if (size==1) { // single camera - old lens focusing
this.channelMap[0]=channelMap1[0].clone();
this.flipImages[0]=true;
......@@ -275,7 +358,8 @@ public class CalibrationHardwareInterface {
for (int i=0;i<size;i++){
this.flipImages[i]=false;
int i0=((i>=this.channelMap3.length)?(this.channelMap3.length-1):i);
this.channelMap[i]=this.channelMap21[i0].clone();
// this.channelMap[i]=this.channelMap21[i0].clone();
this.channelMap[i]=this.channelMap3[i0].clone();
}
} else for (int i=0;i<size;i++){
this.flipImages[i]=false;
......@@ -283,10 +367,13 @@ public class CalibrationHardwareInterface {
this.channelMap[i]=this.channelMap21[i0].clone();
}
}
}
public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"cameraSubnet",this.cameraSubnet);
properties.setProperty(prefix+"iBaseIP",this.iBaseIP+"");
properties.setProperty(prefix+"masterSubCamera",this.masterSubCamera+"");
properties.setProperty(prefix+"masterPort",this.masterPort+"");
properties.setProperty(prefix+"cameraBootTimeSeconds",this.cameraBootTimeSeconds+"");
properties.setProperty(prefix+"connectionTimeoutMilliseconds",this.connectionTimeoutMilliseconds+"");
properties.setProperty(prefix+"imgsrvPort",this.imgsrvPort+"");
......@@ -298,12 +385,14 @@ public class CalibrationHardwareInterface {
for (int i=0;i<this.channelMap.length;i++) {
properties.setProperty(prefix+"channelMap_"+i+"_IPindex", this.channelMap[i][0]+"");
properties.setProperty(prefix+"channelMap_"+i+"_subchannel",this.channelMap[i][1]+"");
properties.setProperty(prefix+"channelMap_"+i+"_port", this.channelMap[i][2]+"");
properties.setProperty(prefix+"flipImages_"+i ,this.flipImages[i]?"1":"0");
}
properties.setProperty(prefix+"cameraIPs.length",this.cameraIPs.length+"");
properties.setProperty(prefix+"colorMode",this.colorMode+"");
properties.setProperty(prefix+"noWait",this.noWait+"");
properties.setProperty(prefix+"nc393",this.nc393+"");
properties.setProperty(prefix+"debugSensorNumber",this.debugSensorNumber+"");
properties.setProperty(prefix+"JPEGquality",this.JPEGquality+"");
properties.setProperty(prefix+"cameraAutoExposure",this.cameraAutoExposure+"");
......@@ -332,12 +421,42 @@ public class CalibrationHardwareInterface {
}
}
public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"channelMap.length")!=null) {
// next initializes default values, so it should be before reading them from saved properties
initDefaultMap (Integer.parseInt(properties.getProperty(prefix+"channelMap.length")));
this.flipImages=new boolean[this.channelMap.length];
for (int i=0;i<this.channelMap.length;i++) {
if (properties.getProperty(prefix+"channelMap_"+i+"_IPindex")!=null)
this.channelMap[i][0]=Integer.parseInt(properties.getProperty(prefix+"channelMap_"+i+"_IPindex"));
if (properties.getProperty(prefix+"channelMap_"+i+"_subchannel")!=null)
this.channelMap[i][1]=Integer.parseInt(properties.getProperty(prefix+"channelMap_"+i+"_subchannel"));
if (properties.getProperty(prefix+"channelMap_"+i+"_port")!=null)
this.channelMap[i][2]=Integer.parseInt(properties.getProperty(prefix+"channelMap_"+i+"_port"));
if (properties.getProperty(prefix+"flipImages_"+i)!=null)
this.flipImages[i]=(Integer.parseInt(properties.getProperty(prefix+"flipImages_"+i))>0);
}
}
int numCams=0;
if (properties.getProperty(prefix+"cameraIPs.length")!=null) {
numCams=Integer.parseInt(properties.getProperty(prefix+"cameraIPs.length"));
this.cameraIPs=new String[numCams];
for (int i=0;i<numCams;i++) {
if (properties.getProperty(prefix+"cameraIPs_"+i)!=null)
this.cameraIPs[i]=properties.getProperty(prefix+"cameraIPs_"+i);
}
}
initCamParsDefaultArrays(numCams);
if (properties.getProperty(prefix+"cameraSubnet")!=null)
this.cameraSubnet=properties.getProperty(prefix+"cameraSubnet");
if (properties.getProperty(prefix+"iBaseIP")!=null)
this.iBaseIP=Integer.parseInt(properties.getProperty(prefix+"iBaseIP"));
if (properties.getProperty(prefix+"masterSubCamera")!=null)
this.masterSubCamera=Integer.parseInt(properties.getProperty(prefix+"masterSubCamera"));
if (properties.getProperty(prefix+"masterPort")!=null)
this.masterPort=Integer.parseInt(properties.getProperty(prefix+"masterPort"));
if (properties.getProperty(prefix+"cameraBootTimeSeconds")!=null)
this.cameraBootTimeSeconds=Integer.parseInt(properties.getProperty(prefix+"cameraBootTimeSeconds"));
if (properties.getProperty(prefix+"connectionTimeoutMilliseconds")!=null)
......@@ -353,31 +472,11 @@ public class CalibrationHardwareInterface {
this.imageURLcmd=properties.getProperty(prefix+"imageURLcmd");
if (properties.getProperty(prefix+"metaURLcmd")!=null)
this.metaURLcmd=properties.getProperty(prefix+"metaURLcmd");
if (properties.getProperty(prefix+"channelMap.length")!=null) {
initDefaultMap (Integer.parseInt(properties.getProperty(prefix+"channelMap.length")));
this.flipImages=new boolean[this.channelMap.length];
for (int i=0;i<this.channelMap.length;i++) {
if (properties.getProperty(prefix+"channelMap_"+i+"_IPindex")!=null)
this.channelMap[i][0]=Integer.parseInt(properties.getProperty(prefix+"channelMap_"+i+"_IPindex"));
if (properties.getProperty(prefix+"channelMap_"+i+"_subchannel")!=null)
this.channelMap[i][1]=Integer.parseInt(properties.getProperty(prefix+"channelMap_"+i+"_subchannel"));
if (properties.getProperty(prefix+"flipImages_"+i)!=null)
this.flipImages[i]=(Integer.parseInt(properties.getProperty(prefix+"flipImages_"+i))>0);
}
}
int numCams=0;
if (properties.getProperty(prefix+"cameraIPs.length")!=null) {
numCams=Integer.parseInt(properties.getProperty(prefix+"cameraIPs.length"));
this.cameraIPs=new String[numCams];
for (int i=0;i<numCams;i++) {
if (properties.getProperty(prefix+"cameraIPs_"+i)!=null)
this.cameraIPs[i]=properties.getProperty(prefix+"cameraIPs_"+i);
// both defaults were here
}
}
initCamParsDefaultArrays(numCams);
if (properties.getProperty(prefix+"colorMode")!=null)
this.colorMode=Integer.parseInt(properties.getProperty(prefix+"colorMode"));
......@@ -387,6 +486,8 @@ public class CalibrationHardwareInterface {
this.JPEGquality=Integer.parseInt(properties.getProperty(prefix+"JPEGquality"));
if (properties.getProperty(prefix+"noWait")!=null)
this.noWait=Boolean.parseBoolean(properties.getProperty(prefix+"noWait"));
if (properties.getProperty(prefix+"nc393")!=null)
this.nc393=Boolean.parseBoolean(properties.getProperty(prefix+"nc393"));
if (properties.getProperty(prefix+"cameraAutoExposure")!=null)
this.cameraAutoExposure=Boolean.parseBoolean(properties.getProperty(prefix+"cameraAutoExposure"));
if (properties.getProperty(prefix+"cameraAutoWhiteBalance")!=null)
......@@ -438,6 +539,7 @@ public class CalibrationHardwareInterface {
}
}
initIPs(); // was missing here?
initJP4();
}
......@@ -458,23 +560,25 @@ public class CalibrationHardwareInterface {
//http://192.168.0.221/parsedit.php?title=bright-day&immediate&EXPOS=10000*0&AUTOEXP_ON=0*0&WB_EN=0*0&COLOR=1*0&GAINR=0x270a4*0&GAING=0x20000*0&GAINB=0x2999a*0&GAINGB=0x20000*0
//http://192.168.0.221/parsedit.php?immediate&TRIG&TRIG_PERIOD
GenericDialog gd = new GenericDialog(title);
gd.addCheckbox ("NC393 (unchecked - nc353)", this.nc393);
gd.addStringField ("Subnet of the cameras (3 first of the four IPv4 address ending with '.')",this.cameraSubnet,12);
gd.addNumericField("Last byte of the first sub-camera IP address)",this.iBaseIP,0);
gd.addNumericField("Camera boot time",this.cameraBootTimeSeconds,0,3,"sec");
gd.addNumericField("Network connection timeout",this.connectionTimeoutMilliseconds,0,3,"ms");
gd.addNumericField("Index (in IP table) of the master camera (used for triggering)",this.masterSubCamera,0);
gd.addNumericField("Master (used for triggering), normally lowest connected port (0..3)",this.masterPort,0);
gd.addNumericField("Image server port number)",this.imgsrvPort,0);
gd.addStringField ("Image server command to reset image buffer",this.resetURLcmd,15);
gd.addStringField ("Image server command to trigger acquisition",this.triggerURLcmd,15);
gd.addStringField ("Image server command to acquire image (waits for the new one after reset)",this.imageURLcmd,15);
gd.addStringField ("Image server command to receive XML metadata (with timestamp)",this.metaURLcmd,15);
gd.addStringField ("Image server command to reset image buffer",this.resetURLcmd,25);
gd.addStringField ("Image server command to trigger acquisition",this.triggerURLcmd,25);
gd.addStringField ("Image server command to acquire image (waits for the new one after reset)",this.imageURLcmd,25);
gd.addStringField ("Image server command to receive XML metadata (with timestamp)",this.metaURLcmd,25);
gd.addMessage("Configure each sub-camera - which IP index and channel does it use.");
if (askRegenerate) gd.addMessage("You may change number of subcameras and press REGENERATE below");
for (int i=0; i< this.channelMap.length;i++){
gd.addMessage("---------------------------------------------------------");
gd.addNumericField("Subcamera "+(i+1)+" IP index (starting from 0)", this.channelMap[i][0],0);
gd.addNumericField("Subcamera "+(i+1)+" port (0..3)", this.channelMap[i][2],0);
gd.addNumericField("Subcamera "+(i+1)+" channel (0,1 or 2)", this.channelMap[i][1],0);
gd.addCheckbox("Subcamera "+(i+1)+" - used mirror", this.flipImages[i]);
}
......@@ -487,6 +591,7 @@ public class CalibrationHardwareInterface {
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
this.nc393= gd.getNextBoolean();
this.cameraSubnet= gd.getNextString();
if (!this.cameraSubnet.endsWith(".")) this.cameraSubnet += ".";
int bip= (int) gd.getNextNumber();
......@@ -497,6 +602,8 @@ public class CalibrationHardwareInterface {
this.cameraBootTimeSeconds=(int) gd.getNextNumber();
this.connectionTimeoutMilliseconds=(int) gd.getNextNumber();
this.masterSubCamera= (int) gd.getNextNumber(); // should be after initIPs()!
this.masterPort= (int) gd.getNextNumber(); // should be after initIPs()!
this.imgsrvPort= (int) gd.getNextNumber();
this.resetURLcmd= gd.getNextString();
this.triggerURLcmd= gd.getNextString();
......@@ -504,6 +611,7 @@ public class CalibrationHardwareInterface {
this.metaURLcmd= gd.getNextString();
for (int i=0; i< this.channelMap.length;i++){
this.channelMap[i][0]=(int) gd.getNextNumber();
this.channelMap[i][2]=(int) gd.getNextNumber();
this.channelMap[i][1]=(int) gd.getNextNumber();
this.flipImages[i]= gd.getNextBoolean();
}
......@@ -557,8 +665,11 @@ public class CalibrationHardwareInterface {
public String getSerialNumber(int chn, int EEPROM_chn){
String url="http://"+this.cameraIPs[chn]+"/i2c.php?cmd=fromEEPROM0&EEPROM_chn="+EEPROM_chn;
int colon_index = this.cameraIPs[chn].indexOf(":");
int sensor_port = Integer.parseInt(this.cameraIPs[chn].substring(colon_index+1)) - this.imgsrvPort;
String ip=this.cameraIPs[chn].substring(0, colon_index);
// String url="http://"+this.cameraIPs[chn]+"/i2c.php?cmd=fromEEPROM0&EEPROM_chn="+EEPROM_chn;
String url="http://"+ip+"/i2c.php?cmd=fromEEPROM" + sensor_port+ "&EEPROM_chn="+EEPROM_chn;
Document dom=null;
String serial=null;
try {
......@@ -610,7 +721,12 @@ public class CalibrationHardwareInterface {
printTiming("=== setupCameraAcquisition()");
}
if (!this.sensorPresent[chn][0] && !this.sensorPresent[chn][1] && !this.sensorPresent[chn][2]) EEPROM_chn=0; // no 10359 - null pointer while "lens center" if first
String url="http://"+this.cameraIPs[chn]+"/i2c.php?cmd=fromEEPROM0&EEPROM_chn="+EEPROM_chn;
int colon_index = this.cameraIPs[chn].indexOf(":");
int sensor_port = Integer.parseInt(this.cameraIPs[chn].substring(colon_index+1)) - this.imgsrvPort;
String ip=this.cameraIPs[chn].substring(0, colon_index);
// String url="http://"+this.cameraIPs[chn]+"/i2c.php?cmd=fromEEPROM0&EEPROM_chn="+EEPROM_chn;
String url="http://"+ip+"/i2c.php?cmd=fromEEPROM"+ sensor_port +"&EEPROM_chn="+EEPROM_chn;
this.lastTemperature=Double.NaN;
Document dom=null;
try {
......@@ -627,7 +743,7 @@ public class CalibrationHardwareInterface {
// remove opening and closing "
if (sTemperature==null){
String msg="Could not read sensor temperature";
// IJ.showMessage("Error",msg);
// IJ.showMessage("Error",msg);
System.out.println("Warning: "+msg);
return Double.parseDouble(sTemperature);
}
......@@ -683,12 +799,15 @@ public class CalibrationHardwareInterface {
if (probeCameraState(chn)) {
numOnline++;
printTiming("===== probing channel "+chn);
boolean single_no_mux= (!this.sensorPresent[chn][0] && !this.sensorPresent[chn][1] && !this.sensorPresent[chn][2]);
if (this.debugLevel>1) System.out.println("Frame number: "+this.cameraFrameNumber[chn]+
", Trigger mode:"+(this.triggeredMode[chn]?"ex":"in")+"ternal, "+
" sensors attached:"+(this.sensorPresent[chn][0]?"1 ":"")+(this.sensorPresent[chn][1]?"2 ":"")+(this.sensorPresent[chn][2]?"3 ":"")+
((!this.sensorPresent[chn][0] && !this.sensorPresent[chn][1] && !this.sensorPresent[chn][2])?"single-sensor, no multiplexer":"")
(single_no_mux?"single-sensor, no multiplexer":"") +
(" Master port "+this.cameraMasterPort[chn])
);
for (int i=0;i<this.sensorPresent[chn].length;i++) if (this.sensorPresent[chn][i]) numSensors++;
if (single_no_mux) numSensors++;
} else {
if (this.debugLevel>1) System.out.println("Camera did not respond");
}
......@@ -700,11 +819,12 @@ public class CalibrationHardwareInterface {
public void initCameraArrays(int numChn){
if (this.debugLevel>1) System.out.println("initCameraArrays("+numChn+")");
this.cameraFrameNumber=new int[numChn];
this.triggeredMode=new boolean[numChn];
this.sensorPresent=new boolean[numChn][];
this.triggeredMode= new boolean[numChn];
this.sensorPresent= new boolean[numChn][];
// TODO - try if skipping setting TRIG_PERIOD=0, IRQ_SMART=6 (when they are already set) will fix hanging
this.triggerPeriod=new int[numChn];
this.triggerPeriod= new int[numChn];
this.irqSmart= new int[numChn];
this.cameraMasterPort= new int[numChn]; // not sure if will use it - master port for each camera:port
}
public boolean probeCameraState(
int chn){
......@@ -718,7 +838,18 @@ public class CalibrationHardwareInterface {
int timeout // ms
){
//http://192.168.0.221/parsedit.php?immediate&TRIG&TRIG_PERIOD&FRAME
String url="http://"+this.cameraIPs[chn]+"/parsedit.php?immediate&TRIG&TRIG_PERIOD&IRQ_SMART&SENS_AVAIL&FRAME";
String url;
int colon_index = this.cameraIPs[chn].indexOf(":");
int sensor_port = Integer.parseInt(this.cameraIPs[chn].substring(colon_index+1)) - this.imgsrvPort;
String ip=this.cameraIPs[chn].substring(0, colon_index);
if (this.nc393){
// url="http://"+this.cameraIPs[chn]+"/parsedit.php?immediate&TRIG&TRIG_PERIOD&SENS_AVAIL&FRAME";
url="http://"+ip+"/parsedit.php?sensor_port="+sensor_port+"&immediate&TRIG&TRIG_PERIOD&SENS_AVAIL&FRAME&TRIG_MASTER";
} else {
// url="http://"+this.cameraIPs[chn]+"/parsedit.php?immediate&TRIG&TRIG_PERIOD&IRQ_SMART&SENS_AVAIL&FRAME";
url="http://"+ip+"/parsedit.php?immediate&TRIG&TRIG_PERIOD&IRQ_SMART&SENS_AVAIL&FRAME";
}
if (this.debugLevel>1) System.out.println("url="+url);
Document dom=null;
if ((this.cameraFrameNumber==null) || ((this.cameraFrameNumber.length<(chn+1)))) initCameraArrays(chn+1);
......@@ -726,7 +857,11 @@ public class CalibrationHardwareInterface {
if ((this.triggeredMode==null) || ((this.triggeredMode.length<(chn+1)))) initCameraArrays(chn+1);
if ((this.sensorPresent==null) || ((this.sensorPresent.length<(chn+1)))) initCameraArrays(chn+1);
if ((this.triggerPeriod==null) || ((this.triggerPeriod.length<(chn+1)))) initCameraArrays(chn+1);
if (!this.nc393) {
if ((this.irqSmart==null) || ((this.irqSmart.length<(chn+1)))) initCameraArrays(chn+1);
} else {
if ((this.cameraMasterPort==null) || ((this.cameraMasterPort.length<(chn+1)))) initCameraArrays(chn+1);
}
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
......@@ -758,7 +893,12 @@ public class CalibrationHardwareInterface {
this.sensorPresent[chn]=new boolean[3];
for (int i=0;i<this.sensorPresent[chn].length;i++) this.sensorPresent[chn][i]=(sensAvail & (1<<i))!=0;
this.triggerPeriod[chn]= Integer.parseInt(((Node) (((Node) dom.getDocumentElement().getElementsByTagName("TRIG_PERIOD").item(0)).getChildNodes().item(0))).getNodeValue());
if (!this.nc393) {
this.irqSmart[chn]= Integer.parseInt(((Node) (((Node) dom.getDocumentElement().getElementsByTagName("IRQ_SMART").item(0)).getChildNodes().item(0))).getNodeValue());
this.cameraMasterPort[chn]= sensor_port;
} else {
this.cameraMasterPort[chn]= Integer.parseInt(((Node) (((Node) dom.getDocumentElement().getElementsByTagName("TRIG_MASTER").item(0)).getChildNodes().item(0))).getNodeValue());
}
this.cameraFrameNumber[chn]= Integer.parseInt(((Node) (((Node) dom.getDocumentElement().getElementsByTagName("FRAME").item(0)).getChildNodes().item(0))).getNodeValue());
} catch(MalformedURLException e){
String msg="Please check the URL:" + e.toString();
......@@ -812,6 +952,7 @@ public class CalibrationHardwareInterface {
startAndJoin(threads);
if (Double.isNaN(exposureScale)){ // full init
int nRepeat=this.setupTriggerMode?4:1;
if (this.nc393) nRepeat++; // is it needed?
for (int i=0;i<nRepeat;i++){
if (this.debugLevel>0) System.out.println((i+1)+" of "+nRepeat+": Triggering cameras to give parameters a chance to propagate");
trigger();
......@@ -845,6 +986,16 @@ public class CalibrationHardwareInterface {
}
// TODO: issue several TRIG pulses after setting parameters?
public boolean setupCameraAcquisition(int chn, double exposureScale){
int colon_index = this.cameraIPs[chn].indexOf(":");
int sensor_port = Integer.parseInt(this.cameraIPs[chn].substring(colon_index+1)) - this.imgsrvPort;
String ip=this.cameraIPs[chn].substring(0, colon_index);
boolean isMasterSubcamera = ip.equals(this.cameraSubnet+(this.iBaseIP+this.masterSubCamera));
boolean isMasterPort = (this.cameraMasterPort[chn] == sensor_port); // for 353 should always be master port
if (isMasterSubcamera && (this.cameraMasterPort[chn] != this.masterPort)){
System.out.println("Master port mismatch for camera "+ip+" (master) - parameters master port = "+
this.masterPort+", camera responded with "+this.cameraMasterPort[chn] );
}
if (this.debugLevel>1) System.out.println("DEBUG393: chn="+chn+" sensor_port="+sensor_port+" ip= "+ip+" isMasterSubcamera="+isMasterSubcamera+ " isMasterPort="+isMasterPort);
boolean exposureOnly=!Double.isNaN(exposureScale);
int minExposure=10; // usec
int maxExposure=1000000; //usec
......@@ -860,6 +1011,7 @@ public class CalibrationHardwareInterface {
int gScale= (int) (Math.round(0x10000*this.cameraGScale*this.cameraGScaleCorr[chn]));
int autoExp= this.cameraAutoExposure?1:0;
int autoWB= this.cameraAutoWhiteBalance?1:0;
String extraURL="";
if (this.cameraExtraURLCommon.length()>0){
extraURL+=(this.cameraExtraURLCommon.substring(0,1).equals("&"))?"":"&"+this.cameraExtraURLCommon;
......@@ -874,19 +1026,62 @@ public class CalibrationHardwareInterface {
if (bScale<minScale) bScale= minScale ; else if (bScale> maxScale) bScale= maxScale;
if (gScale<minScale) gScale= minScale ; else if (gScale> maxScale) gScale= maxScale;
String triggerMode=this.setupTriggerMode?(
"&TRIG_CONDITION="+(this.noCabling?(0):(this.externalTriggerCabling?"0x200000":"0x20000"))+"*0"+
String triggerMode="";
if (this.nc393) {
if (isMasterPort) {
/*
* P_TRIG_OUT (outputs):
* off: 0x00000
* external: 0x02000
* internal: 0x20000
* both: 0x22000
* P_TRIG_IN (inputs):
* off: 0x00000
* external: 0x80000
* internal: 0x08000
* both: 0x88000
*/
if (this.setupTriggerMode){
triggerMode+="&TRIG_CONDITION="+(this.noCabling?(0):(this.externalTriggerCabling?"0x80000":"0x08000"))+"*0"+
"&TRIG_OUT="+(this.noCabling?(0):(this.externalTriggerCabling?"0x02000":"0x20000"))+"*0"+
"&TRIG=4*3";
}
if ((this.triggerPeriod[chn]>1) || this.setupTriggerMode) {
triggerMode+="&TRIG_PERIOD=0*1"; // just stop it if it wasn't already, imgsrv /trig does not set it, only FPGA register
}
}
}else {
if (this.setupTriggerMode){
triggerMode+="&TRIG_CONDITION="+(this.noCabling?(0):(this.externalTriggerCabling?"0x200000":"0x20000"))+"*0"+
"&TRIG_OUT="+(this.noCabling?(0):(this.externalTriggerCabling?"0x800000":"0x80000"))+"*0"+
"&TRIG=4*3"):"";
if (this.triggerPeriod[chn]>1)triggerMode+="&TRIG_PERIOD=1*0"; // just imgsrv /trig does not set it, only FPGA register
"&TRIG=4*3";
}
if ((this.triggerPeriod[chn]>1) || this.setupTriggerMode){
triggerMode+="&TRIG_PERIOD=1*0"; // just imgsrv /trig does not set it, only FPGA register
}
}
String url="http://"+ip+"/parsedit.php?immediate";
if (this.nc393) {
url += "&sensor_port="+sensor_port;
}
String url="http://"+this.cameraIPs[chn]+"/parsedit.php?immediate";
url+="&EXPOS="+exposure+"*0"; // always
if (!exposureOnly){
if (!this.nc393) {
if (this.irqSmart[chn]!=(this.noWait?6:3)){
url+="&IRQ_SMART="+(this.noWait?6:3)+"*0";
}
url+="&COLOR="+this.colorMode+"*0"+
}
url+="&COLOR="+this.colorMode+"*"+(this.nc393?"1":"0")+
"&QUALITY="+this.JPEGquality+"*0"+
"&EXPOS="+exposure+"*0"+
"&AUTOEXP_EXP_MAX="+autoExposureMax+"*0"+
......@@ -941,9 +1136,9 @@ public class CalibrationHardwareInterface {
private boolean editSubCamerasIPs() {
GenericDialog gd = new GenericDialog("Edit IPs/hosts of the sub cameras");
GenericDialog gd = new GenericDialog("Edit IPs/hosts and ports of the sub cameras");
for (int i=0;i<this.cameraIPs.length;i++){
gd.addStringField(i+": IP address/host of the subcamera",this.cameraIPs[i],20);
gd.addStringField(i+": IP address/host:sensor port of the subcamera",this.cameraIPs[i],25);
}
WindowTools.addScrollBars(gd);
gd.showDialog();
......@@ -959,6 +1154,7 @@ public class CalibrationHardwareInterface {
public boolean editCameraSettings(String title){
GenericDialog gd = new GenericDialog("title");
gd.addCheckbox ("NC393 (unchecked - nc353)", this.nc393);
gd.addNumericField("Camera exposure",this.cameraExposure,2,8,"ms");
gd.addNumericField("Scale camera exposure for target laser detection (4 lasers)",100*this.scaleExposureForLasers,1,5,"%");
gd.addNumericField("Scale camera exposure for optical head laser detection (2 lasers)",100*this.scaleExposureForHeadLasers,1,5,"%");
......@@ -1000,6 +1196,7 @@ public class CalibrationHardwareInterface {
WindowTools.addScrollBars(gd);
gd.showDialog();
if (gd.wasCanceled()) return false;
this.nc393= gd.getNextBoolean();
this.cameraExposure= gd.getNextNumber();
this.scaleExposureForLasers= 0.01*gd.getNextNumber();
this.scaleExposureForHeadLasers=0.01*gd.getNextNumber();
......@@ -1061,7 +1258,8 @@ public class CalibrationHardwareInterface {
boolean [] IPs= new boolean[this.cameraIPs.length];
for (int i=0;i<IPs.length;i++) IPs[i]=false;
for (int i=0;i<selectCameras.length;i++) if (i<this.channelMap.length) {
IPs[this.channelMap[i][0]]=true;
// IPs[this.channelMap[i][0]]=true;
IPs[this.channelIPPort[i]] = true; // since NC393
}
return IPs;
}
......@@ -1242,7 +1440,7 @@ public class CalibrationHardwareInterface {
public void run() {
for (int ipIndex=ipIndexAtomic.getAndIncrement(); ipIndex<ipLength;ipIndex=ipIndexAtomic.getAndIncrement()){
// for (int i=0;i<this.imagesIP.length;i++){
if (debugLevel>2) System.out.println("getImages()3: ipIndex="+ipIndex+" acquireIPs.length=" +acquireIPs.length+
if (debugLevel>1/*2*/) System.out.println("getImages()3: ipIndex="+ipIndex+" acquireIPs.length=" +acquireIPs.length+
((ipIndex<acquireIPs.length)? (" acquireIPs[ipIndex]="+acquireIPs[ipIndex]):""));
if ((ipIndex<acquireIPs.length) && acquireIPs[ipIndex]) {
if (debugLevel>2) System.out.println("getImages:" + imageURLs[ipIndex] );
......@@ -1280,8 +1478,10 @@ public class CalibrationHardwareInterface {
//TODO: Multithread the next cycle (per-sensor)
final ImagePlus [] images=this.images;
final int [][] channelMap = this.channelMap;
final int [] channelIPPort = this.channelIPPort;
final AtomicInteger imageIndexAtomic = new AtomicInteger(0);
final int [] motorsPosition=this.motorsPosition;
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
......@@ -1290,7 +1490,8 @@ public class CalibrationHardwareInterface {
for (int imageIndex=imageIndexAtomic.getAndIncrement(); imageIndex<images.length;imageIndex=imageIndexAtomic.getAndIncrement())
if ((imageIndex<acquire.length) && acquire[imageIndex]){
// for (int i=0;i<this.images.length;i++) if ((i<acquire.length) && acquire[i]) {
int iIP=channelMap[imageIndex][0];
// int iIP=channelMap[imageIndex][0];
int iIP=channelIPPort[imageIndex]; // index in composite images (per ip/port)
if (sensorPresent[iIP]==null) { // system board for this channel did not respond null pointer - check cameras were detected
images[imageIndex]=null;
continue;
......@@ -1298,6 +1499,7 @@ public class CalibrationHardwareInterface {
boolean singleSensor=true;
for (int s=0;s<sensorPresent[iIP].length;s++) singleSensor&= !sensorPresent[iIP][s];
if (singleSensor){ // no 10359 multiplexor
if (debugLevel>1) System.out.println("DEBUG393: demuxing single sensor imageIndex="+imageIndex+" iIP="+iIP);
images[imageIndex]=jp4_Instance.demuxClone(imagesIP[iIP]);
} else {
int subCam=channelMap[imageIndex][1];
......@@ -1307,6 +1509,7 @@ public class CalibrationHardwareInterface {
}
// skip missing channels, then demux
for (int s=0;s<channelMap[imageIndex][1];s++) if (!sensorPresent[iIP][s]) subCam--;
if (debugLevel>1) System.out.println("DEBUG393: demuxing imageIndex="+imageIndex+" iIP="+iIP+" subCam="+subCam);
images[imageIndex]=jp4_Instance.demuxImage(imagesIP[iIP],subCam);
}
// this.images[i]=this.jp4_Instances[j].demuxImageOrClone(this.imagesIP[j],this.channelMap[i][1]);
......@@ -1331,6 +1534,7 @@ public class CalibrationHardwareInterface {
}
images[imageIndex].setProperty("channel", String.format("%02d", imageIndex));
images[imageIndex].setProperty("subcamera",""+getSubCamera(imageIndex));
images[imageIndex].setProperty("sensor_port",""+getSensorPort(imageIndex));
images[imageIndex].setProperty("subchannel", ""+getSubChannel(imageIndex));
// private int [] motorsPosition= null; // motors steps when the images were acquired (for null)
if (motorsPosition!=null) for (int m=0;m<motorsPosition.length;m++ ) {
......@@ -1425,6 +1629,9 @@ public class CalibrationHardwareInterface {
public void run() {
for (int ipIndex=ipIndexAtomic.getAndIncrement(); ipIndex<lasersIPs.length;ipIndex=ipIndexAtomic.getAndIncrement()){
long st=System.nanoTime();
if (debugLevel>1) {
System.out.println("image url["+ipIndex+"]="+imageURLs[ipIndex]);
}
laserImagesIP[fnSeqNum-1][ipIndex]=jp4_Instances[ipIndex].openURL(
imageURLs[ipIndex],
"",
......@@ -1476,6 +1683,7 @@ public class CalibrationHardwareInterface {
final boolean otherGreen=laserPointers.laserPointer.otherGreen;
final int [][] channelMap=this.channelMap;
final int [] channelIPPort = this.channelIPPort;
final ImagePlus [] images=this.images;
final boolean [] flipImages=this.flipImages;
final LaserPointers laserPointers=this.laserPointers;
......@@ -1494,7 +1702,8 @@ public class CalibrationHardwareInterface {
for (int sensorNum=sensorNumAtomic.getAndIncrement(); sensorNum<lasers.length;sensorNum=sensorNumAtomic.getAndIncrement()) // null pointer
if (lasers[sensorNum] && (images[sensorNum]!=null)){
// for (int sensorNum=0;sensorNum<lasers.length;sensorNum++) if (lasers[sensorNum] && (this.images[sensorNum]!=null)){ // lasers - here sensors to use lasers for
int iIP=channelMap[sensorNum][0];
// int iIP=channelMap[sensorNum][0];
int iIP=channelIPPort[sensorNum]; // index in composite images (per ip/port)
double saturationRed=255.0;
if (images[sensorNum].getProperty("saturation_0")!=null) saturationRed=Double.parseDouble((String)images[sensorNum].getProperty("saturation_0"));
if (scaleExposureForLasers>0) saturationRed*=scaleExposureForLasers; // scaled to reduced exposure time
......@@ -1736,7 +1945,8 @@ public class CalibrationHardwareInterface {
if (this.debugLevel>1) {
if (this.debugLevel>2) System.out.println("++++++++++++++++++ Image Properies ++++++++++++++++++++++++++++");
for (int i=0;i<this.images.length;i++) if (this.images[i]!=null) {
int j=this.channelMap[i][0];
// int j=this.channelMap[i][0];
int j=channelIPPort[i]; // sincer NC393 adder port
if (this.debugLevel>2) {
System.out.println("Image #"+i);
this.jp4_Instances[j].listImageProperties(this.images[i]);
......@@ -2914,7 +3124,7 @@ public class CalibrationHardwareInterface {
} catch (IOException e) {
String msg="Failed to write XML motor state file: "+path;
IJ.showMessage("Error",msg);
throw new IOException (msg);
extracted(msg);
}
try {
os.close();
......@@ -2940,7 +3150,7 @@ public class CalibrationHardwareInterface {
} catch (IOException e) {
String msg="Failed to read XML configuration file: "+path;
IJ.showMessage("Error",msg);
throw new IOException (msg);
extracted(msg);
}
try {
is.close();
......@@ -2958,11 +3168,14 @@ public class CalibrationHardwareInterface {
} else {
String msg="motor"+(i+1)+" is undefined in "+path+". If the file is corrupted you may delete it.";
IJ.showMessage("Error",msg);
throw new IOException (msg);
extracted(msg);
}
}
return savedPosition;
}
private void extracted(String msg) throws IOException {
throw new IOException (msg);
}
public void checkEnabled(){
if (isEnabled()) return;
GenericDialog gd = new GenericDialog("Enable motors");
......
......@@ -30,6 +30,8 @@ import ij.ImageStack;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.SwingUtilities;
public class DebayerScissors {
// showDoubleFloatArrays SDFA_INSTANCE= new showDoubleFloatArrays();
......@@ -96,7 +98,29 @@ public class DebayerScissors {
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger ai = new AtomicInteger(0);
final int numberOfKernels=tilesY*tilesX;
int indx,dx,dy,tx,ty,li;
final int [] nonOverlapSeq = new int[numberOfKernels];
int [] nextFirstFindex=new int[4];
indx = 0;
li=0;
for (dy=0;dy<2;dy++) for (dx=0;dx<2;dx++) {
for (ty=dy; ty < tilesY; ty+=2) for (tx=dx; tx < tilesX; tx+=2){
nonOverlapSeq[indx++] = ty*tilesX + tx;
}
nextFirstFindex[li++] = indx;
}
final AtomicInteger aStopIndex = new AtomicInteger(0);
final long startTime = System.nanoTime();
final AtomicInteger tilesFinishedAtomic = new AtomicInteger(1); // first finished will be 1
if (updateStatus) IJ.showStatus("Reducing sampling aliases, "+tilesY+" rows, threadsMax="+threadsMax);
if (updateStatus) System.out.println("Reducing sampling aliases, "+tilesY+" rows, threadsMax="+threadsMax);
for (li = 0; li < nextFirstFindex.length; li++){
aStopIndex.set(nextFirstFindex[li]);
if (li>0){
ai.set(nextFirstFindex[li-1]);
}
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
......@@ -114,17 +138,19 @@ public class DebayerScissors {
debayerParameters.debayerRelativeWidthRedblue, // result red/blue mask mpy by scaled default (square)
debayerParameters.debayerRelativeWidthRedblueMain, // green mask when applied to red/blue, main (center)
debayerParameters.debayerRelativeWidthRedblueClones);// green mask when applied to red/blue, clones
// for (int nTile0 = ai.getAndIncrement(); nTile0 < numberOfKernels; nTile0 = ai.getAndIncrement()) {
for (int nTile0 = ai.getAndIncrement(); nTile0 < aStopIndex.get(); nTile0 = ai.getAndIncrement()) {
for (int nTile = ai.getAndIncrement(); nTile < numberOfKernels; nTile = ai.getAndIncrement()) {
int nTile = nonOverlapSeq[nTile0];
tileY = nTile /tilesX;
tileX = nTile % tilesX;
if (tileX==0) {
if (updateStatus) IJ.showStatus("Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY);
if (globalDebugLevel>2) System.out.println("Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY+" : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
if (tileX < 2) {
int trow=(tileY+((2*(tileY & 1) + (tileX & 1))*tilesY))/4;
if (updateStatus) IJ.showStatus("Reducing sampling aliases, row "+(trow+1)+" of "+tilesY);
// System.out.println("(1)Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY+" ("+nTile+"/"+nTile0+") col="+(tileX+1));
if (globalDebugLevel>2) System.out.println("Reducing sampling aliases, row "+(trow+1)+" of "+tilesY+" : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
}
// if ((tileY==yTileDebug) && (tileX==xTileDebug)) this.debugLevel=4;
// else this.debugLevel=wasDebugLevel;
for (chn=0;chn<nChn;chn++){
extractSquareTile( pixels[chn], // source pixel array,
tile[chn], // will be filled, should have correct size before call
......@@ -149,8 +175,8 @@ public class DebayerScissors {
debayerParameters.debayerThreshold, // no high frequencies - use default uniform filter
debayerParameters.debayerGamma, // power function applied to the amplitudes before generating spectral masks
debayerParameters.debayerBonus, // scale far pixels as (1.0+bonus*r/rmax)
debayerParameters.mainToAlias,// relative main/alias amplitudes to enable lixels (i.e. 0.5 means that if alias is >0.5*main, the pixel will be masked out)
debayerParameters.debayerMaskBlur, // for both masks sigma for gaussian blur of the binary masks (<0 -do not use "scissors")
debayerParameters.mainToAlias,// relative main/alias amplitudes to enable pixels (i.e. 0.5 means that if alias is >0.5*main, the pixel will be masked out)
debayerParameters.debayerMaskBlur, // for both masks sigma for Gaussian blur of the binary masks (<0 -do not use "scissors")
debayerParameters.debayerUseScissors, // use "scissors", if false - just apply "diamond" ands "square" with DEBAYER_PARAMETERS.debayerRelativeWidthGreen and DEBAYER_PARAMETERS.debayerRelativeWidthRedblue
((tileY==yTileDebug) && (tileX==xTileDebug))?4:1);
// 1); // internal debug level ((this.debugLevel>2) && (yTile==yTile0) && (xTile==xTile0))?3:1;
......@@ -166,11 +192,13 @@ public class DebayerScissors {
fht_instance.inverseTransform(tile[chn]);
fht_instance.swapQuadrants(tile[chn]);
/* accumulate result */
/*This is synchronized method. It is possible to make threads to write to non-overlapping regions of the outPixles, but as the accumulation
* takes just small fraction of severtal FHTs, it should be OK - reasonable number of threads will spread and not "stay in line"
/*This is (now was) a synchronized method. It is possible to make threads to write to non-overlapping regions of the outPixles, but as the accumulation
* takes just small fraction of several FHTs, it should be OK - reasonable number of threads will spread and not "stay in line"
*/
accumulateSquareTile(outPixles[chn], // float pixels array to accumulate tile
//accumulateSquareTile(
nonSyncAccumulateSquareTile (
outPixles[chn], // float pixels array to accumulate tile
tile[chn], // data to accumulate to the pixels array
imgWidth, // width of pixels array
tileX*step, // left corner X
......@@ -178,22 +206,34 @@ public class DebayerScissors {
}
if ((tileY==yTileDebug) && (tileX==xTileDebug) && (SDFA_instance!=null)) SDFA_instance.showArrays (tile.clone(),debayerParameters.size,debayerParameters.size, "B00");
final int numFinished=tilesFinishedAtomic.getAndIncrement();
// final double dprogr= (1.0+numFinished)/numberOfKernels;
if (numFinished % (numberOfKernels/50+1) == 0) {
// System.out.print(numFinished);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// System.out.println(" --- "+numFinished+"("+numberOfKernels+"): "+dprogr);
IJ.showProgress(numFinished, numberOfKernels);
}
});
}
}
}
};
}
startAndJoin(threads);
// this.debugLevel=wasDebugLevel;
IJ.showProgress(tilesFinishedAtomic.get(), numberOfKernels);
}
// System.out.println("tilesFinishedAtomic.get()="+tilesFinishedAtomic.get()+", numberOfKernels="+numberOfKernels);
if (updateStatus) IJ.showStatus("Reducing sampling aliases DONE");
IJ.showProgress(1.0);
/* prepare result stack to return */
ImageStack outStack=new ImageStack(imgWidth,imgHeight);
for (chn=0;chn<nChn;chn++) {
outStack.addSlice(imageStack.getSliceLabel(chn+1), outPixles[chn]);
}
debayerEnergyWidth= (debayerEnergy!=null)?tilesX:0; // for the image to be displayed externally
// if (debayerParameters.showEnergy) {
// SDFA_INSTANCE.showArrays (debayerEnergy,tilesX,tilesY, "Debayer-Energy");
// }
if (globalDebugLevel>0) System.out.println("Reducing sampling aliases done in "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
return outStack;
}
......@@ -273,6 +313,31 @@ public class DebayerScissors {
}
}
}
void nonSyncAccumulateSquareTile(
float [] pixels, // float pixels array to accumulate tile
double [] tile, // data to accumulate to the pixels array
int width, // width of pixels array
int x0, // left corner X
int y0) { // top corner Y
int length=tile.length;
int size=(int) Math.sqrt(length);
int i,j,x,y;
int height=pixels.length/width;
int index=0;
for (i=0;i<size;i++) {
y=y0+i;
if ((y>=0) && (y<height)) {
index=i*size;
for (j=0;j<size;j++) {
x=x0+j;
if ((x>=0) && (x<width)) pixels[y*width+x]+=tile [index];
index++;
}
}
}
}
synchronized void accumulateSquareTile(
double [] pixels, // float pixels array to accumulate tile
double [] tile, // data to accumulate to the pixels array
......
......@@ -39,7 +39,7 @@ public class DenseCorrespondence {
private void disparitySweepTile (
public void disparitySweepTile ( // never used so far
int tileX,
int tileY,
CyclopeanTile [][] allCyclopeanMap,
......
......@@ -5989,6 +5989,8 @@ List calibration
imp.setProperty("channel", ""+numSensor);
imp.setProperty("comment_subcamera", "number of the subcamera with individual IP, starting with 0");
imp.setProperty("subcamera", ""+camerasInterface.getSubCamera(numSensor));
imp.setProperty("sensor_port",""+camerasInterface.getSensorPort(numSensor));
imp.setProperty("comment_subchannel", "number of the sensor port on a subcamera (0..2)");
imp.setProperty("subchannel", ""+camerasInterface.getSubChannel(numSensor));
imp.setProperty("comment_entrancePupilForward", "entrance pupil distance from the azimuth/radius/height, outwards in mm");
......
......@@ -2213,7 +2213,7 @@ public class EyesisAberrations {
public double [][][][] createPSFMap(
final MatchSimulatedPattern commonMatchSimulatedPattern, // to be cloned in threads, using common data
final ImagePlus imp_sel, // linearized Bayer mosaic image form the camera, GR/BG
final ImagePlus imp_sel, // linearized Bayer mosaic image from the camera, GR/BG
final int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent pdfKernelMap structure)
final double overexposedAllowed, // fraction of pixels OK to be overexposed
final SimulationPattern.SimulParameters simulParameters,
......
......@@ -39,6 +39,8 @@ import ij.process.ImageProcessor;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.SwingUtilities;
import loci.common.services.DependencyException;
import loci.common.services.ServiceException;
import loci.formats.FormatException;
......@@ -1712,7 +1714,44 @@ public class EyesisCorrections {
final AtomicInteger ai = new AtomicInteger(0);
final int numberOfKernels= tilesY*tilesX*nChn;
final int numberOfKernelsInChn=tilesY*tilesX;
int ichn,indx,dx,dy,tx,ty,li;
final int [] nonOverlapSeq = new int[numberOfKernels];
int [] nextFirstFindex=new int[16*nChn];
indx = 0;
li=0;
for (ichn=0;ichn<nChn;ichn++) for (dy=0;dy<4;dy++) for (dx=0;dx<4;dx++) {
for (ty=dy; ty < tilesY; ty+=4) for (tx=dx; tx < tilesX; tx+=4){
nonOverlapSeq[indx++] = ichn*numberOfKernelsInChn+ ty*tilesX + tx;
}
nextFirstFindex[li++] = indx;
}
final AtomicInteger aStopIndex = new AtomicInteger(0);
final AtomicInteger tilesFinishedAtomic = new AtomicInteger(1); // first finished will be 1
if (globalDebugLevel>1)
System.out.println("Eyesis_Corrections:convolveStackWithKernelStack :\n"+
"globalDebugLevel="+globalDebugLevel+"\n"+
"imgWidth="+imgWidth+"\n"+
"imgHeight="+imgHeight+"\n"+
"tilesX="+tilesX+"\n"+
"tilesY="+tilesY+"\n"+
"nChn="+nChn+"\n"+
"step="+step+"\n"+
"size="+size+"\n"+
"kernelSize="+kernelSize+"\n"+
"kernelWidth="+kernelWidth+"\n"+
"kernelNumHor="+kernelNumHor+"\n"+
"numberOfKernelsInChn="+numberOfKernelsInChn+"\n");
if (updateStatus) IJ.showStatus("Convolving image with kernels, "+nChn+" channels, "+tilesY+" rows");
final long startTime = System.nanoTime();
for (li = 0; li < nextFirstFindex.length; li++){
aStopIndex.set(nextFirstFindex[li]);
if (li>0){
ai.set(nextFirstFindex[li-1]);
}
// System.out.println("\n=== nextFirstFindex["+li+"] =" + nextFirstFindex[li]+" === ");
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
......@@ -1724,16 +1763,20 @@ public class EyesisCorrections {
double [] doubleKernel= new double[size * size];
int chn,tileY,tileX;
int chn0=-1;
// double debug_sum;
// int i;
// double debug_sum;
// int i;
DoubleFHT fht_instance =new DoubleFHT(); // provide DoubleFHT instance to save on initializations (or null)
for (int nTile = ai.getAndIncrement(); nTile < numberOfKernels; nTile = ai.getAndIncrement()) {
// for (int nTile0 = ai.getAndIncrement(); nTile0 < numberOfKernels; nTile0 = ai.getAndIncrement()) {
for (int nTile0 = ai.getAndIncrement(); nTile0 < aStopIndex.get(); nTile0 = ai.getAndIncrement()) {
//aStopIndex
int nTile = nonOverlapSeq[nTile0];
chn=nTile/numberOfKernelsInChn;
tileY =(nTile % numberOfKernelsInChn)/tilesX;
tileX = nTile % tilesX;
if (tileX==0) {
if (updateStatus) IJ.showStatus("Convolving image with kernels, channel "+(chn+1)+" of "+nChn+", row "+(tileY+1)+" of "+tilesY);
if (globalDebugLevel>2) System.out.println("Processing kernels, channel "+(chn+1)+" of "+nChn+", row "+(tileY+1)+" of "+tilesY+" : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
if (tileX < 4) {
int trow=(tileY+ ((tileY & 3) * tilesY))/4;
if (updateStatus) IJ.showStatus("Convolving image with kernels, channel "+(chn+1)+" of "+nChn+", row "+(trow+1)+" of "+tilesY);
if (globalDebugLevel>2) System.out.println("Processing kernels, channel "+(chn+1)+" of "+nChn+", row "+(trow+1)+" of "+tilesY+" : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
}
if (chn!=chn0) {
......@@ -1763,9 +1806,9 @@ public class EyesisCorrections {
tileY); // vertical number of kernel to extract
/* zero pad twice the original size*/
doubleKernel=extendFFTInputTo (kernel, size);
// debug_sum=0;
// for (i=0;i<doubleKernel.length;i++) debug_sum+=doubleKernel[i];
// if (globalDebugLevel>1) System.out.println("kernel sum="+debug_sum);
// debug_sum=0;
// for (i=0;i<doubleKernel.length;i++) debug_sum+=doubleKernel[i];
// if (globalDebugLevel>1) System.out.println("kernel sum="+debug_sum);
//if ((tileY==tilesY/2) && (tileX==tilesX/2)) SDFA_INSTANCE.showArrays(doubleKernel,size,size, "doubleKernel-"+chn);
/* FHT transform of the kernel */
......@@ -1779,25 +1822,45 @@ public class EyesisCorrections {
/* accumulate result */
//if ((tileY==tilesY/2) && (tileX==tilesX/2)) SDFA_INSTANCE.showArrays(outTile,size,size, "out-"+chn);
/*This is synchronized method. It is possible to make threads to write to non-overlapping regions of the outPixels, but as the accumulation
* takes just small fraction of severtal FHTs, it should be OK - reasonable number of threads will spread and not "stay in line"
* takes just small fraction of several FHTs, it should be OK - reasonable number of threads will spread and not "stay in line"
*/
accumulateSquareTile(outPixels[chn], // float pixels array to accumulate tile
// Add smart synchronization - wait only if is too far ahead. First test - no synchronization at all
//accumulateSquareTile(
// System.out.print(tileY+":"+tileX+"/"+chn+"("+nTile0+"/"+nTile+") ");
// if (tileX < 4)System.out.println();
nonSyncAccumulateSquareTile(
outPixels[chn], // float pixels array to accumulate tile
outTile, // data to accumulate to the pixels array
imgWidth, // width of pixels array
(tileX-1)*step, // left corner X
(tileY-1)*step); // top corner Y
final int numFinished=tilesFinishedAtomic.getAndIncrement();
if (numFinished % (numberOfKernels/100+1) == 0) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
IJ.showProgress(numFinished,numberOfKernels);
}
});
}
//numberOfKernels
}
}
};
}
startAndJoin(threads);
if (globalDebugLevel > 1) System.out.println("Threads done at "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
}
if (updateStatus) IJ.showStatus("Convolution DONE");
if (globalDebugLevel > 1) System.out.println("Threads done in "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
IJ.showProgress(1.0);
/* prepare result stack to return */
ImageStack outStack=new ImageStack(imgWidth,imgHeight);
for (i=0;i<nChn;i++) {
outStack.addSlice(imageStack.getSliceLabel(i+1), outPixels[i]);
}
if (globalDebugLevel > 0) System.out.println("Convolution done in "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
return outStack;
}
/* Adds zero pixels around the image, "extending canvas" */
......@@ -1928,6 +1991,32 @@ public class EyesisCorrections {
}
}
}
void nonSyncAccumulateSquareTile(
float [] pixels, // float pixels array to accumulate tile
double [] tile, // data to accumulate to the pixels array
int width, // width of pixels array
int x0, // left corner X
int y0) { // top corner Y
int length=tile.length;
int size=(int) Math.sqrt(length);
int i,j,x,y;
int height=pixels.length/width;
int index=0;
for (i=0;i<size;i++) {
y=y0+i;
if ((y>=0) && (y<height)) {
index=i*size;
for (j=0;j<size;j++) {
x=x0+j;
if ((x>=0) && (x<width)) pixels[y*width+x]+=tile [index];
index++;
}
}
}
}
synchronized void accumulateSquareTile(
double [] pixels, // float pixels array to accumulate tile
double [] tile, // data to accumulate to the pixels array
......
......@@ -3464,7 +3464,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
continue;
}
convolutionKernelStack=imp_kernels.getStack();
if (DEBUG_LEVEL>1) System.out.println("Using kernel stack "+kernelPath+" for convolution with "+result[nFile][nChn][nSubChn].getTitle());
if (DEBUG_LEVEL>1) System.out.println("(1)Using kernel stack "+kernelPath+" for convolution with "+result[nFile][nChn][nSubChn].getTitle());
stack_d= convolveStackWithKernelStack(
stack, // stack with 3 colors/slices with the image
convolutionKernelStack, // stack with 3 colors/slices convolution kernels
......@@ -3492,7 +3492,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
continue;
}
convolutionKernelStack=imp_kernels.getStack();
if (DEBUG_LEVEL>1) System.out.println("Using Gaussian stack "+kernelPath+" for convolution with "+result[nFile][nChn][nSubChn].getTitle());
if (DEBUG_LEVEL>1) System.out.println("(2)Using Gaussian stack "+kernelPath+" for convolution with "+result[nFile][nChn][nSubChn].getTitle());
stack_g= convolveStackWithKernelStack(
stack, // stack with 3 colors/slices with the image
convolutionKernelStack, // stack with 3 colors/slices convolution kernels
......@@ -3592,7 +3592,7 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
continue;
}
convolutionKernelStack=imp_kernels.getStack();
if (DEBUG_LEVEL>1) System.out.println("Using Gaussian stack "+kernelPath+" for convolution with "+result[nFile][nChn][nSubChn].getTitle());
if (DEBUG_LEVEL>1) System.out.println("(3)Using Gaussian stack "+kernelPath+" for convolution with "+result[nFile][nChn][nSubChn].getTitle());
stack_g= convolveStackWithKernelStack(
stack, // stack with 3 colors/slices with the image
convolutionKernelStack, // stack with 3 colors/slices convolution kernels
......@@ -3977,7 +3977,6 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
final int tilesY=imgHeight/step-1; // vertical number of overlapping tiles in the source image (should be expanded from the registerd one by "step" in each direction)
final int kernelWidth=kernelStack.getWidth();
final int kernelNumHor=kernelWidth/(size/2);
final int nChn=imageStack.getSize();
final float [][] outPixels=new float[nChn][length]; // GLOBAL same as input
// float [][] outPixels=new float[nChn][length]; // same as input
......@@ -3988,6 +3987,21 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
final AtomicInteger ai = new AtomicInteger(0);
final int numberOfKernels= tilesY*tilesX*nChn;
final int numberOfKernelsInChn=tilesY*tilesX;
if (MASTER_DEBUG_LEVEL>1)
System.out.println("Eyesis_Correction:convolveStackWithKernelStack :\n"+
"MASTER_DEBUG_LEVEL="+MASTER_DEBUG_LEVEL+"\n"+
"imgWidth="+imgWidth+"\n"+
"imgHeight="+imgHeight+"\n"+
"tilesX="+tilesX+"\n"+
"tilesY="+tilesY+"\n"+
"step="+step+"\n"+
"kernelSize="+kernelSize+"\n"+
"tilesX="+tilesX+"\n"+
"tilesY="+tilesY+"\n"+
"kernelWidth="+kernelWidth+"\n"+
"kernelNumHor="+kernelNumHor+"\n"+
"numberOfKernelsInChn="+numberOfKernelsInChn+"\n");
final long startTime = System.nanoTime();
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
......@@ -4153,8 +4167,8 @@ private Panel panel1,panel2,panel3,panel4,panel5,panel5a, panel6,panel7,panelPos
tileY = nTile /tilesX;
tileX = nTile % tilesX;
if (tileX==0) {
if (updateStatus) IJ.showStatus("Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY);
if (MASTER_DEBUG_LEVEL>2) System.out.println("Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY+" : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
if (updateStatus) IJ.showStatus("(2)Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY);
if (MASTER_DEBUG_LEVEL>1) System.out.println("(2)Reducing sampling aliases, row "+(tileY+1)+" of "+tilesY+" : "+IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
}
if ((tileY==yTileDebug) && (tileX==xTileDebug)) DEBUG_LEVEL=4;
......
......@@ -347,6 +347,7 @@ public class JP46_Reader_camera implements PlugIn, ActionListener {
if (demux) showImage=false;
double [] xtraExif=new double[1]; // ExposureTime
// System.out.println("imp_src is "+((imp_src!=null)?"not ":"")+"null");
try {
imp = openJpegOrGifUsingURL(url);
......
......@@ -25,10 +25,14 @@
**
*/
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
......@@ -135,11 +139,20 @@ public class PixelMapping {
if ((channel<0) || (channel>=this.sensors.length)) return -1;
return this.sensors[channel].getSubCamera();
}
/*
public int getSensorPort(int channel ){
if ((channel<0) || (channel>=this.sensors.length)) return -1;
return this.sensors[channel].getSensorPort();
}
*/
public boolean isChannelAvailable(int channel){
return (this.sensors != null) && (channel>=0) && (channel<this.sensors.length) && (this.sensors[channel]!=null);
}
/*
public int [] channelsForSubCamera(int subCamera){
if (this.sensors == null) return null;
int numChannels=0;
......@@ -149,6 +162,50 @@ public class PixelMapping {
for (int i=0;i<this.sensors.length;i++) if ((this.sensors[i]!=null) &&(this.sensors[i].subcamera==subCamera)) result[numChannels++]=i;
return result;
}
*/
// Updating for nc393. subCamera here is 0..9 for Eyesis4pi393 - 0-based index of the file, so it combines physical camera (separate IP)
// as stored in "subcamera" field of the calibration file and "sensor_port". sensor_port may start from non-0, so we need to count all combinations
public int [] channelsForSubCamera(int subCamera){
// ArrayList<ArrayList<ArrayList<Integer>>> camera_IPs = new ArrayList<ArrayList<ArrayList<Integer>>>();
ArrayList<Point> cam_port = new ArrayList<Point>();
for (int i=0;i<this.sensors.length;i++) if (this.sensors[i]!=null) {
Point cp = new Point(this.sensors[i].subcamera, this.sensors[i].sensor_port);
if (!cam_port.contains(cp)){
cam_port.add(cp);
}
}
Point [] cam_port_arr = cam_port.toArray(new Point[0]);
Arrays.sort(cam_port_arr, new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
return (o1.x>o2.x)? 1:((o1.x < o2.x)?-1:(o1.y > o2.y)? 1:((o1.y < o2.y)?-1:0));
}
});
// for (int i=0; i<cam_port_arr.length;i++){
// System.out.println("----- physical camera #"+cam_port_arr[i].x+", sensor_port="+cam_port_arr[i].y);
// }
System.out.println("----- This filename subcamera "+subCamera+": physical camera "+cam_port_arr[subCamera].x+", sensor_port "+cam_port_arr[subCamera].y);
if (subCamera >= cam_port_arr.length) {
System.out.println("Error: Subcamera "+subCamera+" > that total namera of sensor ports in the system = "+cam_port_arr.length);
return null;
}
if (this.sensors == null) return null;
int numChannels=0;
for (int i=0;i<this.sensors.length;i++) if (this.sensors[i]!=null) {
if (new Point(this.sensors[i].subcamera, this.sensors[i].sensor_port).equals(cam_port_arr[subCamera])) numChannels++;
}
int [] result=new int [numChannels];
numChannels=0;
for (int i=0;i<this.sensors.length;i++) if (this.sensors[i]!=null){
if (new Point(this.sensors[i].subcamera, this.sensors[i].sensor_port).equals(cam_port_arr[subCamera])) result[numChannels++]=i;
}
return result;
}
public void removeChannel(int channel){
if ((this.sensors != null) && (channel>=0) && (channel<this.sensors.length)) this.sensors[channel]=null;
}
......@@ -9403,6 +9460,7 @@ public class PixelMapping {
private BitSet innerMask=null;
private int []borderMask=null;
public int getNumberOfPlanes(){return this.maximums.length;}
@SuppressWarnings("unused")
public int getForegroundPlane(){return this.foregroundIndex;}
public double getPlaneDisparity (int plane){return this.maximums[plane][0];}
public void setPlaneDisparity (double disparity, int plane){this.maximums[plane][0]=disparity;}
......@@ -9441,6 +9499,7 @@ public class PixelMapping {
this.auxData=new float[n][];
for (int i=0;i<n;i++) this.auxData[i]=null;
}
@SuppressWarnings("unused")
public void resetAux(){
this.auxData=null;
}
......@@ -9448,6 +9507,7 @@ public class PixelMapping {
if (this.auxData==null) initAux(n+1);
this.auxData[n]=data;
}
@SuppressWarnings("unused")
public float [][] getAux (){
return this.auxData;
}
......@@ -9460,16 +9520,20 @@ public class PixelMapping {
this.likely=new float[this.numPlanes][];
for (int i=0;i<this.numPlanes;i++) this.likely[i]=null;
}
@SuppressWarnings("unused")
public void resetLikely(){
this.likely=null;
}
@SuppressWarnings("unused")
public void setLikely(int n, float [] data){
if (this.likely==null) initLikely();
this.likely[n]=data;
}
@SuppressWarnings("unused")
public float [][] getLikely (){
return this.likely;
}
@SuppressWarnings("unused")
public float [] getLikely (int n){
if ((this.likely==null) || (this.likely.length<=n)) return null;
return this.likely[n];
......@@ -9479,16 +9543,20 @@ public class PixelMapping {
this.unlikely=new float[this.numPlanes][];
for (int i=0;i<this.numPlanes;i++) this.unlikely[i]=null;
}
@SuppressWarnings("unused")
public void resetUnlikely(){
this.unlikely=null;
}
@SuppressWarnings("unused")
public void setUnlikely(int n, float [] data){
if (this.unlikely==null) initUnlikely();
this.unlikely[n]=data;
}
@SuppressWarnings("unused")
public float [][] getUnlikely(){
return this.unlikely;
}
@SuppressWarnings("unused")
public float [] getUnlikely(int n){
if ((this.unlikely==null) || (this.unlikely.length<=n)) return null;
return this.unlikely[n];
......@@ -9577,6 +9645,7 @@ public class PixelMapping {
* @param disparityTolerance - consider "this" as being withing disparityTolerance of disparity. NaN - do not filter by this
* @return
*/
@SuppressWarnings("unused")
public boolean [] getEnabledNonOccluded(
double disparityFG,
double disparity,
......@@ -15527,6 +15596,7 @@ public class PixelMapping {
public int channel= -1;
public int subcamera= -1;
public int subchannel=-1;
public int sensor_port=-1;
// TODO: add serial# (and temperature?)
public double azimuth; // azimuth of the lens entrance pupil center, degrees, clockwise looking from top
public double radius; // mm, distance from the rotation axis
......@@ -16094,6 +16164,9 @@ public class PixelMapping {
public int getChannel(){return this.channel;}
public int getSubChannel(){return this.subchannel;}
public int getSubCamera(){return this.subcamera;}
public int getSensorPort(){return this.sensor_port;}
public void setSensorDataFromImageStack(ImagePlus imp){
// int corrX=0,corrY=1,corrMask=2;
if (imp == null){
......@@ -16170,6 +16243,9 @@ public class PixelMapping {
// older files do not have these properties
if (imp.getProperty("subcamera")!=null) this.subcamera= Integer.parseInt((String) imp.getProperty("subcamera"));
if (imp.getProperty("subchannel")!=null) this.subchannel=Integer.parseInt((String) imp.getProperty("subchannel"));
if (imp.getProperty("sensor_port")!=null) this.sensor_port=Integer.parseInt((String) imp.getProperty("sensor_port"));
// now read the calibration data and mask
this.pixelCorrection=null;
......
/**
** -----------------------------------------------------------------------------**
** deBayerScissors.java
**
** Frequency-domain de-mosoaic filters generation
**
**
** Copyright (C) 2010 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** focus_tuning.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
** -----------------------------------------------------------------------------**
** deBayerScissors.java
**
** Frequency-domain de-mosoaic filters generation
**
**
** Copyright (C) 2010 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** focus_tuning.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
import ij.process.*;
import ij.plugin.filter.GaussianBlur;
import java.util.HashSet;
public class deBayerScissors {
public class deBayerScissors {
private PolarSpectrums pol_instace=null;
private double [][][] lopass=null;
private int size;
private double lastMidEnergy; // last midrange spectral energy
private showDoubleFloatArrays SDFA_instance; // just for debugging?
private DoubleFHT fht_instance;
private int [][] aliasMapRedBlue={
{-2,-2},{-2,-1},{-2,0},{-2,1},
{-1,-2},{-1,-1},{-1,0},{-1,1},
{ 0,-2},{ 0,-1}, { 0,1},
{ 1,-2},{ 1,-1},{ 1,0},{ 1,1}};
private int [][][][] speedTable = null;
public double getMidEnergy() {return lastMidEnergy; } // instead of the DOUBLE_DEBUG_RESULT
public deBayerScissors(
......@@ -59,11 +65,34 @@ import java.util.HashSet;
debayer_width_redblue_clones, // green mask when applied to red/blue, clones
size, // side of the square
4); // should be 4 now
int hsize=size/2;
int subpixel=4; // hardwired - when changing it will need to change alias maps
int aliasX=size/subpixel;
speedTable = new int [hsize+1][size][aliasMapRedBlue.length][3];
int i,j,nAlias,x,y;
for (i = 0;i <= hsize;i++) for (j = 0;j < size;j++) {
speedTable[i][j][0][0] = i*size+j;
speedTable[i][j][0][1] = ((size-i) % size) * size + ((size-j) % size);
for(nAlias=0;nAlias<aliasMapRedBlue.length; nAlias++) {
y = (i-aliasX*aliasMapRedBlue[nAlias][0]+size) % size;
x = (j-aliasX*aliasMapRedBlue[nAlias][1]+size) % size;
if (y > hsize) {
y = size - y;
x = (size - x) % size;
}
if (y>hsize) {
y=size-y;
x=(size-x)%size;
}
speedTable[i][j][nAlias][2]=y*size+x;
}
}
}
/* returns 2 masks (0:0 in the top left corner, match fht) [0] - for greens, [1] - for red/blue */
/* Possible improvements: - 1 make the initial green mask (or actually "fan"-like image) to have sharper ends.
2. detect periodic (line of spots) on the spectrum aplitudes (corresponds to thin lines) and use this
/* returns 2 masks (0:0 in the top left corner, match fht) [0] - for greens, [1] - for red/blue */
/* Possible improvements: - 1 make the initial green mask (or actually "fan"-like image) to have sharper ends.
2. detect periodic (line of spots) on the spectrum amplitudes (corresponds to thin lines) and use this
info to confirm this area to belong to the main spectrum */
public double [][] aliasScissors(double [] green_fht, // fht array for green, will be masked in-place
......@@ -80,7 +109,7 @@ import java.util.HashSet;
double [] red_blue_mask;
double [] green_amp=fht_instance.calculateAmplitude(green_fht);
int i,j;
/**normalize amplitudes, apply gamma */
/**normalize amplitudes, apply gamma */
double dmax=0.0;
for (i=0;i<green_amp.length;i++) if (green_amp[i]>dmax) dmax=green_amp[i];
dmax=1.0/dmax;
......@@ -114,16 +143,17 @@ import java.util.HashSet;
SDFA_instance.showArrays(green_mask_for_redblue_main, "CLONES");
}
/* Maybe here we need to unmasked (wide bandwidth) green_amp? */
red_blue_mask= calcRedBlueAliasMaskRays (green_amp, // both halves are needed ??
/* Maybe here we need to unmasked (wide bandwidth) green_amp? */
red_blue_mask= calcRedBlueAliasMaskRays (
green_amp, // both halves are needed ??
green_mask_for_redblue_main, // may be null if amp_pixels is already masked
green_mask_for_redblue_clones,
pol_instace, // initialized instance (if null - skip rays processing)
mainToAlias,// relative main/alias amplitudes to enable lixels (i.e. 0.5 means that if alias is >0.5*main, the pixel will be masked out)
mainToAlias,// relative main/alias amplitudes to enable pixels (i.e. 0.5 means that if alias is >0.5*main, the pixel will be masked out)
debayer_bonus, // scale far pixels as (1.0+bonus*r/rmax)
this_debug);// relative main/alias amplitudes to enable lixels (i.e. 0.5 means that if alias is >0.5*main, the pixel will be masked out)
this_debug);// relative main/alias amplitudes to enable pixels (i.e. 0.5 means that if alias is >0.5*main, the pixel will be masked out)
/* add double mainToAlias){// relative main/alias amplitudes to enable pixels (i.e. 0.5 means that if alias is >0.5*main, the pixel will be masked out) */
/* add double mainToAlias){// relative main/alias amplitudes to enable pixels (i.e. 0.5 means that if alias is >0.5*main, the pixel will be masked out) */
if (this_debug>3) SDFA_instance.showArrays(red_blue_mask, "RB-raw");
if (debayer_mask_blur>0) {
......@@ -134,31 +164,32 @@ import java.util.HashSet;
} else { // debayer_mask_blur<0 : use default masks
green_mask=lopass[1][0].clone(); //green_lopass.clone(); variable (wide) filter here)
red_blue_mask=lopass[1][1].clone(); //red_blue_lopass.clone();
if (!useFancyDebayer) for (i=0;i<green_mask.length;i++) { // no high-frequency componnets detected - reduce noise by extra (narrow) filtering
if (!useFancyDebayer) for (i=0;i<green_mask.length;i++) { // no high-frequency componets detected - reduce noise by extra (narrow) filtering
green_mask[i]*= lopass[0][0][i]; // *= green_lopass[i];
red_blue_mask[i]*=lopass[0][1][i]; // *=red_blue_lopass[i];
}
}
/* Swap quadrants in the masks to match FHT arrays (0:0 in the top left corner) */
/* Swap quadrants in the masks to match FHT arrays (0:0 in the top left corner) */
fht_instance.swapQuadrants(green_mask);
fht_instance.swapQuadrants(red_blue_mask);
/* return both masks */
/* return both masks */
double [][] result =new double [2][];
result[0]= green_mask;
result[1]= red_blue_mask;
// if (this_debug>3) SDFA_instance.showArrays(result, "before_norm_masks");
// if (this_debug>3) SDFA_instance.showArrays(result, "before_norm_masks");
/* normalize masks to have exactly 1.0 at 0:0 - it can be reduced by blurring */
/* normalize masks to have exactly 1.0 at 0:0 - it can be reduced by blurring */
for (i=0;i<result.length;i++) {
dmax=1.0/result[i][0];
for (j=0;j<result[i].length;j++) result[i][j]*=dmax;
}
// if (this_debug>3) SDFA_instance.showArrays(result, "masks");
// if (this_debug>3) SDFA_instance.showArrays(result, "masks");
return result;
}
public double [] calcRedBlueAliasMaskRays (double [] green_amp, // both halves are needed ??
public double [] calcRedBlueAliasMaskRays (
double [] green_amp, // both halves are needed ??
double [] green_mask, // may be null if amp_pixels is already masked
double [] green_mask_clones, // mask (more inclusive than just green_mask) to be used with clones
PolarSpectrums pol_instace, // initialized instance (if null - skip rays processing)
......@@ -169,28 +200,26 @@ import java.util.HashSet;
int length=green_amp.length;
int size = (int) Math.sqrt(length);
int hsize=size/2;
int subpixel=4; // hardwired - when changing it will need to change alias maps
int aliasX=size/subpixel;
int i,j,index,index_back,x,y;
// int subpixel=4; // hardwired - when changing it will need to change alias maps
// int aliasX=size/subpixel;
int i,j,index,index_back; //,x,y;
double [] amp= green_amp.clone();
double [] amp_clones=green_amp.clone();
if (green_mask!=null) for (i=0;i<amp.length;i++) amp[i]*=green_mask[i];
if (green_mask_clones!=null) for (i=0;i<amp_clones.length;i++) amp_clones[i]*=green_mask_clones[i];
double [] mask= new double [length];
for (i=0;i<length;i++) mask[i]=0.0;
/* Combine into mask by comparing pixels[] from the zero and 7 aliases */
/* Combine into mask by comparing pixels[] from the zero and 7 aliases */
double d;
int nAlias;
int [][] aliasMapRedBlue={{-2,-2},{-2,-1},{-2,0},{-2,1},
/*
int [][] aliasMapRedBlue={
{-2,-2},{-2,-1},{-2,0},{-2,1},
{-1,-2},{-1,-1},{-1,0},{-1,1},
{ 0,-2},{ 0,-1}, { 0,1},
{ 1,-2},{ 1,-1},{ 1,0},{ 1,1}};
/* int [][] aliasMap={{-1,-1},{-1,0},{-1,1},
{ 0,-1}, { 0,1},
{ 1,-1},{ 1,0},{ 1,1}};*/
/* First step - mask out all the pixels where at least one of the alias amplitude is above the main one */
// First step - mask out all the pixels where at least one of the alias amplitude is above the main one
if (this_debug>2) SDFA_instance.showArrays(amp.clone(), "amp");
if (this_debug>2) SDFA_instance.showArrays(amp_clones, "amp_clones");
......@@ -201,7 +230,7 @@ import java.util.HashSet;
if (d>0.0) {
mask[index]=1.0;
mask[index_back]=1.0;
// isGreater=true;
// isGreater=true;
for(nAlias=0;nAlias<aliasMapRedBlue.length; nAlias++) {
y=(i-aliasX*aliasMapRedBlue[nAlias][0]+size) % size;
x=(j-aliasX*aliasMapRedBlue[nAlias][1]+size) % size;
......@@ -214,31 +243,80 @@ import java.util.HashSet;
mask[index_back]=-1.0;
break;
}
}
}
}
*/
/*
speedTable = new int [hsize][size][aliasMapRedBlue.length][3];
int i,j,nAlias,x,y;
for (i=0;i<=hsize;i++) for (j=0;j<size;j++) {
speedTable[i][j][0][0] = i*size+j;
speedTable[i][j][0][1] = ((size-i) % size) * size + ((size-j) % size);
for(nAlias=0;nAlias<aliasMapRedBlue.length; nAlias++) {
y = (i-aliasX*aliasMapRedBlue[nAlias][0]+size) % size;
x = (j-aliasX*aliasMapRedBlue[nAlias][1]+size) % size;
if (y > hsize) {
y = size - y;
x = (size - x) % size;
}
if (y>hsize) {
y=size-y;
x=(size-x)%size;
}
speedTable[i][j][nAlias][2]=y*size+x;
}
}
*/
// First step - mask out all the pixels where at least one of the alias amplitude is above the main one
if (this_debug>2) SDFA_instance.showArrays(amp.clone(), "amp");
if (this_debug>2) SDFA_instance.showArrays(amp_clones, "amp_clones");
for (i=0;i<=hsize;i++) for (j=0;j<size;j++) {
index = speedTable[i][j][0][0]; // i*size+j;
index_back = speedTable[i][j][0][1]; //((size-i) % size) * size + ((size-j) % size);
d=amp[index]*mainToAlias;
if (d>0.0) {
mask[index]=1.0;
mask[index_back]=1.0;
for(nAlias=0;nAlias<aliasMapRedBlue.length; nAlias++) {
if (amp_clones[speedTable[i][j][nAlias][2]]>d) {
mask[index]=-1.0;
mask[index_back]=-1.0;
break;
}
}
}
}
// End of replacement code
if (this_debug>2) SDFA_instance.showArrays(mask, "mask");
if (pol_instace==null) return mask;
/* Now apply mask to amplitudes and use ray processing (same as with greens)*/
/* Now apply mask to amplitudes and use ray processing (same as with greens)*/
for (i=0;i<amp.length;i++) amp[i]*=mask[i];
if (this_debug>2) SDFA_instance.showArrays(amp, "amp-mask");
double [] polar_amp=pol_instace.cartesianToPolar(amp);
if (this_debug>2) SDFA_instance.showArrays(polar_amp.clone(),pol_instace.getWidth(),pol_instace.getHeight(), "RB-polar-amp");
double k= bonus/pol_instace.getWidth();
for (i=0;i<pol_instace.getHeight();i++) for (j=0;j<pol_instace.getWidth();j++) polar_amp[i*pol_instace.getWidth()+j]*=1.0+k*j;
int width = pol_instace.getWidth();
int height = pol_instace.getHeight();
if (this_debug>2) SDFA_instance.showArrays(polar_amp.clone(),width, height, "RB-polar-amp");
double k= bonus/width;
for (i=0;i<pol_instace.getHeight();i++) for (j = 0; j < width; j++) polar_amp[i * width + j]*=1.0+k*j;
double [] polar_mask_pixels=pol_instace.genPolarRedBlueMask(polar_amp,0); // 0 - just 1.0/0.0, 1 - "analog"
double [] cart_mask_pixels= pol_instace.polarToCartesian (polar_mask_pixels,size,0.0);
if (this_debug>2) {
SDFA_instance.showArrays(polar_amp, pol_instace.getWidth(),pol_instace.getHeight(), "RB-amp-bonus");
SDFA_instance.showArrays(polar_mask_pixels,pol_instace.getWidth(),pol_instace.getHeight(), "pRBm");
SDFA_instance.showArrays(cart_mask_pixels,size,size, "cRBm");
SDFA_instance.showArrays(polar_amp, width, height, "RB-amp-bonus");
SDFA_instance.showArrays(polar_mask_pixels, width, height, "pRBm");
SDFA_instance.showArrays(cart_mask_pixels, size, size, "cRBm");
}
if (this_debug>2) {
double [] polar_mask_pixels1=pol_instace.genPolarRedBlueMask(polar_amp,1);
double [] cart_mask_pixels1= pol_instace.polarToCartesian (polar_mask_pixels1,size,0.0);
SDFA_instance.showArrays(polar_mask_pixels1,pol_instace.getWidth(),pol_instace.getHeight(), "pRBm1");
SDFA_instance.showArrays(cart_mask_pixels1,size,size, "cRBm1");
SDFA_instance.showArrays(polar_mask_pixels1, width, height, "pRBm1");
SDFA_instance.showArrays(cart_mask_pixels1, size, size, "cRBm1");
}
return cart_mask_pixels;
......@@ -370,13 +448,13 @@ import java.util.HashSet;
return cosMask;
}
// temporary using float implementation in ImageJ - re-write to directly use double [] arrays
// temporary using float implementation in ImageJ - re-write to directly use double [] arrays
public void blurDouble(double[] pixels,
int width,
double sigmaX,
double sigmaY,
double precision) {
// public void blurFloat(red_blue_mask, DEBAYER_MASK_BLUR, DEBAYER_MASK_BLUR, 0.01);
// public void blurFloat(red_blue_mask, DEBAYER_MASK_BLUR, DEBAYER_MASK_BLUR, 0.01);
int i;
int height = pixels.length/width;
float [] fpixels=new float [pixels.length];
......@@ -386,7 +464,7 @@ import java.util.HashSet;
gb.blurFloat(fp, sigmaX, sigmaY, precision);
for (i=0;i<pixels.length;i++) pixels[i]=fpixels[i];
}
/* ====================================================== */
/* ====================================================== */
public class PolarSpectrums {
public int radius=0;
public int iRadiusPlus1; // number of radius steps
......@@ -395,7 +473,7 @@ import java.util.HashSet;
public double rStep;
public int size;
public int length;
// Make them private later, after debugging
// Make them private later, after debugging
private int [][] polar2CartesianIndices; // for each polar angle/radius (angle*iRadiusPlus1+radius) - 4 interpolation corners (0:0, dx:0, 0:dy, dx:dy), the first (0:0) being the closest to the polar point
private double [][] polar2CartesianFractions; // a pair of dx, dy for interpolations (used with ) polar2CartesianIndices[][]]
private int [][] cartesian2PolarIndices; // each per-pixel array is a list of indices in polar array pointing to this cell (may be empty)
......@@ -411,8 +489,10 @@ import java.util.HashSet;
double [] polPixels=new double[iRadiusPlus1*(iAngle+1)];
int i;
for (i=0;i<polPixels.length;i++) {
polPixels[i]=(1-polar2CartesianFractions[i][1])*( (1-polar2CartesianFractions[i][0])*cartPixels[polar2CartesianIndices[i][0]] + polar2CartesianFractions[i][0]*cartPixels[polar2CartesianIndices[i][1]])+
polar2CartesianFractions[i][1] *( (1-polar2CartesianFractions[i][0])*cartPixels[polar2CartesianIndices[i][2]] + polar2CartesianFractions[i][0]*cartPixels[polar2CartesianIndices[i][3]]) ;
polPixels[i]=(1-polar2CartesianFractions[i][1])*( (1-polar2CartesianFractions[i][0])*cartPixels[polar2CartesianIndices[i][0]] +
polar2CartesianFractions[i][0]*cartPixels[polar2CartesianIndices[i][1]])+
polar2CartesianFractions[i][1] *( (1-polar2CartesianFractions[i][0])*cartPixels[polar2CartesianIndices[i][2]] +
polar2CartesianFractions[i][0]*cartPixels[polar2CartesianIndices[i][3]]) ;
}
return polPixels;
}
......@@ -496,12 +576,14 @@ import java.util.HashSet;
return genPolarMask(polarAmps,0,mode);
}
public double [] genPolarRedBlueMask(double [] polarAmps, // polar array of amplitude values, <0 - stop
int mode){ // result mode - 0: output mask as 0/1, 1 -output proportional, positive - pass, negative - rejected
return genPolarMask(polarAmps,1,mode);
public double [] genPolarRedBlueMask(
double [] polarAmps, // polar array of amplitude values, <0 - stop
int mode)
{ // result mode - 0: output mask as 0/1, 1 -output proportional, positive - pass, negative - rejected
return genPolarMask(polarAmps, 1, mode);
}
// **** Seems to be most time-critical ****
public double [] genPolarMask(double [] polarAmps, // polar array of amplitude values, <0 - stop
int type, // 0 - green, 1 red/blue
int mode){ // result mode - 0: output mask as 0/1, 1 -output proportional, positive - pass, negative - rejected
......@@ -529,11 +611,14 @@ import java.util.HashSet;
step++;
/* add polar point index */
newVal=good?step:-step;
// index=iMax*iRadiusPlus1+rayLength[iMax]; // rayLength[iMax] should point to a new cell (with intMap[]==0) may ommit - set in the end of the loop and before the loop?
intMap[index]=newVal;
if (sameCartesian[index]!=null) for (i=0;i<sameCartesian[index].length;i++) intMap[sameCartesian[index][i]]=newVal;
if (sameCartesian[index]!=null)
for (i=0;i<sameCartesian[index].length;i++)
intMap[sameCartesian[index][i]]=newVal;
/* add aliases of point index (as negative values) */
if ((good) &&(polarMap[index]!=null)) for (i=0;i<polarMap[index].length;i++) intMap[polarMap[index][i]]=-step;
if ((good) &&(polarMap[index]!=null))
for (i=0;i<polarMap[index].length;i++)
intMap[polarMap[index][i]]=-step;
/* update ray lengths and status */
max=-1.0;
iMax=-1;
......@@ -543,13 +628,13 @@ import java.util.HashSet;
lastIndex=base+iRadiusPlus1; // first in the next row
while ((l<lastIndex) && (intMap[l]>0)) l++;
rayLength[ia]=l-base; // last "good" ( >0 and in the same row)
if ((l==lastIndex) || (intMap[l]<0) || (polarAmps[l]<0.0) ) rayOpen[ia]=false;
else {
if (polarAmps[l]>max) {
if ((l==lastIndex) || (intMap[l]<0) || (polarAmps[l]<0.0) )
rayOpen[ia]=false;
else if (polarAmps[l]>max) {
max=polarAmps[l];
iMax=ia;
}
}
}
if (iMax>=0) {
rayLength[iMax]++;
......@@ -573,8 +658,9 @@ import java.util.HashSet;
}
return result;
}
public PolarSpectrums(
int isize, // size of the square array, centar is at size/2, size/2, only top half+line will be used
int isize, // size of the square array, center is at size/2, size/2, only top half+line will be used
double fullAngle, // i.e. Math.PI, 2*Math.PI
int maxRadius, // width of the polar array - should be <= size/2-2
double outerStep, // maximal step in pixels on the maxRadius for 1 angular step (i.e. 0.5)
......
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