diff --git a/openbr/plugins/quantize.cpp b/openbr/plugins/quantize.cpp index ba53be2..45fdcbf 100644 --- a/openbr/plugins/quantize.cpp +++ b/openbr/plugins/quantize.cpp @@ -268,7 +268,14 @@ class ProductQuantizationDistance : public Distance const float *lut = (const float*)ProductQuantizationLUTs[index].data; for (int j=0; jat(0,i*256+j) = distance->compare(center->row(i), center->row(j)); - - if (!bayesian) return; - - QList indicies = OpenCVUtils::matrixToVector(clusterLabels); - QVector genuineScores, impostorScores; - genuineScores.reserve(indicies.size()); - impostorScores.reserve(indicies.size()*indicies.size()/2); - for (int i=0; iat(0, indicies[i]*256+indicies[j]); - if (labels[i] == labels[j]) genuineScores.append(score); - else impostorScores.append(score); - } - - genuineScores = Common::Downsample(genuineScores, 256); - impostorScores = Common::Downsample(impostorScores, 256); - const double hGenuine = Common::KernelDensityBandwidth(genuineScores); - const double hImpostor = Common::KernelDensityBandwidth(impostorScores); + fullLUT.at(0,i*256+j) = distance->compare(center->row(i), center->row(j)); + + if (bayesian) { + QList indicies = OpenCVUtils::matrixToVector(clusterLabels); + QVector genuineScores, impostorScores; + genuineScores.reserve(indicies.size()); + impostorScores.reserve(indicies.size()*indicies.size()/2); + for (int i=0; i(0, indicies[i]*256+indicies[j]); + if (labels[i] == labels[j]) genuineScores.append(score); + else impostorScores.append(score); + } + + genuineScores = Common::Downsample(genuineScores, 256); + impostorScores = Common::Downsample(impostorScores, 256); + const double hGenuine = Common::KernelDensityBandwidth(genuineScores); + const double hImpostor = Common::KernelDensityBandwidth(impostorScores); + + for (int i=0; i<256; i++) + for (int j=i; j<256; j++) { + const float loglikelihood = log(Common::KernelDensityEstimation(genuineScores, fullLUT.at(0,i*256+j), hGenuine) / + Common::KernelDensityEstimation(impostorScores, fullLUT.at(0,i*256+j), hImpostor)); + fullLUT.at(0,i*256+j) = loglikelihood; + fullLUT.at(0,j*256+i) = loglikelihood; + } + } + // Compress LUT into one dimensional array + int index = 0; for (int i=0; i<256; i++) - for (int j=i; j<256; j++) { - const float loglikelihood = log(Common::KernelDensityEstimation(genuineScores, lut->at(0,i*256+j), hGenuine) / - Common::KernelDensityEstimation(impostorScores, lut->at(0,i*256+j), hImpostor)); - lut->at(0,i*256+j) = loglikelihood; - lut->at(0,j*256+i) = loglikelihood; + for (int j=0; j<=i; j++) { + lut->at(0,index) = fullLUT.at(0,i*256+j); + index++; } + if (index != lut->cols) + qFatal("Logic error."); } int getStep(int cols) const @@ -454,7 +478,7 @@ private: const QList labels = src.labels(); Mat &lut = ProductQuantizationLUTs[index]; - lut = Mat(getDims(data.cols), 256*256, CV_32FC1); + lut = Mat(getDims(data.cols), 256*(256+1)/2, CV_32FC1); QList subdata, subluts; const int offset = getOffset(data.cols);