QImage visualize_parts(const PartConfig &conf, const PartWindowParam &window_param, const Annotation &annotation) { assert(annotation.size() > 0); double scale = (annotation[0].bottom() - annotation[0].top())/window_param.train_object_height(); cout << "visualize_parts, scale: " << scale << endl; QImage _img; cout << "loading image" << endl; assert(_img.load(annotation.imageName().c_str())); QImage img = _img.convertToFormat(QImage::Format_RGB32); QPainter painter(&img); for (int pidx = 0; pidx < conf.part_size(); ++pidx) { PartBBox part_bbox; get_part_bbox(annotation[0], conf.part(pidx), part_bbox, scale); int coloridx = 1; int pen_width = 2; if (conf.part(pidx).is_detect()) { if (conf.part(pidx).is_root()) draw_bbox(painter, part_bbox, 2, pen_width); else draw_bbox(painter, part_bbox, coloridx, pen_width); } else draw_bbox(painter, part_bbox, -1); // only draw center point and axis (skip bounding box) } cout << "done" << endl; return img; }
int get_app_group_idx(const PartConfig &part_conf, int pid) { for (int agidx = 0; agidx < part_conf.app_group_size(); ++agidx) for (int idx = 0; idx < part_conf.app_group(agidx).part_id_size(); ++idx) { if (part_conf.app_group(agidx).part_id(idx) == pid) return agidx; } return -1; }
int pidx_from_pid(const PartConfig &part_conf, int pid) { for (int pidx = 0; pidx < part_conf.part_size(); ++pidx) { assert(part_conf.part(pidx).has_part_id()); if (part_conf.part(pidx).part_id() == pid) return pidx; } assert(false && "part id not found"); return -1; }
/** compute the average size of part bounding box */ void compute_part_window_param(const AnnotationList &annolist, const PartConfig &partconf, PartWindowParam &windowparam) { int nParts = partconf.part_size(); int nImages = annolist.size(); /** compute reference object height, use only rectangles that have all parts annotated (rectangles with missing parts are sometimes smaller then reference object height) */ double train_object_height = 0; int n = 0; for (int imgidx = 0; imgidx < nImages; ++imgidx) { int nRects = annolist[imgidx].size(); for (int ridx = 0; ridx < nRects; ++ridx) { bool bHasAllParts = true; //for (int pidx = 0; pidx < partconf.part_size(); ++pidx) /** TEMPORARY !!!! Needed for experiments on HumanEva when training is done on the combined set of images from Buffy, Ramanan, and TUD Pedestrians */ // assert(partconf.part_size() == 10); // for (int pidx = 0; pidx < 6; ++pidx) // if (!annorect_has_part(annolist[imgidx][ridx], partconf.part(pidx))) { // bHasAllParts = false; // break; // } if (bHasAllParts) { train_object_height += abs(annolist[imgidx][ridx].bottom() - annolist[imgidx][ridx].top()); ++n; } }// rectangles }// images assert(n > 0); train_object_height /= n; windowparam.set_train_object_height(train_object_height); cout << "train_object_height: " << train_object_height << endl; /** determine average dimensions of the parts */ windowparam.clear_part(); for (int pidx = 0; pidx < nParts; ++pidx) { PartWindowParam::PartParam *pPartParam = windowparam.add_part(); pPartParam->set_part_id(partconf.part(pidx).part_id()); pPartParam->set_window_size_x(0); pPartParam->set_window_size_y(0); pPartParam->set_pos_offset_x(0); pPartParam->set_pos_offset_y(0); /** begin debug */ cout << "part_pos_size:" << partconf.part(pidx).part_pos_size() << endl; for (int idx = 0; idx < partconf.part(pidx).part_pos_size(); ++idx) cout << "\tapidx: " << partconf.part(pidx).part_pos(idx) << endl; /** end debug */ if (partconf.part(pidx).is_detect()) { double sum_window_size_x = 0; double sum_window_size_y = 0; double sum_pos_offset_x = 0; double sum_pos_offset_y = 0; int nAnnoRects = 0; for (int imgidx = 0; imgidx < nImages; ++imgidx) { int nRects = annolist[imgidx].size(); for (int ridx = 0; ridx < nRects; ++ridx) { // cout << "pidx: " << pidx << // " imgidx: " << imgidx << // ", ridx: " << ridx << // ", has_part: " << annorect_has_part(annolist[imgidx][ridx], partconf.part(pidx)) << endl; if (annorect_has_part(annolist[imgidx][ridx], partconf.part(pidx))) { PartBBox bbox; get_part_bbox(annolist[imgidx][ridx], partconf.part(pidx), bbox); sum_window_size_x += (bbox.max_proj_x - bbox.min_proj_x); sum_window_size_y += (bbox.max_proj_y - bbox.min_proj_y); sum_pos_offset_x += bbox.min_proj_x; sum_pos_offset_y += bbox.min_proj_y; ++nAnnoRects; } }// rects }// images assert(nAnnoRects > 0); cout << "processed rects: " << nAnnoRects << endl; pPartParam->set_window_size_x((int)(sum_window_size_x/nAnnoRects)); pPartParam->set_window_size_y((int)(sum_window_size_y/nAnnoRects)); /* average offset of part position with respect to top/left corner */ pPartParam->set_pos_offset_x((int)(-sum_pos_offset_x/nAnnoRects)); pPartParam->set_pos_offset_y((int)(-sum_pos_offset_y/nAnnoRects)); } }// parts /** compute offset of the root part with respect to bounding box center */ int rootpart_idx = -1; for (int pidx = 0; pidx < nParts; ++pidx) { if (partconf.part(pidx).is_root()) { rootpart_idx = pidx; break; } } assert(rootpart_idx >=0 && "missing root part"); double_vector bbox_offset = boost_math::double_zero_vector(2); int total_rects = 0; for (int imgidx = 0; imgidx < nImages; ++imgidx) { for (uint ridx = 0; ridx < annolist[imgidx].size(); ++ridx) { bool bHasAllParts = true; //for (int pidx = 0; pidx < partconf.part_size(); ++pidx) // TEMPORARY !!!! needed for training of HumanEva on combined training set // assert(partconf.part_size() == 10); // for (int pidx = 0; pidx < 6; ++pidx) // if (!annorect_has_part(annolist[imgidx][ridx], partconf.part(pidx))) { // bHasAllParts = false; // break; // } //if (annorect_has_part(annolist[imgidx][ridx], partconf.part(rootpart_idx))) { if (bHasAllParts) { PartBBox bbox; get_part_bbox(annolist[imgidx][ridx], partconf.part(rootpart_idx), bbox); double_vector bbox_center(2); bbox_center(0) = 0.5*(annolist[imgidx][ridx].left() + annolist[imgidx][ridx].right()); bbox_center(1) = 0.5*(annolist[imgidx][ridx].top() + annolist[imgidx][ridx].bottom()); bbox_offset += bbox_center - bbox.part_pos; ++total_rects; } } } bbox_offset /= total_rects; windowparam.set_bbox_offset_x(bbox_offset(0)); windowparam.set_bbox_offset_y(bbox_offset(1)); }