blob: 946859d8849c484e4142dfda5082c3949b1dac90 [file] [log] [blame]
Parker Schuh6691f192017-01-14 17:01:02 -08001#include "aos/vision/blob/range_image.h"
2
3#include <math.h>
4#include <algorithm>
5
6namespace aos {
7namespace vision {
8
9void DrawRangeImage(const RangeImage &rimg, ImagePtr outbuf, PixelRef color) {
10 for (int i = 0; i < (int)rimg.ranges().size(); ++i) {
11 int y = rimg.min_y() + i;
12 for (ImageRange rng : rimg.ranges()[i]) {
13 for (int x = rng.st; x < rng.ed; ++x) {
14 outbuf.get_px(x, y) = color;
15 }
16 }
17 }
18}
19
20RangeImage MergeRangeImage(const BlobList &blobl) {
21 if (blobl.size() == 1) return blobl[0];
22
23 int min_y = blobl[0].min_y();
24 for (const RangeImage &subrimg : blobl) {
25 if (min_y > subrimg.min_y()) min_y = subrimg.min_y();
26 }
27 std::vector<std::vector<ImageRange>> ranges;
28 int i = min_y;
29 while (true) {
30 std::vector<ImageRange> range_lst;
31 int n_missing = 0;
32 for (const RangeImage &subrimg : blobl) {
33 if (subrimg.min_y() > i) continue;
34 int ri = i - subrimg.min_y();
35 if (ri < (int)subrimg.ranges().size()) {
36 for (const auto &span : subrimg.ranges()[ri]) {
37 range_lst.emplace_back(span);
38 }
39 } else {
40 ++n_missing;
41 }
42 }
43 std::sort(range_lst.begin(), range_lst.end());
44 ranges.emplace_back(std::move(range_lst));
45 if (n_missing == static_cast<int>(blobl.size()))
46 return RangeImage(min_y, std::move(ranges));
47 ++i;
48 }
49}
50
51std::string ShortDebugPrint(const BlobList &blobl) {
52 RangeImage rimg = MergeRangeImage(blobl);
53 std::string out;
54 out += "{";
55 out += "min_y: " + std::to_string(rimg.min_y());
56 for (const auto &line : rimg) {
57 out += "{";
58 for (const auto &span : line) {
59 out +=
60 "{" + std::to_string(span.st) + ", " + std::to_string(span.ed) + "},";
61 }
62 out += "},";
63 }
64 out += "}";
65 return out;
66}
67
68void DebugPrint(const BlobList &blobl) {
69 RangeImage rimg = MergeRangeImage(blobl);
70 int minx = rimg.ranges()[0][0].st;
71 int maxx = 0;
72 for (const auto &range : rimg.ranges()) {
73 for (const auto &span : range) {
74 if (span.st < minx) minx = span.st;
75 if (span.ed > maxx) maxx = span.ed;
76 }
77 }
Parker Schuh309dd722017-02-25 11:31:18 -080078 printf("maxx: %d minx: %d\n", maxx, minx);
Parker Schuh6691f192017-01-14 17:01:02 -080079 char buf[maxx - minx];
80 for (const auto &range : rimg.ranges()) {
81 int i = minx;
82 for (const auto &span : range) {
83 for (; i < span.st; ++i) buf[i - minx] = ' ';
84 for (; i < span.ed; ++i) buf[i - minx] = '#';
85 }
86 for (; i < maxx; ++i) buf[i - minx] = ' ';
Parker Schuh309dd722017-02-25 11:31:18 -080087 printf("%.*s\n", maxx - minx, buf);
Parker Schuh6691f192017-01-14 17:01:02 -080088 }
89}
90
91void RangeImage::Flip(int image_width, int image_height) {
92 std::reverse(ranges_.begin(), ranges_.end());
93 for (std::vector<ImageRange> &range : ranges_) {
94 std::reverse(range.begin(), range.end());
95 for (ImageRange &interval : range) {
96 int tmp = image_width - interval.ed;
97 interval.ed = image_width - interval.st;
98 interval.st = tmp;
99 }
100 }
101
102 min_y_ = image_height - static_cast<int>(ranges_.size()) - min_y_;
103}
104
105int RangeImage::npixels() {
106 if (npixelsc_ > 0) {
107 return npixelsc_;
108 }
109 npixelsc_ = calc_area();
110 return npixelsc_;
111}
112
113int RangeImage::calc_area() const {
114 int area = 0;
115 for (auto &range : ranges_) {
116 for (auto &interval : range) {
117 area += interval.calc_width();
118 }
119 }
120 return area;
121}
122
123} // namespace vision
124} // namespace aos