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 | 32 | { |
| 33 | 33 | // Face |
| 34 | 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 | 35 | Globals->abbreviations.insert("GenderClassification", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<GenderClassifier>+Discard"); |
| 37 | 36 | Globals->abbreviations.insert("AgeRegression", "FaceDetection!<FaceClassificationRegistration>!<FaceClassificationExtraction>+<AgeRegressor>+Discard"); |
| 38 | 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 | 42 | Globals->abbreviations.insert("OpenBR", "FaceRecognition"); |
| 44 | 43 | Globals->abbreviations.insert("GenderEstimation", "GenderClassification"); |
| 45 | 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 | 47 | // Generic Image Processing |
| 49 | 48 | Globals->abbreviations.insert("SIFT", "Open+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); |
| ... | ... | @@ -51,6 +50,7 @@ class AlgorithmsInitializer : public Initializer |
| 51 | 50 | Globals->abbreviations.insert("SmallSIFT", "Open+LimitSize(512)+KeyPointDetector(SIFT)+KeyPointDescriptor(SIFT):KeyPointMatcher(BruteForce)"); |
| 52 | 51 | Globals->abbreviations.insert("SmallSURF", "Open+LimitSize(512)+KeyPointDetector(SURF)+KeyPointDescriptor(SURF):KeyPointMatcher(BruteForce)"); |
| 53 | 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 | 55 | // Hash |
| 56 | 56 | Globals->abbreviations.insert("FileName", "Name+Identity:Identical"); | ... | ... |
sdk/plugins/integral.cpp
| ... | ... | @@ -38,9 +38,9 @@ class IntegralSamplerTransform : public UntrainableTransform |
| 38 | 38 | Q_PROPERTY(float scaleFactor READ get_scaleFactor WRITE set_scaleFactor RESET reset_scaleFactor STORED false) |
| 39 | 39 | Q_PROPERTY(float stepFactor READ get_stepFactor WRITE set_stepFactor RESET reset_stepFactor STORED false) |
| 40 | 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 | 42 | BR_PROPERTY(float, scaleFactor, 1.5) |
| 43 | - BR_PROPERTY(float, stepFactor, 0.25) | |
| 43 | + BR_PROPERTY(float, stepFactor, 0.75) | |
| 44 | 44 | BR_PROPERTY(int, minSize, 8) |
| 45 | 45 | |
| 46 | 46 | void project(const Template &src, Template &dst) const |
| ... | ... | @@ -53,21 +53,23 @@ class IntegralSamplerTransform : public UntrainableTransform |
| 53 | 53 | const int rowStep = channels * m.cols; |
| 54 | 54 | |
| 55 | 55 | int descriptors = 0; |
| 56 | - int currentSize = min(m.rows, m.cols)-1; | |
| 56 | + float idealSize = min(m.rows, m.cols)-1; | |
| 57 | 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 | 64 | Mat n(descriptors, channels, CV_32FC1); |
| 64 | 65 | |
| 65 | 66 | const qint32 *dataIn = (qint32*)m.data; |
| 66 | 67 | float *dataOut = (float*)n.data; |
| 67 | - currentSize = min(m.rows, m.cols)-1; | |
| 68 | + idealSize = min(m.rows, m.cols)-1; | |
| 68 | 69 | int index = 0; |
| 69 | 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 | 73 | for (int i=currentSize; i<m.rows; i+=currentStep) { |
| 72 | 74 | for (int j=currentSize; j<m.cols; j+=currentStep) { |
| 73 | 75 | InputDescriptor a(dataIn+((i-currentSize)*rowStep+(j-currentSize)*channels), channels, 1); |
| ... | ... | @@ -79,8 +81,8 @@ class IntegralSamplerTransform : public UntrainableTransform |
| 79 | 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 | 88 | if (descriptors != index) | ... | ... |
sdk/plugins/quantize.cpp
| ... | ... | @@ -109,58 +109,90 @@ class PackTransform : public UntrainableTransform |
| 109 | 109 | |
| 110 | 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 | 144 | * \ingroup transforms |
| 116 | - * \brief A bayesian extension to product quantization \cite jegou11 | |
| 145 | + * \brief Product quantization \cite jegou11 | |
| 117 | 146 | * \author Josh Klontz \cite jklontz |
| 118 | 147 | */ |
| 119 | -class BayesianProductQuantizationTransform : public Transform | |
| 148 | +class ProductQuantizationTransform : public Transform | |
| 120 | 149 | { |
| 121 | 150 | Q_OBJECT |
| 122 | 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 | 156 | int index; |
| 126 | 157 | QList<Mat> centers; |
| 127 | 158 | |
| 128 | 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 | 166 | private: |
| 136 | 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 | 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 | 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 | 177 | Mat labels, center; |
| 146 | 178 | kmeans(data.colRange(i*n,(i+1)*n), 256, labels, TermCriteria(TermCriteria::MAX_ITER, 10, 0), 3, KMEANS_PP_CENTERS, center); |
| 147 | - | |
| 148 | 179 | for (int j=0; j<256; j++) |
| 149 | 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 | 182 | centers.append(center); |
| 152 | 183 | } |
| 153 | 184 | } |
| 154 | 185 | |
| 155 | 186 | void project(const Template &src, Template &dst) const |
| 156 | 187 | { |
| 188 | + Mat m = src.m().reshape(1, 1); | |
| 157 | 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 | 191 | uchar bestIndex = -1; |
| 160 | 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 | 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 | 196 | if (distance < bestDistance) { |
| 165 | 197 | bestDistance = distance; |
| 166 | 198 | bestIndex = i; |
| ... | ... | @@ -172,16 +204,16 @@ private: |
| 172 | 204 | |
| 173 | 205 | void store(QDataStream &stream) const |
| 174 | 206 | { |
| 175 | - stream << centers << BayesianProductQuantizationLUTs[index]; | |
| 207 | + stream << centers << ProductQuantizationLUTs[index]; | |
| 176 | 208 | } |
| 177 | 209 | |
| 178 | 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 | 218 | } // namespace br |
| 187 | 219 | ... | ... |