@@ -398,48 +398,47 @@ MaterialBuilder RtiBuilder::pickBasePTM(std::vector<Vector3f> &lights) {
398
398
x = (At * A)^-1*At*b
399
399
*/
400
400
401
- uint32_t dim = ndimensions*3 ;
401
+ uint32_t nlights = lights.size ();
402
+ uint32_t dim = nlights*3 ; // number of lights *3
402
403
MaterialBuilder mat;
403
404
mat.mean .resize (dim, 0.0 );
404
405
405
- Eigen::MatrixXf A (lights.size (), 6 );
406
- for (uint32_t l = 0 ; l < lights.size (); l++) {
406
+ bool first_degree = (colorspace == LRGB && nplanes == 6 ) || (colorspace == RGB && nplanes == 9 );
407
+
408
+ Eigen::MatrixXf A (lights.size (), first_degree ? 3 : 6 );
409
+ for (uint32_t l = 0 ; l < nlights; l++) {
407
410
Vector3f &light = lights[l];
408
411
A (l, 0 ) = 1.0 ;
409
412
A (l, 1 ) = light[0 ];
410
413
A (l, 2 ) = light[1 ];
411
- A (l, 3 ) = light[0 ]*light[0 ];
412
- A (l, 4 ) = light[0 ]*light[1 ];
413
- A (l, 5 ) = light[1 ]*light[1 ];
414
- }
415
-
416
- if ((colorspace == LRGB && nplanes == 6 ) || (colorspace == RGB && nplanes == 9 )) {
417
- A.conservativeResize (lights.size (), 3 );
414
+ if (!first_degree) {
415
+ A (l, 3 ) = light[0 ]*light[0 ];
416
+ A (l, 4 ) = light[0 ]*light[1 ];
417
+ A (l, 5 ) = light[1 ]*light[1 ];
418
+ }
418
419
}
419
420
420
421
Eigen::MatrixXf iA = (A.transpose ()*A).inverse ()*A.transpose ();
421
422
if (iA.hasNaN ()) {
422
- Eigen::MatrixXf AN (lights.size (), nplanes);
423
- for (uint32_t l = 0 ; l < lights.size (); l++) {
424
- Vector3f &light = lights[l];
425
- if (colorspace == LRGB) {
426
- A (l, 0 ) = 1.0 ;
427
- A (l, 1 ) = light[0 ];
428
- A (l, 2 ) = light[1 ];
429
- check for number of planes
430
- A (l, 3 ) = light[0 ]*light[0 ];
431
- A (l, 4 ) = light[0 ]*light[1 ];
432
- A (l, 5 ) = light[1 ]*light[1 ];
433
- } else {
434
- A (l, 0 ) = 1.0 ;
435
- A (l, 1 ) = light[0 ];
436
- A (l, 2 ) = light[1 ];
437
- A (l, 3 ) = light[0 ]*light[0 ];
438
- A (l, 4 ) = light[0 ]*light[1 ];
439
- A (l, 5 ) = light[1 ]*light[1 ];
423
+ if (colorspace != LRGB) {
424
+ A = Eigen::MatrixXf::Zero (nlights*3 , nplanes);
425
+
426
+ for (uint32_t l = 0 ; l < lights.size (); l++) {
427
+ Vector3f &light = lights[l];
428
+ for (int k = 0 ; k < 3 ; k++) {
429
+ A (l*3 +k, 0 *3 +k) = 1.0 ;
430
+ A (l*3 +k, 1 *3 +k) = light[0 ];
431
+ A (l*3 +k, 2 *3 +k) = light[1 ];
432
+ if (!first_degree) {
433
+ A (l*3 +k, 3 *3 +k) = light[0 ]*light[0 ];
434
+ A (l*3 +k, 4 *3 +k) = light[0 ]*light[1 ];
435
+ A (l*3 +k, 5 *3 +k) = light[1 ]*light[1 ];
436
+ }
437
+ }
440
438
}
441
- }
442
- mat.svd .compute (A, Eigen::ComputeThinU | Eigen::ComputeThinV);
439
+ }
440
+ mat.svd .compute (A, Eigen::ComputeThinU | Eigen::ComputeThinV);
441
+ mat.useEigen = true ;
443
442
} else {
444
443
if (colorspace == LRGB) {
445
444
// we could generalize for different polynomials
@@ -556,7 +555,7 @@ MaterialBuilder RtiBuilder::pickBase(PixelArray &sample, std::vector<Vector3f> &
556
555
case H: builder = pickBaseHSH (directions, type); break ;
557
556
default : cerr << " Unknown basis" << endl; exit (0 );
558
557
}
559
- /*
558
+ /*
560
559
uint32_t dim = sample.components()*3;
561
560
for(uint32_t p = 0; p < nplanes; p += 3) {
562
561
for(uint32_t k = 0; k < lights.size(); k ++) {
@@ -653,8 +652,8 @@ void RtiBuilder::minmaxMaterial(PixelArray &sample) {
653
652
if (callback && (i % 8000 ) == 0 )
654
653
if (!(*callback)(" Coefficients quantization:" , 100 *i/sample.npixels ()))
655
654
throw std::string (" Cancelled." );
656
- \
657
- vector<float > principal = toPrincipal (sample[i]);
655
+ \
656
+ vector<float > principal = toPrincipal (sample[i]);
658
657
659
658
// find max and min of coefficients
660
659
for (uint32_t p = 0 ; p < nplanes; p++) {
@@ -930,8 +929,8 @@ Vector3f RtiBuilder::getNormalThreeLights(vector<float> &pri) {
930
929
Vector3f l2 (sin (a)*cos (9 *b), sin (a)*sin (9 *b), cos (a));
931
930
932
931
T << l0[0 ], l0[1 ], l0[2 ],
933
- l1[0 ], l1[1 ], l1[2 ],
934
- l2[0 ], l2[1 ], l2[2 ];
932
+ l1[0 ], l1[1 ], l1[2 ],
933
+ l2[0 ], l2[1 ], l2[2 ];
935
934
936
935
T = T.inverse ().eval ();
937
936
@@ -1407,7 +1406,7 @@ size_t RtiBuilder::save(const string &output, int quality) {
1407
1406
1408
1407
// Set spatial resolution if known. Convert to pixels/m as RtiBuilder stores this in mm/pixel
1409
1408
if (imageset.pixel_size > 0 ) {
1410
- int dotsPerMeter = round (1000.0 /imageset.pixel_size );
1409
+ int dotsPerMeter = round (1000.0 /imageset.pixel_size );
1411
1410
normals.setDotsPerMeterX (dotsPerMeter);
1412
1411
normals.setDotsPerMeterY (dotsPerMeter);
1413
1412
means.setDotsPerMeterX (dotsPerMeter);
@@ -1946,18 +1945,24 @@ std::vector<float> RtiBuilder::toPrincipal(Pixel &pixel, MaterialBuilder &materi
1946
1945
float luma = (mean[0 ] + mean[1 ] + mean[2 ])/255 ; // actually 3 times luma, but balances in the equation below.
1947
1946
1948
1947
// fit luminosity.
1949
- for (size_t p = 3 ; p < nplanes; p++)
1950
- for (size_t k = 0 ; k < ndimensions; k++)
1951
- res[p] += ((v[k*3 ] + v[k*3 +1 ] + v[k*3 +2 ])/luma)* materialbuilder.proj [k + (p-3 )*ndimensions];
1948
+ if (!materialbuilder.useEigen ) {
1949
+ for (size_t p = 3 ; p < nplanes; p++)
1950
+ for (size_t k = 0 ; k < ndimensions; k++)
1951
+ res[p] += ((v[k*3 ] + v[k*3 +1 ] + v[k*3 +2 ])/luma)* materialbuilder.proj [k + (p-3 )*ndimensions];
1952
+ } else {
1953
+ Eigen::Map<Eigen::VectorXf> ev (v, ndimensions);
1954
+ Eigen::Map<Eigen::VectorXf> eres (&*res.begin () + 3 , nplanes);
1952
1955
1956
+ eres = materialbuilder.svd .solve (ev);
1957
+ }
1953
1958
res[0 ] = mean[0 ];
1954
1959
res[1 ] = mean[1 ];
1955
1960
res[2 ] = mean[2 ];
1956
1961
1957
1962
1958
1963
1959
1964
} else { // RGB, YCC
1960
- if (!materialbuilder.svd . computeU () ) { // not rank deficient.
1965
+ if (!materialbuilder.useEigen ) { // not rank deficient.
1961
1966
vector<float > col (dim);
1962
1967
1963
1968
for (size_t k = 0 ; k < dim; k++)
0 commit comments