59{
60 if(!std::filesystem::exists(path)) return;
61
62 auto ParseShapeId = [](cv::Mat image, const std::vector<std::vector<cv::Point>> &contours, const std::vector<cv::Vec4i> &hierarchy, int root_idx) -> uint32_t {
63 cv::Mat mask = cv::Mat::zeros(image.size(), CV_8UC1);
64
65 cv::drawContours(mask, contours, root_idx, 255, cv::FILLED);
66
67 int child = hierarchy[root_idx][2];
68 while (child != -1) {
69 cv::drawContours(mask, contours, child, 0, cv::FILLED);
70 child = hierarchy[child][0];
71 }
72 std::vector<cv::Vec3b> pixels;
73 for (int y = 0; y < image.rows; ++y) {
74 for (int x = 0; x < image.cols; ++x) {
75 if (mask.at<uchar>(y, x)) { pixels.push_back(image.at<cv::Vec3b>(y, x)); }
76 }
77 }
78
79 std::map<cv::Vec3b, int, std::function<bool(const cv::Vec3b &, const cv::Vec3b &)>> colorCount(
80 [](const cv::Vec3b &a, const cv::Vec3b &b) { return std::lexicographical_compare(a.val, a.val + 3, b.val, b.val + 3); });
81
82 for (auto &c : pixels) colorCount[c]++;
83
84 cv::Vec3b main_color;
85 int max_count = 0;
86 int total_count = 0;
87 for (const auto &kv : colorCount) {
88 if (kv.second > max_count) {
89 max_count = kv.second;
90 main_color = kv.first;
91 }
92 total_count += kv.second;
93 }
94
95 SkipIdHelper helper{main_color[2], main_color[1], main_color[0]};
97 return (max_count * 2 > total_count) ? helper.value : 0;
98 };
99
103 int preffered_w{FromDIP(400)}, preffered_h{FromDIP(400)};
104 cv::Mat src_image = cv::imread(path, cv::IMREAD_UNCHANGED);
105 cv::cvtColor(src_image, src_image, cv::COLOR_BGRA2BGR);
106 float zoom_x{static_cast<float>(preffered_w) / src_image.cols};
107 float zoom_y{static_cast<float>(preffered_h) / src_image.rows};
108 float image_scale{0};
109 if (abs(zoom_x - 1) > abs(zoom_y - 1))
110 image_scale = zoom_x;
111 else
112 image_scale = zoom_y;
115 std::vector<cv::Mat> channels;
116 cv::Mat gray;
117 cv::cvtColor(
pick_image_, gray, cv::COLOR_BGR2GRAY);
118 cv::Mat mask;
119 cv::threshold(gray, mask, 0, 255, cv::THRESH_BINARY);
120 std::vector<std::vector<cv::Point>> pick_counters;
121 std::vector<cv::Vec4i> hierarchy;
122 cv::findContours(mask, pick_counters, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_TC89_KCOS);
123 auto compute_depth = [&](int idx) {
124 int depth = 0;
125 while (hierarchy[idx][3] != -1) {
126 depth++;
127 idx = hierarchy[idx][3];
128 }
129 return depth;
130 };
131 for (int i = 0; i < pick_counters.size(); ++i) {
132 int depth = compute_depth(i);
133 int parent = hierarchy[i][3];
134 if (parent != -1) continue;
135
136 auto id = ParseShapeId(
pick_image_, pick_counters, hierarchy, i);
137 if (id > 0) {
138 std::vector<FloatPoint> flat_points;
139 std::vector<std::vector<FloatPoint>> polygon;
140
141
142 {
143 polygon.emplace_back();
144 for (const auto &pt : pick_counters[i]) {
146 polygon.back().push_back(fp);
147 flat_points.push_back(fp);
148 }
149 int child = hierarchy[i][2];
150 while (child != -1) {
151 polygon.emplace_back();
152 for (const auto &pt : pick_counters[child]) {
154 polygon.back().push_back(fp);
155 flat_points.push_back(fp);
156 }
157 child = hierarchy[child][0];
158 }
159 std::vector<uint32_t> indices = mapbox::earcut<uint32_t>(polygon);
160 std::vector<FloatPoint> final_counter;
161 for (size_t j = 0; j < indices.size(); j += 3) {
162 final_counter.push_back(flat_points[indices[j]]);
163 final_counter.push_back(flat_points[indices[j + 1]]);
164 final_counter.push_back(flat_points[indices[j + 2]]);
165 }
166
168 }
169
170 {
172 int child = hierarchy[i][2];
173 while (child != -1) {
174 pick_parts_[id].emplace_back(pick_counters[child]);
175 child = hierarchy[child][0];
176 }
177 }
179 }
180 }
181}
std::unordered_map< uint32_t, PartState > parts_state_
Definition SkipPartCanvas.hpp:101
std::unordered_map< uint32_t, std::vector< std::vector< cv::Point > > > pick_parts_
Definition SkipPartCanvas.hpp:100
std::unordered_map< uint32_t, std::vector< std::vector< FloatPoint > > > parts_triangles_
Definition SkipPartCanvas.hpp:99
double image_view_scale_
Definition SkipPartCanvas.hpp:111
std::array< Coord, 2 > FloatPoint
Definition SkipPartCanvas.hpp:33
@ psUnCheck
Definition PartSkipCommon.hpp:10