Skip to content

Commit

Permalink
## v1.5.6 (#35)
Browse files Browse the repository at this point in the history
* append lvis support

* support separate eval

* restyle _prepare functions. speedup!

* add lvis example

* update history
  • Loading branch information
MiXaiLL76 authored Jun 19, 2024
1 parent c0dec59 commit 1430906
Show file tree
Hide file tree
Showing 13 changed files with 728 additions and 303 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Code examples for using the library are available on the [Wiki](https://github.c
- [Eval example](https://nbviewer.org/github/MiXaiLL76/faster_coco_eval/blob/main/examples/eval_example.ipynb)
- [Curve example](https://nbviewer.org/github/MiXaiLL76/faster_coco_eval/blob/main/examples/curve_example.ipynb)
- [CED Keypoint example](https://nbviewer.org/github/MiXaiLL76/faster_coco_eval/blob/main/examples/ced_example.ipynb)
- [LVIS example](https://nbviewer.org/github/MiXaiLL76/faster_coco_eval/blob/main/examples/lvis_example.ipynb)

## Update history

Expand Down
74 changes: 51 additions & 23 deletions csrc/faster_eval_api/coco_eval/cocoeval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ namespace coco_eval
const int num_detections = detection_sorted_indices.size();
// std::vector<uint64_t> ground_truth_matches(
// num_iou_thresholds * num_ground_truth, 0);
std::vector<uint64_t> &ground_truth_matches = results->ground_truth_matches;
std::vector<int64_t> &ground_truth_matches = results->ground_truth_matches;
ground_truth_matches.resize(num_iou_thresholds * num_ground_truth, 0);

std::vector<uint64_t> &ground_truth_orig_id = results->ground_truth_orig_id;
std::vector<int64_t> &ground_truth_orig_id = results->ground_truth_orig_id;
ground_truth_orig_id.resize(num_iou_thresholds * num_ground_truth, -1);

std::vector<uint64_t> &detection_matches = results->detection_matches;
std::vector<int64_t> &detection_matches = results->detection_matches;

std::vector<bool> &detection_ignores = results->detection_ignores;
std::vector<bool> &ground_truth_ignores = results->ground_truth_ignores;
Expand Down Expand Up @@ -150,7 +150,7 @@ namespace coco_eval
detection_ignores[t * num_detections + d] =
detection_ignores[t * num_detections + d] ||
(detection_matches[t * num_detections + d] == 0 &&
(detection.area < area_range[0] || detection.area > area_range[1]));
(detection.area < area_range[0] || detection.area > area_range[1] || detection.lvis_mark));
}
}

Expand Down Expand Up @@ -532,47 +532,75 @@ namespace coco_eval

time_t rawtime;
struct tm local_time;
std::array<char, 200> buffer;
char buffer[200];
time(&rawtime);

#ifdef _WIN32
localtime_s(&local_time, &rawtime);
#else
localtime_r(&rawtime, &local_time);
#endif
strftime(
buffer.data(), 200, "%Y-%m-%d %H:%num_max_detections:%S", &local_time);
strftime(buffer, 200, "%Y-%m-%d %H:%S", &local_time);

int evaluations_size = static_cast<int>(evaluations.size());

std::vector<uint64_t> out_detection_matches = {};
std::vector<uint64_t> out_ground_truth_matches = {};
std::vector<uint64_t> out_ground_truth_orig_id = {};
std::vector<int64_t> out_detection_matches = {};
std::vector<int64_t> out_ground_truth_matches = {};
std::vector<int64_t> out_ground_truth_orig_id = {};
for (auto eval : evaluations)
{
out_detection_matches.insert(out_detection_matches.end(), eval.detection_matches.begin(), eval.detection_matches.end());
out_ground_truth_matches.insert(out_ground_truth_matches.end(), eval.ground_truth_matches.begin(), eval.ground_truth_matches.end());
out_ground_truth_orig_id.insert(out_ground_truth_orig_id.end(), eval.ground_truth_orig_id.begin(), eval.ground_truth_orig_id.end());
}

std::vector<int64_t> counts = {
num_iou_thresholds,
num_recall_thresholds,
num_categories,
num_area_ranges,
num_max_detections};

std::vector<int64_t> recall_counts = {
num_iou_thresholds,
num_categories,
num_area_ranges,
num_max_detections};
std::vector<int64_t> matches_shape = {num_iou_thresholds * num_area_ranges, -1};

return py::dict(
"params"_a = params,
"counts"_a = std::vector<int64_t>({num_iou_thresholds,
num_recall_thresholds,
num_categories,
num_area_ranges,
num_max_detections}),
"date"_a = buffer,
"precision"_a = precisions_out,
"recall"_a = recalls_out,
"scores"_a = scores_out,
"detection_matches"_a = out_detection_matches,
// "detection_ignores"_a = out_detection_ignores,
"ground_truth_matches"_a = out_ground_truth_matches,
"ground_truth_orig_id"_a = out_ground_truth_orig_id,
"counts"_a = counts,
"date"_a = py::str(buffer),

// precision and scores are num_iou_thresholds X num_recall_thresholds X num_categories X num_area_ranges X num_max_detections
"precision"_a = py::array(precisions_out.size(), precisions_out.data()).reshape(counts),
"scores"_a = py::array(scores_out.size(), scores_out.data()).reshape(counts),

// recall is num_iou_thresholds X num_categories X num_area_ranges X num_max_detections
"recall"_a = py::array(recalls_out.size(), recalls_out.data()).reshape(recall_counts),

"detection_matches"_a = py::array(out_detection_matches.size(), out_detection_matches.data()).reshape(matches_shape),
"ground_truth_matches"_a = py::array(out_ground_truth_matches.size(), out_ground_truth_matches.data()).reshape(matches_shape),
"ground_truth_orig_id"_a = py::array(out_ground_truth_orig_id.size(), out_ground_truth_orig_id.data()).reshape(matches_shape),
"evaluations_size"_a = evaluations_size);
}

py::dict EvaluateAccumulate(
const py::object &params,
const ImageCategoryInstances<std::vector<double>> &image_category_ious,
const ImageCategoryInstances<InstanceAnnotation> &
image_category_ground_truth_instances,
const ImageCategoryInstances<InstanceAnnotation> &
image_category_detection_instances)
{
const std::vector<int> max_detections = list_to_vec<int>(params.attr("maxDets"));
const std::vector<std::array<double, 2>> area_ranges = list_to_vec<std::array<double, 2>>(params.attr("areaRng"));
const std::vector<double> iou_thresholds = list_to_vec<double>(params.attr("iouThrs"));

std::vector<ImageEvaluation> result = EvaluateImages(area_ranges, max_detections.back(), iou_thresholds, image_category_ious, image_category_ground_truth_instances, image_category_detection_instances);
return Accumulate(params, result);
}
} // namespace COCOeval

} // namespace coco_eval
20 changes: 15 additions & 5 deletions csrc/faster_eval_api/coco_eval/cocoeval.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ namespace coco_eval
double score,
double area,
bool is_crowd,
bool ignore)
: id{id}, score{score}, area{area}, is_crowd{is_crowd}, ignore{ignore} {}
bool ignore,
bool lvis_mark)
: id{id}, score{score}, area{area}, is_crowd{is_crowd}, ignore{ignore}, lvis_mark{lvis_mark} {}
uint64_t id;
double score = 0.;
double area = 0.;
bool is_crowd = false;
bool ignore = false;
bool lvis_mark = false;
};

// Stores intermediate results for evaluating detection results for a single
Expand All @@ -39,10 +41,10 @@ namespace coco_eval
{
// For each of the D detected instances, the id of the matched ground truth
// instance, or 0 if unmatched
std::vector<uint64_t> detection_matches;
std::vector<int64_t> detection_matches;

std::vector<uint64_t> ground_truth_matches;
std::vector<uint64_t> ground_truth_orig_id;
std::vector<int64_t> ground_truth_matches;
std::vector<int64_t> ground_truth_orig_id;
// The detection score of each of the D detected instances
std::vector<double> detection_scores;

Expand Down Expand Up @@ -90,5 +92,13 @@ namespace coco_eval
const py::object &params,
const std::vector<ImageEvaluation> &evalutations);

py::dict EvaluateAccumulate(
const py::object &params,
const ImageCategoryInstances<std::vector<double>> &image_category_ious,
const ImageCategoryInstances<InstanceAnnotation> &
image_category_ground_truth_instances,
const ImageCategoryInstances<InstanceAnnotation> &
image_category_detection_instances);

} // namespace COCOeval
} // namespace coco_eval
3 changes: 2 additions & 1 deletion csrc/faster_eval_api/faster_eval_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ namespace coco_eval
m.def("get_compiler_version", &get_compiler_version, "get_compiler_version");
m.def("COCOevalAccumulate", &COCOeval::Accumulate, "COCOeval::Accumulate");
m.def("COCOevalEvaluateImages", &COCOeval::EvaluateImages, "COCOeval::EvaluateImages");
pybind11::class_<COCOeval::InstanceAnnotation>(m, "InstanceAnnotation").def(pybind11::init<uint64_t, double, double, bool, bool>());
m.def("COCOevalEvaluateAccumulate", &COCOeval::EvaluateAccumulate, "COCOeval::EvaluateAccumulate");
pybind11::class_<COCOeval::InstanceAnnotation>(m, "InstanceAnnotation").def(pybind11::init<uint64_t, double, double, bool, bool, bool>());
pybind11::class_<COCOeval::ImageEvaluation>(m, "ImageEvaluation").def(pybind11::init<>());

#ifdef VERSION_INFO
Expand Down
Loading

0 comments on commit 1430906

Please sign in to comment.