48 int numParts()
const {
return (
int)locations.size(); }
51 unsigned size()
const {
return locations.size() + occluded.size() + 1; }
52 bool empty()
const {
return locations.empty(); }
54 void resize(
unsigned numParts);
56 void print(std::ostream& os = std::cout)
const;
60 const cv::Point& operator[](
unsigned indx)
const {
return locations[indx]; }
68 double dx, dy, dx2, dy2;
73 dx(a), dy(b), dx2(c), dy2(d) { }
75 dx(c.dx), dy(c.dy), dx2(c.dx2), dy2(c.dy2) { }
79 const char *
type()
const {
return "drwnDeformationCost"; }
81 bool save(drwnXMLNode& xml)
const;
82 bool load(drwnXMLNode& xml);
84 inline double cost(
const cv::Point& p,
const cv::Point& q)
const {
85 const double deltaX = fabs((
double)(p.x - q.x));
86 const double deltaY = fabs((
double)(p.y - q.y));
87 return ((dx + dx2 * deltaX) * deltaX + (dy + dy2 * deltaY) * deltaY);
104 static int MESSAGE_PASSING_SCALE;
105 static double DEFAULT_LAMBDA;
106 static double DEFAULT_OCCLUSION_COST;
110 double _occlusionCost;
116 cv::Mat _centroidPrior;
117 vector<pair<cv::Mat, cv::Mat> > _partCosts;
118 vector<cv::Point> _partOffsets;
119 vector<drwnDeformationCost> _pairwiseCosts;
126 void setCentroidPrior(
const cv::Mat& centroidPrior = cv::Mat());
127 void setPartCosts(
int partId,
const cv::Mat& matchingCost,
129 const cv::Mat& occlusionCost = cv::Mat());
136 cv::Mat energyLandscape()
const;
141 const cv::Mat& msgIn = cv::Mat())
const;
154 static int MATCH_MODE;
164 drwnPart(
const cv::Size& extent,
unsigned channels = 1);
169 int channels()
const {
return (
int)_weights.size(); }
170 int width()
const {
return _extent.width; }
171 int height()
const {
return _extent.height; }
174 const char *
type()
const {
return "drwnPart"; }
177 bool save(drwnXMLNode& xml)
const;
178 bool load(drwnXMLNode& xml);
182 void setExtent(
const cv::Size& extent) { _extent = extent; }
183 void setExtent(
int width,
int height) { _extent = cv::Size(width, height); }
184 void setWeights(
const cv::Mat& weights);
185 void setWeights(
const vector<cv::Mat>& weights);
186 void setOffset(
const cv::Point& offset) { _offset = offset; }
188 const vector<cv::Mat>& getWeights()
const {
return _weights; }
189 const cv::Point& getOffset()
const {
return _offset; }
193 cv::Mat unaryCosts(
const cv::Mat& features)
const;
194 cv::Mat unaryCosts(
const vector<cv::Mat>& features)
const;
195 double pairwiseCost(
const cv::Point& x,
const cv::Point& c)
const;
201 friend double overlap(
const drwnPart& partA,
const cv::Point& locationA,
202 const drwnPart& partB,
const cv::Point& locationB);
218 vector<drwnPart *> _parts;
226 int numParts()
const {
return (
int)_parts.size(); }
227 const cv::Size& getBaseSize()
const {
return _baseSize; }
228 void setBaseSize(
const cv::Size& baseSize) { _baseSize = baseSize; }
230 virtual void clear();
231 bool save(drwnXMLNode& xml)
const;
232 bool load(drwnXMLNode& xml);
243 const cv::Point ¢roidPrior)
const;
245 const vector<cv::Mat>& partPriors,
const cv::Mat& centroidPrior)
const;
247 double& bestScale,
double startScale,
double endScale,
int numLevels)
const;
252 cv::Mat energyLandscape(
const cv::Mat& img)
const;
255 void slidingWindowDetections(
const cv::Mat& img,
drwnObjectList& detections)
const;
256 void slidingWindowDetections(
const cv::Mat& img,
drwnObjectList& detections,
257 int numLevelsPerOctave)
const;
260 cv::Mat showMAPPartLocations(
const cv::Mat& img)
const;
261 cv::Mat showMAPPartLocations(
const cv::Mat& img,
263 double energy = DRWN_DBL_MAX,
double scale = 1.0)
const;
264 cv::Mat showPartEnergyLandscape(
const cv::Mat& img)
const;
268 drwnPart *operator[](
unsigned indx) {
return _parts[indx]; }
269 const drwnPart *operator[](
unsigned indx)
const {
return _parts[indx]; }
273 virtual vector<cv::Mat> computeMatchingCosts(
const cv::Mat& img)
const = 0;
276 static vector<pair<cv::Point, cv::Size> > initializePartLocations(
int nParts,
277 const cv::Size& imgSize);
280 static cv::Scalar partColorMap(
int v);
295 for (
unsigned i = 0; i < _models.size(); i++) {
301 bool empty()
const {
return _models.empty(); }
302 int size()
const {
return (
int)_models.size(); }
305 for (
int i = 0; i < (int)_models.size(); i++) {
311 void write(
const char *filename)
const {
312 DRWN_ASSERT(filename != NULL);
315 for (
unsigned i = 0; i < _models.size(); i++) {
317 _models[i]->save(*child);
319 ofstream ofs(filename);
321 DRWN_ASSERT_MSG(!ofs.fail(),
"could not write XML file " << filename);
325 void read(
const char *filename) {
326 DRWN_ASSERT(filename != NULL);
333 for (drwnXMLNode *node = xml.first_node(
"drwnPartsModel"); node != NULL;
334 node = node->next_sibling(
"drwnPartsModel")) {
344 void add(T *model) { _models.push_back(model); }
345 void copy(
const T *model) { _models.push_back(model->clone()); }
348 std::pair<int, double> inference(
const cv::Mat& img,
drwnPartsAssignment& mapAssignment)
const {
350 std::pair<int, double> bestModel(-1, DRWN_DBL_MAX);
352 mapAssignment.clear();
353 for (
int i = 0; i < (int)_models.size(); i++) {
355 double energy = _models[i]->inference(img, assignment);
356 DRWN_LOG_DEBUG(
"...component " << i <<
" has energy " << energy);
357 if (energy < bestModel.second) {
358 bestModel = make_pair(i, energy);
359 mapAssignment = assignment;
363 DRWN_ASSERT(_models.empty() || (bestModel.first != -1));
370 const vector<vector<cv::Mat> >& partPriors,
const cv::Mat& centroidPrior)
const {
372 std::pair<int, double> bestModel(-1, DRWN_DBL_MAX);
374 mapAssignment.clear();
375 for (
int i = 0; i < (int)_models.size(); i++) {
377 double energy = _models[i]->inference(img, assignment, partPriors[i], centroidPrior);
378 DRWN_LOG_DEBUG(
"...component " << i <<
" has energy " << energy);
379 if (energy < bestModel.second) {
380 bestModel = make_pair(i, energy);
381 mapAssignment = assignment;
385 DRWN_ASSERT(_models.empty() || (bestModel.first != -1));
392 double& bestScale,
double startScale,
double endScale,
int numLevels)
const {
394 DRWN_ASSERT((endScale <= startScale) && (numLevels > 0));
395 const double scaleFactor = exp(log(endScale / startScale) / (
double)numLevels);
398 std::pair<int, double> bestModel(-1, DRWN_DBL_MAX);
399 mapAssignment.clear();
401 cv::Mat scaledImage(img.clone());
403 for (
int i = 0; i < numLevels; i++) {
405 std::pair<int, double> result = inference(scaledImage, assignment);
406 if (result.second < bestModel.second) {
408 bestScale = (double)img.cols / (
double)scaledImage.cols;
409 mapAssignment = assignment;
412 if ((scaleFactor * scaledImage.rows < 1.0) ||
413 (scaleFactor * scaledImage.cols < 1.0))
break;
416 scaleFactor * scaledImage.cols);
423 std::pair<cv::Mat, cv::Mat> energyLandscape(
const cv::Mat& img)
const {
424 std::pair<cv::Mat, cv::Mat> energy;
425 energy.first = cv::Mat(img.rows, img.cols, CV_32FC1, cv::Scalar(DRWN_FLT_MIN));
426 energy.second = cv::Mat(img.rows, img.cols, CV_32SC1, cv::Scalar(-1));
428 cv::Mat mask(img.rows, img.cols, CV_8UC1);
429 for (
int i = 0; i < (int)_models.size(); i++) {
430 cv::Mat e = _models->energyLandscape(img);
431 cv::compare(energy.first, e, mask, CV_CMP_GT);
432 energy.first.setTo(e, mask);
433 energy.second.setTo(cv::Scalar(i), mask);
440 void slidingWindowDetections(
const cv::Mat& img,
drwnObjectList& detections)
const {
441 for (
int i = 0; i < (int)_models.size(); i++) {
443 _models[i]->slidingWindowDetections(img, d);
444 for (drwnObjectList::iterator it = d.begin(); it != d.end(); ++it) {
447 detections.insert(detections.end(), d.begin(), d.end());
451 void slidingWindowDetections(
const cv::Mat& img,
drwnObjectList& detections,
452 int numLevelsPerOctave)
const {
453 for (
int i = 0; i < (int)_models.size(); i++) {
455 _models[i]->slidingWindowDetections(img, d, numLevelsPerOctave);
456 for (drwnObjectList::iterator it = d.begin(); it != d.end(); ++it) {
459 detections.insert(detections.end(), d.begin(), d.end());
465 T* operator[](
unsigned indx) {
return _models[indx]; }
466 const T* operator[](
unsigned indx)
const {
return _models[indx]; }
479 const char *
type()
const {
return "drwnTemplatePartsModel"; }
483 void learnModel(
int nParts,
const vector<cv::Mat>& imgs);
487 virtual vector<cv::Mat> computeMatchingCosts(
const cv::Mat& img)
const;
494 static int X_STEP_SIZE;
495 static int Y_STEP_SIZE;
503 const char *
type()
const {
return "drwnHOGPartsModel"; }
507 void learnModel(
int nParts,
const vector<cv::Mat>& imgs);
508 void learnModel(
const vector<cv::Size>& partSizes,
509 const vector<pair<cv::Mat, drwnPartsAssignment> >& imgs);
513 virtual vector<cv::Mat> computeMatchingCosts(
const cv::Mat& img)
const;
cv::Point _offset
centroid offset (in pixels)
Definition: drwnPartsModel.h:159
Definition: drwnPartsModel.h:472
vector< bool > occluded
only includes parts
Definition: drwnPartsModel.h:39
drwnXMLNode * drwnAddXMLChildNode(drwnXMLNode &parent, const char *name, const char *value=NULL, bool bCopyName=true)
adds a child node for a given parent (set bCopyName to false if it's a static string) and returns a r...
Definition: drwnXMLParser.cpp:102
List of objects for the same image (see drwnObject)
Definition: drwnObject.h:101
void drwnResizeInPlace(cv::Mat &m, const cv::Size &size, int interpolation=CV_INTER_LINEAR)
resize an image in place
Definition: drwnOpenCVUtils.cpp:463
Definition: drwnPartsModel.h:492
double score
score or multiplier (for constraints)
Definition: drwnPartsModel.h:40
vector< cv::Point > locations
parts locations
Definition: drwnPartsModel.h:38
Helper class for running inference in a (constellation) parts-based model. Supports linear and quadra...
Definition: drwnPartsModel.h:102
Interface for implementing a part-based constellation model (i.e., pictorial structures model) for ob...
Definition: drwnPartsModel.h:215
const drwnPartsModel * model
model that generated this assignment
Definition: drwnPartsModel.h:36
vector< cv::Mat > _weights
template coefficients (in feature space)
Definition: drwnPartsModel.h:158
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnPartsModel.h:174
Mixture of parts models (T must have a parts model interface). Inference returns the best scoring mod...
Definition: drwnPartsModel.h:288
bool drwnIsXMLEmpty(drwnXMLNode &xml)
checks whether an xml document is empty
Definition: drwnXMLParser.cpp:55
drwnDeformationCost _dcost
deformation cost (dx, dy, dx^2, dy^2) (in pixels)
Definition: drwnPartsModel.h:160
Class for holding as assignment to part locations and occlusion variables.
Definition: drwnPartsModel.h:34
drwnPart * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnPartsModel.h:175
drwnXMLNode * drwnParseXMLFile(drwnXMLDoc &xml, const char *filename, const char *tag=NULL)
parse an xml file into xml (loads all data into memory) and return a pointer to the first node (with ...
Definition: drwnXMLParser.cpp:22
cv::Point centroid
centroid location
Definition: drwnPartsModel.h:37
A part is defined as a template over a number of channels (possibly one), an offset from the object c...
Definition: drwnPartsModel.h:152
cv::Size _extent
width and height of template (in pixels)
Definition: drwnPartsModel.h:157
drwnHOGPartsModel * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnPartsModel.h:504
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnPartsModel.h:479
standard Darwin object interface (cloneable and writeable)
Definition: drwnInterfaces.h:72
const char * type() const
returns object type as a string (e.g., Foo::type() { return "Foo"; })
Definition: drwnPartsModel.h:503
drwnTemplatePartsModel * clone() const
returns a copy of the class usually implemented as virtual Foo* clone() { return new Foo(*this); } ...
Definition: drwnPartsModel.h:480
bool operator==(const CvRect &r, const CvRect &s)
equality operator for CvRect objects
Definition: drwnOpenCVUtils.cpp:83