|
6 | 6 |
|
7 | 7 | #include <cmath> |
8 | 8 | #include <array> |
| 9 | +#include <list> |
9 | 10 | #include <map> |
10 | 11 | #include "Common/Cpp/PrettyPrint.h" |
11 | 12 | //#include "Kernels/Waterfill/Kernels_Waterfill.h" |
@@ -127,25 +128,80 @@ uint8_t TeraCardReader::stars( |
127 | 128 |
|
128 | 129 | ImageViewRGB32 cropped = extract_box_reference(screen, m_stars); |
129 | 130 |
|
130 | | - { |
131 | | - ImageStats background = image_stats(extract_box_reference(screen, ImageFloatBox{0.55, 0.62, 0.20, 0.03})); |
132 | | - Color background_average = background.average.round(); |
| 131 | + ImageViewRGB32 background = extract_box_reference(screen, ImageFloatBox{0.55, 0.62, 0.20, 0.03}); |
| 132 | +// background.save("background.png"); |
| 133 | + ImageStats background_stats = image_stats(background); |
| 134 | + Color background_average = background_stats.average.round(); |
| 135 | + |
| 136 | + // Iterate through several difference distance filters and find how many |
| 137 | + // possible stars are in each one. Then do a majority vote. |
| 138 | + const std::vector<double> DISTANCES{70, 80, 90, 100, 110, 120, 130}; |
| 139 | + |
| 140 | + std::map<size_t, size_t> count_map; |
133 | 141 |
|
134 | | - PackedBinaryMatrix matrix = compress_rgb32_to_binary_euclidean(cropped, (uint32_t)background_average, 100); |
| 142 | + for (double distance : DISTANCES){ |
| 143 | + PackedBinaryMatrix matrix = compress_rgb32_to_binary_euclidean(cropped, (uint32_t)background_average, distance); |
135 | 144 |
|
136 | 145 | matrix.invert(); |
137 | 146 | // cout << matrix.dump() << endl; |
138 | 147 | std::unique_ptr<WaterfillSession> session = make_WaterfillSession(matrix); |
139 | 148 | auto iter = session->make_iterator(100); |
140 | 149 | WaterfillObject object; |
141 | | - size_t count = 0; |
| 150 | + |
| 151 | + std::list<ImagePixelBox> objects; |
142 | 152 | while (iter->find_next(object, false)){ |
143 | | -// extract_box_reference(cropped, object).save("test-" + std::to_string(count) + ".png"); |
144 | | - count++; |
| 153 | + // Attempt to merge with existing objects. |
| 154 | + ImagePixelBox current(object); |
| 155 | + bool changed; |
| 156 | + do{ |
| 157 | + changed = false; |
| 158 | + for (auto iter1 = objects.begin(); iter1 != objects.end();){ |
| 159 | + if (current.overlaps_with(*iter1)){ |
| 160 | + changed = true; |
| 161 | + current.merge_with(*iter1); |
| 162 | + objects.erase(iter1); |
| 163 | + break; |
| 164 | + }else{ |
| 165 | + ++iter1; |
| 166 | + } |
| 167 | + } |
| 168 | + }while (changed); |
| 169 | + objects.emplace_back(std::move(current)); |
145 | 170 | } |
146 | | - if (1 <= count && count <= 7){ |
147 | | - return (uint8_t)count; |
| 171 | + |
| 172 | +#if 0 |
| 173 | + static size_t count = 0; |
| 174 | + for (const ImagePixelBox& obj : objects){ |
| 175 | + extract_box_reference(cropped, obj).save("test-" + std::to_string(count++) + ".png"); |
148 | 176 | } |
| 177 | + cout << "objects.size() = " << objects.size() << endl; |
| 178 | +#endif |
| 179 | + |
| 180 | + |
| 181 | + count_map[objects.size()]++; |
| 182 | + } |
| 183 | + |
| 184 | + count_map.erase(0); |
| 185 | + |
| 186 | + if (count_map.empty()){ |
| 187 | + dump_image(logger, info, "ReadStarsFailed", screen); |
| 188 | + return 0; |
| 189 | + } |
| 190 | + |
| 191 | + auto best = count_map.begin(); |
| 192 | + for (auto iter = count_map.begin(); iter != count_map.end(); ++iter){ |
| 193 | + if (iter->first == 0){ |
| 194 | + continue; |
| 195 | + } |
| 196 | + if (iter->second > best->second){ |
| 197 | + best = iter; |
| 198 | + } |
| 199 | + } |
| 200 | + |
| 201 | + size_t stars = best->first; |
| 202 | + |
| 203 | + if (1 <= stars && stars <= 7){ |
| 204 | + return (uint8_t)stars; |
149 | 205 | } |
150 | 206 |
|
151 | 207 | dump_image(logger, info, "ReadStarsFailed", screen); |
|
0 commit comments