Commit 140268451d944f241d54fc77d503347c9ea4f5ae
1 parent
cff9e644
more plugin development
Showing
3 changed files
with
65 additions
and
31 deletions
sdk/plugins/algorithms.cpp
| @@ -32,7 +32,6 @@ class AlgorithmsInitializer : public Initializer | @@ -32,7 +32,6 @@ class AlgorithmsInitializer : public Initializer | ||
| 32 | { | 32 | { |
| 33 | // Face | 33 | // Face |
| 34 | Globals->abbreviations.insert("FaceRecognition", "FaceDetection!<FaceRecognitionRegistration>!<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>:MatchProbability(ByteL1)"); | 34 | Globals->abbreviations.insert("FaceRecognition", "FaceDetection!<FaceRecognitionRegistration>!<FaceRecognitionExtraction>+<FaceRecognitionEmbedding>+<FaceRecognitionQuantization>:MatchProbability(ByteL1)"); |
| 35 | - Globals->abbreviations.insert("FaceRecognitionNoTraining", "Open+Cascade(FrontalFace)+ASEFEyes+Affine(256,256,0.25,0.35)+(RG+MAdd(0.5))/(Cvt(Gray)+Gradient+Bin(0,360,8,true))+Merge+Integral+IntegralSampler+CvtFloat:L2"); | ||
| 36 | Globals->abbreviations.insert("GenderClassification", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<GenderClassifier>+Discard"); | 35 | Globals->abbreviations.insert("GenderClassification", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<GenderClassifier>+Discard"); |
| 37 | Globals->abbreviations.insert("AgeRegression", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<AgeRegressor>+Discard"); | 36 | Globals->abbreviations.insert("AgeRegression", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<AgeRegressor>+Discard"); |
| 38 | Globals->abbreviations.insert("FaceQuality", "Open!Cascade(FrontalFace)+ASEFEyes+Affine(64,64,0.25,0.35)+ImageQuality+Cvt(Gray)+DFFS+Discard"); | 37 | Globals->abbreviations.insert("FaceQuality", "Open!Cascade(FrontalFace)+ASEFEyes+Affine(64,64,0.25,0.35)+ImageQuality+Cvt(Gray)+DFFS+Discard"); |
| @@ -43,7 +42,7 @@ class AlgorithmsInitializer : public Initializer | @@ -43,7 +42,7 @@ class AlgorithmsInitializer : public Initializer | ||
| 43 | Globals->abbreviations.insert("OpenBR", "FaceRecognition"); | 42 | Globals->abbreviations.insert("OpenBR", "FaceRecognition"); |
| 44 | Globals->abbreviations.insert("GenderEstimation", "GenderClassification"); | 43 | Globals->abbreviations.insert("GenderEstimation", "GenderClassification"); |
| 45 | Globals->abbreviations.insert("AgeEstimation", "AgeRegression"); | 44 | Globals->abbreviations.insert("AgeEstimation", "AgeRegression"); |
| 46 | - Globals->abbreviations.insert("ImageRetrieval", "Open+(RG+MAdd(0.5))/(Cvt(Gray)+Gradient+Bin(0,360,8,true))+Merge+Integral+IntegralSampler+CvtFloat+WordWise(RowWisePCA(8)+RowWiseMeanCenter+Binarize,RowWisePCA)+Sentence:SentenceSimilarity"); | 45 | + Globals->abbreviations.insert("FaceRecognitionHoG", "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(64,64,0.25,0.35)+Gradient+Bin(0,360,8,true)+Merge+Integral+IntegralSampler+ProductQuantization:ProductQuantization"); |
| 47 | 46 | ||
| 48 | // Generic Image Processing | 47 | // Generic Image Processing |
| 49 | Globals->abbreviations.insert("SIFT", "Open+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); | 48 | Globals->abbreviations.insert("SIFT", "Open+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); |
| @@ -51,6 +50,7 @@ class AlgorithmsInitializer : public Initializer | @@ -51,6 +50,7 @@ class AlgorithmsInitializer : public Initializer | ||
| 51 | Globals->abbreviations.insert("SmallSIFT", "Open+LimitSize(512)+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); | 50 | Globals->abbreviations.insert("SmallSIFT", "Open+LimitSize(512)+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); |
| 52 | Globals->abbreviations.insert("SmallSURF", "Open+LimitSize(512)+KeyPointDetector(SURF)+KeyPointDescriptor(SURF):KeyPointMatcher(BruteForce)"); | 51 | Globals->abbreviations.insert("SmallSURF", "Open+LimitSize(512)+KeyPointDetector(SURF)+KeyPointDescriptor(SURF):KeyPointMatcher(BruteForce)"); |
| 53 | Globals->abbreviations.insert("ColorHist", "Open+LimitSize(512)!EnsureChannels(3)+SplitChannels+Hist(256,0,8)+Cat+Normalize(L1):L2"); | 52 | Globals->abbreviations.insert("ColorHist", "Open+LimitSize(512)!EnsureChannels(3)+SplitChannels+Hist(256,0,8)+Cat+Normalize(L1):L2"); |
| 53 | + Globals->abbreviations.insert("ImageRetrieval", "Open+Cvt(Gray)+Cascade(FrontalFace)+ASEFEyes+Affine(88,88,0.25,0.35)+Gradient+Bin(0,360,8,true)+Merge+Integral+IntegralSampler+WordWise(RowWisePCA(8)+RowWiseMeanCenter+Binarize,RowWisePCA)+Sentence:SentenceSimilarity"); | ||
| 54 | 54 | ||
| 55 | // Hash | 55 | // Hash |
| 56 | Globals->abbreviations.insert("FileName", "Name+Identity:Identical"); | 56 | Globals->abbreviations.insert("FileName", "Name+Identity:Identical"); |
sdk/plugins/integral.cpp
| @@ -38,9 +38,9 @@ class IntegralSamplerTransform : public UntrainableTransform | @@ -38,9 +38,9 @@ class IntegralSamplerTransform : public UntrainableTransform | ||
| 38 | Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) | 38 | Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) |
| 39 | Q_PROPERTY(float stepFactor READ get_stepFactor WRITE set_stepFactor RESET reset_stepFactor STORED false) | 39 | Q_PROPERTY(float stepFactor READ get_stepFactor WRITE set_stepFactor RESET reset_stepFactor STORED false) |
| 40 | Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) | 40 | Q_PROPERTY(int minSize READ get_minSize WRITE set_minSize RESET reset_minSize STORED false) |
| 41 | - BR_PROPERTY(int, scales, 4) | 41 | + BR_PROPERTY(int, scales, 5) |
| 42 | BR_PROPERTY(float, scaleFactor, 1.5) | 42 | BR_PROPERTY(float, scaleFactor, 1.5) |
| 43 | - BR_PROPERTY(float, stepFactor, 0.25) | 43 | + BR_PROPERTY(float, stepFactor, 0.75) |
| 44 | BR_PROPERTY(int, minSize, 8) | 44 | BR_PROPERTY(int, minSize, 8) |
| 45 | 45 | ||
| 46 | void project(const Template &src, Template &dst) const | 46 | void project(const Template &src, Template &dst) const |
| @@ -53,21 +53,23 @@ class IntegralSamplerTransform : public UntrainableTransform | @@ -53,21 +53,23 @@ class IntegralSamplerTransform : public UntrainableTransform | ||
| 53 | const int rowStep = channels * m.cols; | 53 | const int rowStep = channels * m.cols; |
| 54 | 54 | ||
| 55 | int descriptors = 0; | 55 | int descriptors = 0; |
| 56 | - int currentSize = min(m.rows, m.cols)-1; | 56 | + float idealSize = min(m.rows, m.cols)-1; |
| 57 | for (int scale=0; scale<scales; scale++) { | 57 | for (int scale=0; scale<scales; scale++) { |
| 58 | - descriptors += (1+(m.rows-currentSize)/int(currentSize*stepFactor)) * | ||
| 59 | - (1+(m.cols-currentSize)/int(currentSize*stepFactor)); | ||
| 60 | - currentSize /= scaleFactor; | ||
| 61 | - if (currentSize < minSize) break; | 58 | + const int currentSize(idealSize); |
| 59 | + descriptors += (1+(m.rows-currentSize-1)/int(idealSize*stepFactor)) * | ||
| 60 | + (1+(m.cols-currentSize-1)/int(idealSize*stepFactor)); | ||
| 61 | + idealSize /= scaleFactor; | ||
| 62 | + if (idealSize < minSize) break; | ||
| 62 | } | 63 | } |
| 63 | Mat n(descriptors, channels, CV_32FC1); | 64 | Mat n(descriptors, channels, CV_32FC1); |
| 64 | 65 | ||
| 65 | const qint32 *dataIn = (qint32*)m.data; | 66 | const qint32 *dataIn = (qint32*)m.data; |
| 66 | float *dataOut = (float*)n.data; | 67 | float *dataOut = (float*)n.data; |
| 67 | - currentSize = min(m.rows, m.cols)-1; | 68 | + idealSize = min(m.rows, m.cols)-1; |
| 68 | int index = 0; | 69 | int index = 0; |
| 69 | for (int scale=0; scale<scales; scale++) { | 70 | for (int scale=0; scale<scales; scale++) { |
| 70 | - const int currentStep = currentSize * stepFactor; | 71 | + const int currentSize(idealSize); |
| 72 | + const int currentStep(idealSize*stepFactor); | ||
| 71 | for (int i=currentSize; i<m.rows; i+=currentStep) { | 73 | for (int i=currentSize; i<m.rows; i+=currentStep) { |
| 72 | for (int j=currentSize; j<m.cols; j+=currentStep) { | 74 | for (int j=currentSize; j<m.cols; j+=currentStep) { |
| 73 | InputDescriptor a(dataIn+((i-currentSize)*rowStep+(j-currentSize)*channels), channels, 1); | 75 | InputDescriptor a(dataIn+((i-currentSize)*rowStep+(j-currentSize)*channels), channels, 1); |
| @@ -79,8 +81,8 @@ class IntegralSamplerTransform : public UntrainableTransform | @@ -79,8 +81,8 @@ class IntegralSamplerTransform : public UntrainableTransform | ||
| 79 | index++; | 81 | index++; |
| 80 | } | 82 | } |
| 81 | } | 83 | } |
| 82 | - currentSize /= scaleFactor; | ||
| 83 | - if (currentSize < minSize) break; | 84 | + idealSize /= scaleFactor; |
| 85 | + if (idealSize < minSize) break; | ||
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | if (descriptors != index) | 88 | if (descriptors != index) |
sdk/plugins/quantize.cpp
| @@ -109,58 +109,90 @@ class PackTransform : public UntrainableTransform | @@ -109,58 +109,90 @@ class PackTransform : public UntrainableTransform | ||
| 109 | 109 | ||
| 110 | BR_REGISTER(Transform, PackTransform) | 110 | BR_REGISTER(Transform, PackTransform) |
| 111 | 111 | ||
| 112 | -QVector<Mat> BayesianProductQuantizationLUTs; | 112 | +QVector<Mat> ProductQuantizationLUTs; |
| 113 | + | ||
| 114 | +/*! | ||
| 115 | + * \ingroup distances | ||
| 116 | + * \brief Distance in a product quantized space \cite jegou11 | ||
| 117 | + * \author Josh Klontz | ||
| 118 | + */ | ||
| 119 | +class ProductQuantizationDistance : public Distance | ||
| 120 | +{ | ||
| 121 | + Q_OBJECT | ||
| 122 | + Q_PROPERTY(bool bayesian READ get_bayesian WRITE set_bayesian RESET reset_bayesian STORED false) | ||
| 123 | + BR_PROPERTY(bool, bayesian, false) | ||
| 124 | + | ||
| 125 | + float compare(const Template &a, const Template &b) const | ||
| 126 | + { | ||
| 127 | + float distance = 0; | ||
| 128 | + for (int i=0; i<a.size(); i++) { | ||
| 129 | + const int elements = a[i].total(); | ||
| 130 | + const uchar *aData = a[i].data; | ||
| 131 | + const uchar *bData = b[i].data; | ||
| 132 | + const float *lut = (const float*)ProductQuantizationLUTs[i].data; | ||
| 133 | + for (int j=0; j<elements; j++) | ||
| 134 | + distance += lut[i*256*256 + aData[j]*256+bData[j]]; | ||
| 135 | + } | ||
| 136 | + if (!bayesian) distance = -log(distance+1); | ||
| 137 | + return distance; | ||
| 138 | + } | ||
| 139 | +}; | ||
| 140 | + | ||
| 141 | +BR_REGISTER(Distance, ProductQuantizationDistance) | ||
| 113 | 142 | ||
| 114 | /*! | 143 | /*! |
| 115 | * \ingroup transforms | 144 | * \ingroup transforms |
| 116 | - * \brief A bayesian extension to product quantization \cite jegou11 | 145 | + * \brief Product quantization \cite jegou11 |
| 117 | * \author Josh Klontz \cite jklontz | 146 | * \author Josh Klontz \cite jklontz |
| 118 | */ | 147 | */ |
| 119 | -class BayesianProductQuantizationTransform : public Transform | 148 | +class ProductQuantizationTransform : public Transform |
| 120 | { | 149 | { |
| 121 | Q_OBJECT | 150 | Q_OBJECT |
| 122 | Q_PROPERTY(int n READ get_n WRITE set_n RESET reset_n STORED false) | 151 | Q_PROPERTY(int n READ get_n WRITE set_n RESET reset_n STORED false) |
| 123 | - BR_PROPERTY(int, n, 3) | 152 | + Q_PROPERTY(bool bayesian READ get_bayesian WRITE set_bayesian RESET reset_bayesian STORED false) |
| 153 | + BR_PROPERTY(int, n, 2) | ||
| 154 | + BR_PROPERTY(bool, bayesian, false) | ||
| 124 | 155 | ||
| 125 | int index; | 156 | int index; |
| 126 | QList<Mat> centers; | 157 | QList<Mat> centers; |
| 127 | 158 | ||
| 128 | public: | 159 | public: |
| 129 | - BayesianProductQuantizationTransform() | 160 | + ProductQuantizationTransform() |
| 130 | { | 161 | { |
| 131 | - index = BayesianProductQuantizationLUTs.size(); | ||
| 132 | - BayesianProductQuantizationLUTs.append(Mat()); | 162 | + index = ProductQuantizationLUTs.size(); |
| 163 | + ProductQuantizationLUTs.append(Mat()); | ||
| 133 | } | 164 | } |
| 134 | 165 | ||
| 135 | private: | 166 | private: |
| 136 | void train(const TemplateList &src) | 167 | void train(const TemplateList &src) |
| 137 | { | 168 | { |
| 138 | - Mat data = OpenCVUtils::toMatByRow(src.data()); | 169 | + Mat data = OpenCVUtils::toMat(src.data()); |
| 170 | + qDebug() << data.rows << data.cols; | ||
| 139 | if (data.cols % n != 0) qFatal("Expected dimensionality to be divisible by n."); | 171 | if (data.cols % n != 0) qFatal("Expected dimensionality to be divisible by n."); |
| 140 | 172 | ||
| 141 | - Mat &lut = BayesianProductQuantizationLUTs[index]; | 173 | + Mat &lut = ProductQuantizationLUTs[index]; |
| 142 | lut = Mat(data.cols/n, 256*256, CV_32FC1); | 174 | lut = Mat(data.cols/n, 256*256, CV_32FC1); |
| 143 | 175 | ||
| 144 | - for (int i=0; i<data.cols/n; i++) { | 176 | + for (int i=0; i<lut.rows; i++) { |
| 145 | Mat labels, center; | 177 | Mat labels, center; |
| 146 | kmeans(data.colRange(i*n,(i+1)*n), 256, labels, TermCriteria(TermCriteria::MAX_ITER, 10, 0), 3, KMEANS_PP_CENTERS, center); | 178 | kmeans(data.colRange(i*n,(i+1)*n), 256, labels, TermCriteria(TermCriteria::MAX_ITER, 10, 0), 3, KMEANS_PP_CENTERS, center); |
| 147 | - | ||
| 148 | for (int j=0; j<256; j++) | 179 | for (int j=0; j<256; j++) |
| 149 | for (int k=0; k<256; k++) | 180 | for (int k=0; k<256; k++) |
| 150 | - lut.at<float>(i,j*256+k) = norm(center.row(k), center.row(k), NORM_L2); | 181 | + lut.at<float>(i,j*256+k) = norm(center.row(j), center.row(k), NORM_L2); |
| 151 | centers.append(center); | 182 | centers.append(center); |
| 152 | } | 183 | } |
| 153 | } | 184 | } |
| 154 | 185 | ||
| 155 | void project(const Template &src, Template &dst) const | 186 | void project(const Template &src, Template &dst) const |
| 156 | { | 187 | { |
| 188 | + Mat m = src.m().reshape(1, 1); | ||
| 157 | dst = Mat(1, src.m().cols/n, CV_8UC1); | 189 | dst = Mat(1, src.m().cols/n, CV_8UC1); |
| 158 | - for (int i=0; i<src.m().cols/n; i++) { | 190 | + for (int i=0; i<m.cols/n; i++) { |
| 159 | uchar bestIndex = -1; | 191 | uchar bestIndex = -1; |
| 160 | double bestDistance = std::numeric_limits<double>::max(); | 192 | double bestDistance = std::numeric_limits<double>::max(); |
| 161 | - Mat m = src.m().colRange(i*n, (i+1)*n); | 193 | + Mat m_i = m.colRange(i*n, (i+1)*n); |
| 162 | for (uchar i=0; i<256; i++) { | 194 | for (uchar i=0; i<256; i++) { |
| 163 | - double distance = norm(m, centers[index].row(i), NORM_L2); | 195 | + double distance = norm(m_i, centers[index].row(i), NORM_L2); |
| 164 | if (distance < bestDistance) { | 196 | if (distance < bestDistance) { |
| 165 | bestDistance = distance; | 197 | bestDistance = distance; |
| 166 | bestIndex = i; | 198 | bestIndex = i; |
| @@ -172,16 +204,16 @@ private: | @@ -172,16 +204,16 @@ private: | ||
| 172 | 204 | ||
| 173 | void store(QDataStream &stream) const | 205 | void store(QDataStream &stream) const |
| 174 | { | 206 | { |
| 175 | - stream << centers << BayesianProductQuantizationLUTs[index]; | 207 | + stream << centers << ProductQuantizationLUTs[index]; |
| 176 | } | 208 | } |
| 177 | 209 | ||
| 178 | void load(QDataStream &stream) | 210 | void load(QDataStream &stream) |
| 179 | { | 211 | { |
| 180 | - stream >> centers >> BayesianProductQuantizationLUTs[index]; | 212 | + stream >> centers >> ProductQuantizationLUTs[index]; |
| 181 | } | 213 | } |
| 182 | }; | 214 | }; |
| 183 | 215 | ||
| 184 | -BR_REGISTER(Transform, BayesianProductQuantizationTransform) | 216 | +BR_REGISTER(Transform, ProductQuantizationTransform) |
| 185 | 217 | ||
| 186 | } // namespace br | 218 | } // namespace br |
| 187 | 219 |