#include #include #include using namespace cv; using namespace std; tuple find_center(int x1, int y1, int width, int height) { return make_tuple(x1 + width/2, y1 + height/2); } tuple find_center_area(int center_x, int center_y, int delta_x, int delta_y) { return make_tuple(center_y - delta_y/2, center_y + delta_y/2, center_x - delta_x/2, center_x + delta_x/2); } tuple find_hole(int center_x, int center_y, int delta_x, int delta_y, int crop_x, int crop_y) { Point top_left(center_x - delta_x/2 + crop_x, center_y - delta_y/2 + crop_y); Point bottom_right(center_x + delta_x/2 + crop_x, center_y + delta_y/2 + crop_y); return make_tuple(top_left, bottom_right); } float color_difference(const Vec3f& color1, const Vec3f& color2) { float diff_h = abs(color1[0] - color2[0]); return diff_h / 180.0f; // HSV hue range is 0-180 in OpenCV } vector> search_MIC_position( const string& input_path, const string& output_path, const vector& standard, int crop_x, int crop_y, int crop_width, int crop_height, int draw_width, int draw_height) { // 读取图像 Mat img = imread(input_path); if (img.empty()) { cerr << "Error loading image: " << input_path << endl; return {}; } // 裁剪图像 int x = crop_x, y = crop_y; int w = img.cols - crop_width, h = img.rows - crop_height; Mat cropped = img(Rect(x, y, w, h)); // 转换为HSV Mat hsv; cvtColor(cropped, hsv, COLOR_BGR2HSV); // 计算每个微孔尺寸 int cell_height = h / 8, cell_width = w / 12; // 存储所有孔中心 vector> hole_centers(8, vector(12)); for (int i = 0; i < 8; ++i) { for (int j = 0; j < 12; ++j) { int x1 = j * cell_width, y1 = i * cell_height; auto [cx, cy] = find_center(x1, y1, cell_width, cell_height); hole_centers[i][j] = Point(cx, cy); } } // 分组中心点 vector> all_group_center; vector group_9_center, group_10_center; for (auto& row : hole_centers) { all_group_center.emplace_back(row.begin(), row.begin() + 10); group_9_center.push_back(row[10]); group_10_center.push_back(row[11]); } all_group_center.push_back(group_9_center); all_group_center.push_back(group_10_center); // 获取标准孔颜色 Point std_center = all_group_center.back().back(); auto [y1, y2, x1, x2] = find_center_area(std_center.x, std_center.y, 50, 50); Mat std_roi = hsv(Range(y1, y2), Range(x1, x2)); Vec3f standard_color = mean(std_roi); // 颜色范围定义 Vec3b lower_blue(100, 43, 46), upper_blue(124, 255, 255); Vec3b lower_purple(125, 43, 46), upper_purple(155, 255, 255); // 结果存储 vector> marked_positions; Mat output_img = img.clone(); for (int i = 0; i < all_group_center.size(); ++i) { bool mark = false; int index_pink = -1; for (int j = 0; j < all_group_center[i].size(); ++j) { Point hole = all_group_center[i][j]; auto [y1, y2, x1, x2] = find_center_area(hole.x, hole.y, 50, 50); Mat roi = hsv(Range(y1, y2), Range(x1, x2)); Vec3f color = mean(roi); if (standard[i]) { // 蓝色判断 if (color[0] >= lower_blue[0] && color[0] <= upper_blue[0]) { auto [tl, br] = find_hole(hole.x, hole.y, draw_width, draw_height, x, y); rectangle(output_img, tl, br, Scalar(10, 215, 255), 20); if (i == 8) marked_positions.emplace_back(j+1, 11); else if (i == 9) marked_positions.emplace_back(j+1, 12); else marked_positions.emplace_back(i+1, j+1); mark = true; break; } } else { // 蓝紫色判断 if (color[0] >= lower_blue[0] && color[0] <= upper_purple[0]) { Vec3f pink_color; if (index_pink == -1) pink_color = standard_color; else { Point pink_hole = all_group_center[i][index_pink]; auto [py1, py2, px1, px2] = find_center_area(pink_hole.x, pink_hole.y, 50, 50); Mat pink_roi = hsv(Range(py1, py2), Range(px1, px2)); pink_color = mean(pink_roi); } if (color_difference(color, pink_color) >= 0.5f) { auto [tl, br] = find_hole(hole.x, hole.y, draw_width, draw_height, x, y); rectangle(output_img, tl, br, Scalar(10, 215, 255), 20); if (i == 8) marked_positions.emplace_back(j+1, 11); else if (i == 9) marked_positions.emplace_back(j+1, 12); else marked_positions.emplace_back(i+1, j+1); mark = true; break; } } else { index_pink = j; } } } if (!mark) { if (i == 8) marked_positions.emplace_back(-1, 11); else if (i == 9) marked_positions.emplace_back(-1, 12); else marked_positions.emplace_back(i+1, -1); } } imwrite(output_path, output_img); return marked_positions; }