Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
imagej-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
imagej-elphel
Commits
1361f670
Commit
1361f670
authored
Apr 06, 2017
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
planes from neighbor supertiles
parent
3f6c6c63
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
601 additions
and
64 deletions
+601
-64
EyesisCorrectionParameters.java
src/main/java/EyesisCorrectionParameters.java
+15
-2
GeometryCorrection.java
src/main/java/GeometryCorrection.java
+31
-10
SuperTiles.java
src/main/java/SuperTiles.java
+194
-9
TilePlanes.java
src/main/java/TilePlanes.java
+308
-42
TileProcessor.java
src/main/java/TileProcessor.java
+53
-1
No files found.
src/main/java/EyesisCorrectionParameters.java
View file @
1361f670
...
@@ -2147,7 +2147,8 @@ public class EyesisCorrectionParameters {
...
@@ -2147,7 +2147,8 @@ public class EyesisCorrectionParameters {
public
double
plTargetEigen
=
0.1
;
// Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below
public
double
plTargetEigen
=
0.1
;
// Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below
public
double
plFractOutliers
=
0.3
;
// Maximal fraction of outliers to remove
public
double
plFractOutliers
=
0.3
;
// Maximal fraction of outliers to remove
public
int
plMaxOutliers
=
20
;
// Maximal number of outliers to remove
public
int
plMaxOutliers
=
20
;
// Maximal number of outliers to remove
public
double
plMinStrength
=
0.1
;
// Minimal total strength of a plane
public
double
plMaxEigen
=
0.3
;
// Maximal eigenvalue of a plane
// other debug images
// other debug images
public
boolean
show_ortho_combine
=
false
;
// Show 'ortho_combine'
public
boolean
show_ortho_combine
=
false
;
// Show 'ortho_combine'
...
@@ -2163,7 +2164,7 @@ public class EyesisCorrectionParameters {
...
@@ -2163,7 +2164,7 @@ public class EyesisCorrectionParameters {
public
boolean
show_neighbors
=
false
;
// show 'neighbors'
public
boolean
show_neighbors
=
false
;
// show 'neighbors'
public
boolean
show_flaps_dirs
=
false
;
// show 'flaps-dirs'
public
boolean
show_flaps_dirs
=
false
;
// show 'flaps-dirs'
public
boolean
show_first_clusters
=
false
;
// show 'first_N_clusters'
public
boolean
show_first_clusters
=
false
;
// show 'first_N_clusters'
public
boolean
show_planes
=
false
;
// show planes
public
CLTParameters
(){}
public
CLTParameters
(){}
public
void
setProperties
(
String
prefix
,
Properties
properties
){
public
void
setProperties
(
String
prefix
,
Properties
properties
){
...
@@ -2386,6 +2387,8 @@ public class EyesisCorrectionParameters {
...
@@ -2386,6 +2387,8 @@ public class EyesisCorrectionParameters {
properties
.
setProperty
(
prefix
+
"plTargetEigen"
,
this
.
plTargetEigen
+
""
);
properties
.
setProperty
(
prefix
+
"plTargetEigen"
,
this
.
plTargetEigen
+
""
);
properties
.
setProperty
(
prefix
+
"plFractOutliers"
,
this
.
plFractOutliers
+
""
);
properties
.
setProperty
(
prefix
+
"plFractOutliers"
,
this
.
plFractOutliers
+
""
);
properties
.
setProperty
(
prefix
+
"plMaxOutliers"
,
this
.
plMaxOutliers
+
""
);
properties
.
setProperty
(
prefix
+
"plMaxOutliers"
,
this
.
plMaxOutliers
+
""
);
properties
.
setProperty
(
prefix
+
"plMinStrength"
,
this
.
plMinStrength
+
""
);
properties
.
setProperty
(
prefix
+
"plMaxEigen"
,
this
.
plMaxEigen
+
""
);
properties
.
setProperty
(
prefix
+
"show_ortho_combine"
,
this
.
show_ortho_combine
+
""
);
properties
.
setProperty
(
prefix
+
"show_ortho_combine"
,
this
.
show_ortho_combine
+
""
);
properties
.
setProperty
(
prefix
+
"show_refine_supertiles"
,
this
.
show_refine_supertiles
+
""
);
properties
.
setProperty
(
prefix
+
"show_refine_supertiles"
,
this
.
show_refine_supertiles
+
""
);
...
@@ -2399,6 +2402,7 @@ public class EyesisCorrectionParameters {
...
@@ -2399,6 +2402,7 @@ public class EyesisCorrectionParameters {
properties
.
setProperty
(
prefix
+
"show_neighbors"
,
this
.
show_neighbors
+
""
);
properties
.
setProperty
(
prefix
+
"show_neighbors"
,
this
.
show_neighbors
+
""
);
properties
.
setProperty
(
prefix
+
"show_flaps_dirs"
,
this
.
show_flaps_dirs
+
""
);
properties
.
setProperty
(
prefix
+
"show_flaps_dirs"
,
this
.
show_flaps_dirs
+
""
);
properties
.
setProperty
(
prefix
+
"show_first_clusters"
,
this
.
show_first_clusters
+
""
);
properties
.
setProperty
(
prefix
+
"show_first_clusters"
,
this
.
show_first_clusters
+
""
);
properties
.
setProperty
(
prefix
+
"show_planes"
,
this
.
show_planes
+
""
);
}
}
public
void
getProperties
(
String
prefix
,
Properties
properties
){
public
void
getProperties
(
String
prefix
,
Properties
properties
){
if
(
properties
.
getProperty
(
prefix
+
"transform_size"
)!=
null
)
this
.
transform_size
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"transform_size"
));
if
(
properties
.
getProperty
(
prefix
+
"transform_size"
)!=
null
)
this
.
transform_size
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"transform_size"
));
...
@@ -2614,6 +2618,8 @@ public class EyesisCorrectionParameters {
...
@@ -2614,6 +2618,8 @@ public class EyesisCorrectionParameters {
if
(
properties
.
getProperty
(
prefix
+
"plTargetEigen"
)!=
null
)
this
.
plTargetEigen
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plTargetEigen"
));
if
(
properties
.
getProperty
(
prefix
+
"plTargetEigen"
)!=
null
)
this
.
plTargetEigen
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plTargetEigen"
));
if
(
properties
.
getProperty
(
prefix
+
"plFractOutliers"
)!=
null
)
this
.
plFractOutliers
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plFractOutliers"
));
if
(
properties
.
getProperty
(
prefix
+
"plFractOutliers"
)!=
null
)
this
.
plFractOutliers
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plFractOutliers"
));
if
(
properties
.
getProperty
(
prefix
+
"plMaxOutliers"
)!=
null
)
this
.
plMaxOutliers
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"plMaxOutliers"
));
if
(
properties
.
getProperty
(
prefix
+
"plMaxOutliers"
)!=
null
)
this
.
plMaxOutliers
=
Integer
.
parseInt
(
properties
.
getProperty
(
prefix
+
"plMaxOutliers"
));
if
(
properties
.
getProperty
(
prefix
+
"plMinStrength"
)!=
null
)
this
.
plMinStrength
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plMinStrength"
));
if
(
properties
.
getProperty
(
prefix
+
"plMaxEigen"
)!=
null
)
this
.
plMaxEigen
=
Double
.
parseDouble
(
properties
.
getProperty
(
prefix
+
"plMaxEigen"
));
if
(
properties
.
getProperty
(
prefix
+
"show_ortho_combine"
)!=
null
)
this
.
show_ortho_combine
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_ortho_combine"
));
if
(
properties
.
getProperty
(
prefix
+
"show_ortho_combine"
)!=
null
)
this
.
show_ortho_combine
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_ortho_combine"
));
if
(
properties
.
getProperty
(
prefix
+
"show_refine_supertiles"
)!=
null
)
this
.
show_refine_supertiles
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_refine_supertiles"
));
if
(
properties
.
getProperty
(
prefix
+
"show_refine_supertiles"
)!=
null
)
this
.
show_refine_supertiles
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_refine_supertiles"
));
...
@@ -2627,6 +2633,7 @@ public class EyesisCorrectionParameters {
...
@@ -2627,6 +2633,7 @@ public class EyesisCorrectionParameters {
if
(
properties
.
getProperty
(
prefix
+
"show_neighbors"
)!=
null
)
this
.
show_neighbors
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_neighbors"
));
if
(
properties
.
getProperty
(
prefix
+
"show_neighbors"
)!=
null
)
this
.
show_neighbors
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_neighbors"
));
if
(
properties
.
getProperty
(
prefix
+
"show_flaps_dirs"
)!=
null
)
this
.
show_flaps_dirs
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_flaps_dirs"
));
if
(
properties
.
getProperty
(
prefix
+
"show_flaps_dirs"
)!=
null
)
this
.
show_flaps_dirs
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_flaps_dirs"
));
if
(
properties
.
getProperty
(
prefix
+
"show_first_clusters"
)!=
null
)
this
.
show_first_clusters
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_first_clusters"
));
if
(
properties
.
getProperty
(
prefix
+
"show_first_clusters"
)!=
null
)
this
.
show_first_clusters
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_first_clusters"
));
if
(
properties
.
getProperty
(
prefix
+
"show_planes"
)!=
null
)
this
.
show_planes
=
Boolean
.
parseBoolean
(
properties
.
getProperty
(
prefix
+
"show_planes"
));
}
}
public
boolean
showDialog
()
{
public
boolean
showDialog
()
{
...
@@ -2864,6 +2871,8 @@ public class EyesisCorrectionParameters {
...
@@ -2864,6 +2871,8 @@ public class EyesisCorrectionParameters {
gd
.
addNumericField
(
"Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below"
,
this
.
plTargetEigen
,
6
);
gd
.
addNumericField
(
"Remove outliers until main axis eigenvalue (possibly scaled by plDispNorm) gets below"
,
this
.
plTargetEigen
,
6
);
gd
.
addNumericField
(
"Maximal fraction of outliers to remove"
,
this
.
plFractOutliers
,
6
);
gd
.
addNumericField
(
"Maximal fraction of outliers to remove"
,
this
.
plFractOutliers
,
6
);
gd
.
addNumericField
(
"Maximal number of outliers to remove"
,
this
.
plMaxOutliers
,
0
);
gd
.
addNumericField
(
"Maximal number of outliers to remove"
,
this
.
plMaxOutliers
,
0
);
gd
.
addNumericField
(
"Minimal total strength of a plane"
,
this
.
plMinStrength
,
6
);
gd
.
addNumericField
(
"Maximal eigenvalue of a plane"
,
this
.
plMaxEigen
,
6
);
gd
.
addMessage
(
"--- Other debug images ---"
);
gd
.
addMessage
(
"--- Other debug images ---"
);
gd
.
addCheckbox
(
"Show 'ortho_combine'"
,
this
.
show_ortho_combine
);
gd
.
addCheckbox
(
"Show 'ortho_combine'"
,
this
.
show_ortho_combine
);
...
@@ -2878,6 +2887,7 @@ public class EyesisCorrectionParameters {
...
@@ -2878,6 +2887,7 @@ public class EyesisCorrectionParameters {
gd
.
addCheckbox
(
"show 'neighbors'"
,
this
.
show_neighbors
);
gd
.
addCheckbox
(
"show 'neighbors'"
,
this
.
show_neighbors
);
gd
.
addCheckbox
(
"Show 'flaps-dirs'"
,
this
.
show_flaps_dirs
);
gd
.
addCheckbox
(
"Show 'flaps-dirs'"
,
this
.
show_flaps_dirs
);
gd
.
addCheckbox
(
"Show 'first_N_clusters'"
,
this
.
show_first_clusters
);
gd
.
addCheckbox
(
"Show 'first_N_clusters'"
,
this
.
show_first_clusters
);
gd
.
addCheckbox
(
"Show planes"
,
this
.
show_planes
);
WindowTools
.
addScrollBars
(
gd
);
WindowTools
.
addScrollBars
(
gd
);
gd
.
showDialog
();
gd
.
showDialog
();
...
@@ -3101,6 +3111,8 @@ public class EyesisCorrectionParameters {
...
@@ -3101,6 +3111,8 @@ public class EyesisCorrectionParameters {
this
.
plTargetEigen
=
gd
.
getNextNumber
();
this
.
plTargetEigen
=
gd
.
getNextNumber
();
this
.
plFractOutliers
=
gd
.
getNextNumber
();
this
.
plFractOutliers
=
gd
.
getNextNumber
();
this
.
plMaxOutliers
=
(
int
)
gd
.
getNextNumber
();
this
.
plMaxOutliers
=
(
int
)
gd
.
getNextNumber
();
this
.
plMinStrength
=
gd
.
getNextNumber
();
this
.
plMaxEigen
=
gd
.
getNextNumber
();
this
.
show_ortho_combine
=
gd
.
getNextBoolean
();
this
.
show_ortho_combine
=
gd
.
getNextBoolean
();
this
.
show_refine_supertiles
=
gd
.
getNextBoolean
();
this
.
show_refine_supertiles
=
gd
.
getNextBoolean
();
...
@@ -3114,6 +3126,7 @@ public class EyesisCorrectionParameters {
...
@@ -3114,6 +3126,7 @@ public class EyesisCorrectionParameters {
this
.
show_neighbors
=
gd
.
getNextBoolean
();
this
.
show_neighbors
=
gd
.
getNextBoolean
();
this
.
show_flaps_dirs
=
gd
.
getNextBoolean
();
this
.
show_flaps_dirs
=
gd
.
getNextBoolean
();
this
.
show_first_clusters
=
gd
.
getNextBoolean
();
this
.
show_first_clusters
=
gd
.
getNextBoolean
();
this
.
show_planes
=
gd
.
getNextBoolean
();
return
true
;
return
true
;
}
}
}
}
...
...
src/main/java/GeometryCorrection.java
View file @
1361f670
...
@@ -356,6 +356,36 @@ public class GeometryCorrection {
...
@@ -356,6 +356,36 @@ public class GeometryCorrection {
return
xyz
;
return
xyz
;
}
}
/**
* Find disparity for the intersection of the view ray (px, py) and a real-world plane orthogonal through the end of the
* vector norm_xyz
* @param norm_xyz vector from the origin (camera) orthogonal to the plane, length is a distance to the plane
* @param px pixel coordinate horizontal
* @param py pixel coordinate vertical
* @param correctDistortions true for lens distortion correction, false otherwise
* @return disparity for the point on the plane specified by norm_xyz and known view coordinates px, py
*/
public
double
getPlaneDisparity
(
double
[]
norm_xyz
,
double
px
,
double
py
,
boolean
correctDistortions
)
// correct distortion (will need corrected background too !)
{
double
pXcd
=
px
-
0.5
*
this
.
pixelCorrectionWidth
;
double
pYcd
=
py
-
0.5
*
this
.
pixelCorrectionHeight
;
double
rD
=
Math
.
sqrt
(
pXcd
*
pXcd
+
pYcd
*
pYcd
)*
0.001
*
this
.
pixelSize
;
// distorted radius in a virtual center camera
double
rND2R
=
correctDistortions
?(
getRByRDist
(
rD
/
this
.
distortionRadius
,
false
)):
1.0
;
double
pXc
=
pXcd
*
rND2R
;
// non-distorted coordinates relative to the (0.5 * this.pixelCorrectionWidth, 0.5 * this.pixelCorrectionHeight)
double
pYc
=
pYcd
*
rND2R
;
// in pixels
// point for the unity disparity
double
x
=
SCENE_UNITS_SCALE
*
pXc
*
this
.
disparityRadius
;
double
y
=
-
SCENE_UNITS_SCALE
*
pYc
*
this
.
disparityRadius
;
double
z
=
-
SCENE_UNITS_SCALE
*
this
.
focalLength
*
this
.
disparityRadius
/
(
0.001
*
this
.
pixelSize
);
// "+" - near, "-" far
double
vect_dot_norm
=
(
x
*
norm_xyz
[
0
])
+
(
y
*
norm_xyz
[
1
])
+
(
z
*
norm_xyz
[
2
]);
double
norm_dot_norm
=
(
norm_xyz
[
0
]
*
norm_xyz
[
0
])
+
(
norm_xyz
[
1
]
*
norm_xyz
[
1
])
+
(
norm_xyz
[
2
]
*
norm_xyz
[
2
]);
return
vect_dot_norm
/
norm_dot_norm
;
}
/* Just for testing using delta instead of d */
/* Just for testing using delta instead of d */
public
double
[][]
getWorldJacobian
(
public
double
[][]
getWorldJacobian
(
double
px
,
double
px
,
...
@@ -419,15 +449,6 @@ public class GeometryCorrection {
...
@@ -419,15 +449,6 @@ public class GeometryCorrection {
// k = rD/r
// k = rD/r
double
d_k_d_rrND
=
correctDistortions
?
getDerivRDistFromR
(
rrND
):
0.0
;
double
d_k_d_rrND
=
correctDistortions
?
getDerivRDistFromR
(
rrND
):
0.0
;
double
d_rND2R_d_rrD
=
-
rND2R
*
rND2R
*
d_k_d_rrND
/
(
d_k_d_rrND
*
rrND
+
1.0
/
rND2R
);
// rrND);
double
d_rND2R_d_rrD
=
-
rND2R
*
rND2R
*
d_k_d_rrND
/
(
d_k_d_rrND
*
rrND
+
1.0
/
rND2R
);
// rrND);
/*
double d_rND2R_d_rrD0 = correctDistortions?(getDerivRByRDist(rrD, false)): 0.0;
double d_rND2R_d_rrD1 = correctDistortions?(getDerivRByRDist(rrD, false, 0.00001)): 0.0;
if (debug) {
System.out.println("getWorldJacobian(): d_rND2R_d_rrD="+d_rND2R_d_rrD+", d_rND2R_d_rrD0="+d_rND2R_d_rrD0+", d_rND2R_d_rrD1="+d_rND2R_d_rrD1 );
}
*/
double
d_rND2R_d_px
=
d_rND2R_d_rrD
*
d_rRD_d_px
;
double
d_rND2R_d_px
=
d_rND2R_d_rrD
*
d_rRD_d_px
;
double
d_rND2R_d_py
=
d_rND2R_d_rrD
*
d_rRD_d_py
;
double
d_rND2R_d_py
=
d_rND2R_d_rrD
*
d_rRD_d_py
;
...
@@ -514,7 +535,7 @@ public class GeometryCorrection {
...
@@ -514,7 +535,7 @@ public class GeometryCorrection {
boolean
correctDistortions
,
boolean
correctDistortions
,
int
debugLevel
)
int
debugLevel
)
{
{
if
(
debugLevel
>
0
){
if
(
debugLevel
>
1
){
System
.
out
.
println
(
"getImageJacobian():"
);
System
.
out
.
println
(
"getImageJacobian():"
);
}
}
double
x
=
xyz
[
0
];
double
x
=
xyz
[
0
];
...
...
src/main/java/SuperTiles.java
View file @
1361f670
This diff is collapsed.
Click to expand it.
src/main/java/TilePlanes.java
View file @
1361f670
This diff is collapsed.
Click to expand it.
src/main/java/TileProcessor.java
View file @
1361f670
...
@@ -2973,6 +2973,58 @@ public class TileProcessor {
...
@@ -2973,6 +2973,58 @@ public class TileProcessor {
geometryCorrection
,
geometryCorrection
,
clt_parameters
.
correct_distortions
,
clt_parameters
.
correct_distortions
,
debugLevel
);
// final int debugLevel)
debugLevel
);
// final int debugLevel)
if
(
clt_parameters
.
show_planes
){
int
[]
wh
=
st
.
getShowPlanesWidthHeight
();
double
[][]
plane_data_nonan
=
st
.
getShowPlanes
(
st
.
getPlanes
(),
clt_parameters
.
plMinStrength
,
// minWeight,
clt_parameters
.
plMaxEigen
,
// maxEigen,
clt_parameters
.
plDispNorm
,
false
);
//boolean use_NaN)
double
[][]
plane_data_nan
=
st
.
getShowPlanes
(
st
.
getPlanes
(),
clt_parameters
.
plMinStrength
,
// minWeight,
clt_parameters
.
plMaxEigen
,
// maxEigen,
clt_parameters
.
plDispNorm
,
true
);
//boolean use_NaN)
double
[][]
plane_data
=
new
double
[
plane_data_nonan
.
length
+
plane_data_nan
.
length
][];
int
indx
=
0
;
for
(
int
i
=
0
;
i
<
plane_data_nonan
.
length
;
i
++){
plane_data
[
indx
++]
=
plane_data_nonan
[
i
];
}
for
(
int
i
=
0
;
i
<
plane_data_nan
.
length
;
i
++){
plane_data
[
indx
++]
=
plane_data_nan
[
i
];
}
// sdfa_instance.showArrays(plane_data_nonan, wh[0], wh[1], true, "plane_data_noNaN");
// sdfa_instance.showArrays(plane_data_nan, wh[0], wh[1], true, "plane_data_NaN");
sdfa_instance
.
showArrays
(
plane_data
,
wh
[
0
],
wh
[
1
],
true
,
"plane_data"
);
// show plane data
for
(
int
dr
=
0
;
dr
<
8
;
dr
++){
TilePlanes
.
PlaneData
[][]
planes
=
st
.
getNeibPlanes
(
dr
);
plane_data_nonan
=
st
.
getShowPlanes
(
planes
,
clt_parameters
.
plMinStrength
,
// minWeight,
clt_parameters
.
plMaxEigen
,
// maxEigen,
clt_parameters
.
plDispNorm
,
false
);
//boolean use_NaN)
plane_data_nan
=
st
.
getShowPlanes
(
planes
,
clt_parameters
.
plMinStrength
,
// minWeight,
clt_parameters
.
plMaxEigen
,
// maxEigen,
clt_parameters
.
plDispNorm
,
true
);
//boolean use_NaN)
plane_data
=
new
double
[
plane_data_nonan
.
length
+
plane_data_nan
.
length
][];
indx
=
0
;
for
(
int
i
=
0
;
i
<
plane_data_nonan
.
length
;
i
++){
plane_data
[
indx
++]
=
plane_data_nonan
[
i
];
}
for
(
int
i
=
0
;
i
<
plane_data_nan
.
length
;
i
++){
plane_data
[
indx
++]
=
plane_data_nan
[
i
];
}
sdfa_instance
.
showArrays
(
plane_data
,
wh
[
0
],
wh
[
1
],
true
,
"plane_data_"
+
dr
);
}
}
/*
/*
st.processPlanes1(
st.processPlanes1(
null, // final boolean [] selected, // or null
null, // final boolean [] selected, // or null
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment