Commit 7ae74c55d8d8046c7e2c59d20763187656beb1ea

Authored by Josh Klontz
1 parent 3048ffa0

made LUT 1D

Showing 1 changed file with 52 additions and 28 deletions
openbr/plugins/quantize.cpp
@@ -268,7 +268,14 @@ class ProductQuantizationDistance : public Distance @@ -268,7 +268,14 @@ class ProductQuantizationDistance : public Distance
268 268
269 const float *lut = (const float*)ProductQuantizationLUTs[index].data; 269 const float *lut = (const float*)ProductQuantizationLUTs[index].data;
270 for (int j=0; j<elements; j++) 270 for (int j=0; j<elements; j++)
271 - distance += lut[j*256*256 + aData[j]*256+bData[j]]; 271 + {
  272 + const int aj = aData[j];
  273 + const int bj = bData[j];
  274 + // http://stackoverflow.com/questions/4803180/mapping-elements-in-2d-upper-triangle-and-lower-triangle-to-linear-structure
  275 + const int y = max(aj, bj);
  276 + const int x = min(aj, bj);
  277 + distance += lut[j*256*(256+1)/2 + x + (y+1)*y/2];
  278 + }
272 } 279 }
273 if (!bayesian) distance = -log(distance+1); 280 if (!bayesian) distance = -log(distance+1);
274 return distance; 281 return distance;
@@ -305,8 +312,14 @@ class RecursiveProductQuantizationDistance : public Distance @@ -305,8 +312,14 @@ class RecursiveProductQuantizationDistance : public Distance
305 bData += sizeof(quint16); 312 bData += sizeof(quint16);
306 313
307 const float *lut = (const float*)ProductQuantizationLUTs[index].data; 314 const float *lut = (const float*)ProductQuantizationLUTs[index].data;
308 - for (int j=0; j<elements; j++)  
309 - similarity += lut[j*256*256 + aData[j]*256+bData[j]]; 315 + for (int j=0; j<elements; j++) {
  316 + const int aj = aData[j];
  317 + const int bj = bData[j];
  318 + // http://stackoverflow.com/questions/4803180/mapping-elements-in-2d-upper-triangle-and-lower-triangle-to-linear-structure
  319 + const int y = max(aj, bj);
  320 + const int x = min(aj, bj);
  321 + similarity += lut[j*256*(256+1)/2 + x + (y+1)*y/2];
  322 + }
310 323
311 evidence += similarity; 324 evidence += similarity;
312 const int subSize = (size-1)/4; 325 const int subSize = (size-1)/4;
@@ -395,35 +408,46 @@ private: @@ -395,35 +408,46 @@ private:
395 Mat clusterLabels; 408 Mat clusterLabels;
396 kmeans(data, 256, clusterLabels, TermCriteria(TermCriteria::MAX_ITER, 10, 0), 3, KMEANS_PP_CENTERS, *center); 409 kmeans(data, 256, clusterLabels, TermCriteria(TermCriteria::MAX_ITER, 10, 0), 3, KMEANS_PP_CENTERS, *center);
397 410
  411 + Mat fullLUT(1, 256*256, CV_32FC1);
398 for (int i=0; i<256; i++) 412 for (int i=0; i<256; i++)
399 for (int j=0; j<256; j++) 413 for (int j=0; j<256; j++)
400 - lut->at<float>(0,i*256+j) = distance->compare(center->row(i), center->row(j));  
401 -  
402 - if (!bayesian) return;  
403 -  
404 - QList<int> indicies = OpenCVUtils::matrixToVector<int>(clusterLabels);  
405 - QVector<float> genuineScores, impostorScores;  
406 - genuineScores.reserve(indicies.size());  
407 - impostorScores.reserve(indicies.size()*indicies.size()/2);  
408 - for (int i=0; i<indicies.size(); i++)  
409 - for (int j=i+1; j<indicies.size(); j++) {  
410 - const float score = lut->at<float>(0, indicies[i]*256+indicies[j]);  
411 - if (labels[i] == labels[j]) genuineScores.append(score);  
412 - else impostorScores.append(score);  
413 - }  
414 -  
415 - genuineScores = Common::Downsample(genuineScores, 256);  
416 - impostorScores = Common::Downsample(impostorScores, 256);  
417 - const double hGenuine = Common::KernelDensityBandwidth(genuineScores);  
418 - const double hImpostor = Common::KernelDensityBandwidth(impostorScores); 414 + fullLUT.at<float>(0,i*256+j) = distance->compare(center->row(i), center->row(j));
  415 +
  416 + if (bayesian) {
  417 + QList<int> indicies = OpenCVUtils::matrixToVector<int>(clusterLabels);
  418 + QVector<float> genuineScores, impostorScores;
  419 + genuineScores.reserve(indicies.size());
  420 + impostorScores.reserve(indicies.size()*indicies.size()/2);
  421 + for (int i=0; i<indicies.size(); i++)
  422 + for (int j=i+1; j<indicies.size(); j++) {
  423 + const float score = fullLUT.at<float>(0, indicies[i]*256+indicies[j]);
  424 + if (labels[i] == labels[j]) genuineScores.append(score);
  425 + else impostorScores.append(score);
  426 + }
  427 +
  428 + genuineScores = Common::Downsample(genuineScores, 256);
  429 + impostorScores = Common::Downsample(impostorScores, 256);
  430 + const double hGenuine = Common::KernelDensityBandwidth(genuineScores);
  431 + const double hImpostor = Common::KernelDensityBandwidth(impostorScores);
  432 +
  433 + for (int i=0; i<256; i++)
  434 + for (int j=i; j<256; j++) {
  435 + const float loglikelihood = log(Common::KernelDensityEstimation(genuineScores, fullLUT.at<float>(0,i*256+j), hGenuine) /
  436 + Common::KernelDensityEstimation(impostorScores, fullLUT.at<float>(0,i*256+j), hImpostor));
  437 + fullLUT.at<float>(0,i*256+j) = loglikelihood;
  438 + fullLUT.at<float>(0,j*256+i) = loglikelihood;
  439 + }
  440 + }
419 441
  442 + // Compress LUT into one dimensional array
  443 + int index = 0;
420 for (int i=0; i<256; i++) 444 for (int i=0; i<256; i++)
421 - for (int j=i; j<256; j++) {  
422 - const float loglikelihood = log(Common::KernelDensityEstimation(genuineScores, lut->at<float>(0,i*256+j), hGenuine) /  
423 - Common::KernelDensityEstimation(impostorScores, lut->at<float>(0,i*256+j), hImpostor));  
424 - lut->at<float>(0,i*256+j) = loglikelihood;  
425 - lut->at<float>(0,j*256+i) = loglikelihood; 445 + for (int j=0; j<=i; j++) {
  446 + lut->at<float>(0,index) = fullLUT.at<float>(0,i*256+j);
  447 + index++;
426 } 448 }
  449 + if (index != lut->cols)
  450 + qFatal("Logic error.");
427 } 451 }
428 452
429 int getStep(int cols) const 453 int getStep(int cols) const
@@ -454,7 +478,7 @@ private: @@ -454,7 +478,7 @@ private:
454 const QList<int> labels = src.labels<int>(); 478 const QList<int> labels = src.labels<int>();
455 479
456 Mat &lut = ProductQuantizationLUTs[index]; 480 Mat &lut = ProductQuantizationLUTs[index];
457 - lut = Mat(getDims(data.cols), 256*256, CV_32FC1); 481 + lut = Mat(getDims(data.cols), 256*(256+1)/2, CV_32FC1);
458 482
459 QList<Mat> subdata, subluts; 483 QList<Mat> subdata, subluts;
460 const int offset = getOffset(data.cols); 484 const int offset = getOffset(data.cols);