@@ -76,6 +77,7 @@ public class CalibrationHardwareInterface {
...
@@ -76,6 +77,7 @@ public class CalibrationHardwareInterface {
// JP46_Reader_camera JP4_INSTANCE= new JP46_Reader_camera(false);
// JP46_Reader_camera JP4_INSTANCE= new JP46_Reader_camera(false);
publicLaserPointerslaserPointers=null;
publicLaserPointerslaserPointers=null;
privateintmasterSubCamera=0;// "master" camera index of IP in the list
privateintmasterSubCamera=0;// "master" camera index of IP in the list
privateintmasterPort=0;// "master" camera port (0..3) to apply trigger to
privateJP46_Reader_camera[]jp4_Instances=null;
privateJP46_Reader_camera[]jp4_Instances=null;
privateString[]resetURLs=null;
privateString[]resetURLs=null;
privateString[]imageURLs=null;
privateString[]imageURLs=null;
...
@@ -87,7 +89,8 @@ public class CalibrationHardwareInterface {
...
@@ -87,7 +89,8 @@ public class CalibrationHardwareInterface {
// TODO: when saving/restoring save cameraSubnet, iBaseIP, cameraIPs, so any IPs are OK through config, generate - sequential
// TODO: when saving/restoring save cameraSubnet, iBaseIP, cameraIPs, so any IPs are OK through config, generate - sequential
privateStringcameraSubnet="192.168.0.";
privateStringcameraSubnet="192.168.0.";
privateintiBaseIP=236;
privateintiBaseIP=236;
privateString[]cameraIPs=null;
privateString[]cameraIPs=null;// since nc393 port is a part of cameraIPs[]
privateint[]channelIPPort=null;// index in camareIPs (each IP/port combination) for each individual sensor
privateintimgsrvPort=8081;
privateintimgsrvPort=8081;
privateStringresetURLcmd="towp/save/pointers";// advance buffer, next time will wait for the next frame acquired
privateStringresetURLcmd="towp/save/pointers";// advance buffer, next time will wait for the next frame acquired
// will return XML, just "trig" - 1x1 GIF
// will return XML, just "trig" - 1x1 GIF
...
@@ -99,6 +102,7 @@ public class CalibrationHardwareInterface {
...
@@ -99,6 +102,7 @@ public class CalibrationHardwareInterface {
privatedoublelastTemperature=Double.NaN;
privatedoublelastTemperature=Double.NaN;
privateintcolorMode=5;// JP4
privateintcolorMode=5;// JP4
privatebooleannoWait=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
privatebooleannoWait=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
privatebooleannc393=false;
privateintdebugSensorNumber=-1;// increase debug level for this particular sensor
privateintdebugSensorNumber=-1;// increase debug level for this particular sensor
privateintJPEGquality=99;// JPEG quality
privateintJPEGquality=99;// JPEG quality
privatebooleancameraAutoExposure=false;
privatebooleancameraAutoExposure=false;
...
@@ -115,7 +119,7 @@ public class CalibrationHardwareInterface {
...
@@ -115,7 +119,7 @@ public class CalibrationHardwareInterface {
@@ -610,45 +721,50 @@ public class CalibrationHardwareInterface {
...
@@ -610,45 +721,50 @@ public class CalibrationHardwareInterface {
printTiming("=== setupCameraAcquisition()");
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
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
// for (int sensorNum=0;sensorNum<lasers.length;sensorNum++) if (lasers[sensorNum] && (this.images[sensorNum]!=null)){ // lasers - here sensors to use lasers for
// for (int sensorNum=0;sensorNum<lasers.length;sensorNum++) if (lasers[sensorNum] && (this.images[sensorNum]!=null)){ // lasers - here sensors to use lasers for
intiIP=channelMap[sensorNum][0];
// int iIP=channelMap[sensorNum][0];
intiIP=channelIPPort[sensorNum];// index in composite images (per ip/port)
DoubleFHTfht_instance=newDoubleFHT();// provide DoubleFHT instance to save on initializations (or null)
showDoubleFloatArraysSDFA_instance=null;// just for debugging?
deBayerScissorsdebayer_instance=newdeBayerScissors(debayerParameters.size,// size of the square array, centar is at size/2, size/2, only top half+line will be used
deBayerScissorsdebayer_instance=newdeBayerScissors(debayerParameters.size,// size of the square array, centar is at size/2, size/2, only top half+line will be used
debayerParameters.polarStep,// maximal step in pixels on the maxRadius for 1 angular step (i.e. 0.5)
debayerParameters.polarStep,// maximal step in pixels on the maxRadius for 1 angular step (i.e. 0.5)
debayerParameters.debayerRelativeWidthGreen,// result green mask mpy by scaled default (diamond)
debayerParameters.debayerRelativeWidthGreen,// result green mask mpy by scaled default (diamond)
debayerParameters.debayerRelativeWidthRedblue,// result red/blue mask mpy by scaled default (square)
debayerParameters.debayerRelativeWidthRedblue,// result red/blue mask mpy by scaled default (square)
debayerParameters.debayerRelativeWidthRedblueMain,// green mask when applied to red/blue, main (center)
debayerParameters.debayerRelativeWidthRedblueMain,// green mask when applied to red/blue, main (center)
debayerParameters.debayerRelativeWidthRedblueClones);// green mask when applied to red/blue, clones
debayerParameters.debayerRelativeWidthRedblueClones);// green mask when applied to red/blue, clones
both_masks=debayer_instance.aliasScissors(tile[greenChn],// fht array for green, will be masked in-place
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.debayerUseScissors,// use "scissors", if false - just apply "diamond" ands "square" with DEBAYER_PARAMETERS.debayerRelativeWidthGreen and DEBAYER_PARAMETERS.debayerRelativeWidthRedblue
both_masks=debayer_instance.aliasScissors(tile[greenChn],// fht array for green, will be masked in-place
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 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
/*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(
nonSyncAccumulateSquareTile(
outPixles[chn],// float pixels array to accumulate tile
tile[chn],// data to accumulate to the pixels array
finalinttilesY=imgHeight/step-1;// vertical number of overlapping tiles in the source image (should be expanded from the registerd one by "step" in each direction)
finalinttilesY=imgHeight/step-1;// vertical number of overlapping tiles in the source image (should be expanded from the registerd one by "step" in each direction)
finalintkernelWidth=kernelStack.getWidth();
finalintkernelWidth=kernelStack.getWidth();
finalintkernelNumHor=kernelWidth/(size/2);
finalintkernelNumHor=kernelWidth/(size/2);
finalintnChn=imageStack.getSize();
finalintnChn=imageStack.getSize();
finalfloat[][]outPixels=newfloat[nChn][length];// GLOBAL same as input
finalfloat[][]outPixels=newfloat[nChn][length];// GLOBAL same as input
// float [][] outPixels=new float[nChn][length]; // same as input
// float [][] outPixels=new float[nChn][length]; // same as input
// 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);
debayer_bonus,// scale far pixels as (1.0+bonus*r/rmax)
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)
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)
debayer_bonus,// scale far pixels as (1.0+bonus*r/rmax)
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) */
privateint[][]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
privatedouble[][]polar2CartesianFractions;// a pair of dx, dy for interpolations (used with ) polar2CartesianIndices[][]]
}else{
privateint[][]cartesian2PolarIndices;// each per-pixel array is a list of indices in polar array pointing to this cell (may be empty)
for(iy=0;iy<size;iy++){
privateint[]cartesian2PolarIndex;// Cartesian->polar array index (cell closest to the center). Is it possible that cartesian2PolarIndices does not include this one?
iy1=(iy+hsizeM1)%size-hsizeM1;
privateint[][]polarGreenMap=null;// each element is a variable length integer array with a list of the alias indices
for(ix=0;ix<size;ix++){
privateint[][]polarRedBlueMap=null;// each element is a variable length integer array with a list of the alias indices
ix1=(ix+hsizeM1)%size-hsizeM1;
privateint[][]sameCartesian=null;// each element is a variable length integer array with a list of indices of the other polar cells that belong (point to) the same cartesian cell
privateint[]cartAmpList=null;// list of indices of the elements of the cartesian array (symmetrical around the center) so the distance is between ampRMinMax[0] and ampRMinMax[1]
elsefht[index++]=0.0;
privatedouble[]ampRMinMax={0.0,0.0};
}
publicPolarSpectrums(){}// so "Compile and Run" will be happy
}
/* Convert cartesian to polar array, dimensions are set in the class constructor. Uses bi-linear interpolation */
privateint[][]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
returncartPixels;
privatedouble[][]polar2CartesianFractions;// a pair of dx, dy for interpolations (used with ) polar2CartesianIndices[][]]
}
privateint[][]cartesian2PolarIndices;// each per-pixel array is a list of indices in polar array pointing to this cell (may be empty)
/* Caculates maximal value of a center-symmetrical array of the amplitudes in a ring. Uses cached table of indices, recalculates if it changed */
privateint[]cartesian2PolarIndex;// Cartesian->polar array index (cell closest to the center). Is it possible that cartesian2PolarIndices does not include this one?
publicdoublemaxAmpInRing(double[]amps){returnmaxAmpInRing(amps,size*0.118,size*0.236);}// ~=1/3* (Math.sqrt(2)/4), 2/3* (Math.sqrt(2)/4) (center 1/3 ring between center and the closest alias for greens)
privateint[][]polarGreenMap=null;// each element is a variable length integer array with a list of the alias indices
publicdoublemaxAmpInRing(double[]amps,
privateint[][]polarRedBlueMap=null;// each element is a variable length integer array with a list of the alias indices
doublerMin,
privateint[][]sameCartesian=null;// each element is a variable length integer array with a list of indices of the other polar cells that belong (point to) the same cartesian cell
doublerMax
privateint[]cartAmpList=null;// list of indices of the elements of the cartesian array (symmetrical around the center) so the distance is between ampRMinMax[0] and ampRMinMax[1]
){
privatedouble[]ampRMinMax={0.0,0.0};
inti,j,x,y;
publicPolarSpectrums(){}// so "Compile and Run" will be happy
publicdouble[]genPolarGreenMask(double[]polarAmps,// polar array of amplitude values, <0 - stop
}
intmode){// result mode - 0: output mask as 0/1, 1 -output proportional, positive - pass, negative - rejected
if(symmHalf){
returngenPolarMask(polarAmps,0,mode);
j=l2-i;
}
if(j<length)cartPixels[j]=cartPixels[i];
}
publicdouble[]genPolarRedBlueMask(double[]polarAmps,// polar array of amplitude values, <0 - stop
}
intmode){// result mode - 0: output mask as 0/1, 1 -output proportional, positive - pass, negative - rejected
returncartPixels;
returngenPolarMask(polarAmps,1,mode);
}
}
/* Caculates maximal value of a center-symmetrical array of the amplitudes in a ring. Uses cached table of indices, recalculates if it changed */
publicdoublemaxAmpInRing(double[]amps){returnmaxAmpInRing(amps,size*0.118,size*0.236);}// ~=1/3* (Math.sqrt(2)/4), 2/3* (Math.sqrt(2)/4) (center 1/3 ring between center and the closest alias for greens)
publicdoublemaxAmpInRing(double[]amps,
publicdouble[]genPolarMask(double[]polarAmps,// polar array of amplitude values, <0 - stop
doublerMin,
inttype,// 0 - green, 1 red/blue
doublerMax
intmode){// result mode - 0: output mask as 0/1, 1 -output proportional, positive - pass, negative - rejected
int[]rayLength=newint[iAngle+1];// index (radius)) of the current ray end for this angle
doublerMax2=rMax*rMax;
boolean[]rayOpen=newboolean[iAngle+1];// this ray can grow (not blocked)
doubler2;
for(i=0;i<iAngle;i++){
// pass 1 - count number of elements
rayLength[i]=0;
intnumMembers=0;
rayOpen[i]=true;
for(i=0;i<=size/2;i++){
}
y=i-(size/2);
intlastIndex;
for(j=0;j<size;j++){
intbase;
x=j-(size/2);
intl;
r2=x*x+y*y;
doublemax;
if((r2>=rMin2)&&(r2<=rMax2))numMembers++;
intnewVal;
}
intstep=0;
}
intiMax=0;// index of the best ray
cartAmpList=newint[numMembers];
intindex=0;
// pass 2 - count number of elements fill in the array
booleangood=true;
numMembers=0;
while(iMax>=0){
for(i=0;i<=size/2;i++){
step++;
y=i-(size/2);
/* add polar point index */
for(j=0;j<size;j++){
newVal=good?step:-step;
x=j-(size/2);
// 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?
/* Create per-polar pixel list of aliases for green Bayer. For each polar point it shows the polar coordinates of the same (and rotated by pi) point of aliases */
else{
/* current implementation - us cartesian (original) pixels as all/nothing, maybe it makes sense to go directly polar-polar, but then it may leave gaps */
/* Create per-polar pixel list of aliases for green Bayer. For each polar point it shows the polar coordinates of the same (and rotated by pi) point of aliases */
/* current implementation - us cartesian (original) pixels as all/nothing, maybe it makes sense to go directly polar-polar, but then it may leave gaps */