diff --git a/src/main/java/com/hy/java/uct/umlrecog/cddetector/ClassDetector.java b/src/main/java/com/hy/java/uct/umlrecog/cddetector/ClassDetector.java index e5e2f8e4feb4626fafd6ed01d3169b5b58f2d253..551c2fed1d56c01965342172c374e7f9b45d7c82 100644 --- a/src/main/java/com/hy/java/uct/umlrecog/cddetector/ClassDetector.java +++ b/src/main/java/com/hy/java/uct/umlrecog/cddetector/ClassDetector.java @@ -67,7 +67,7 @@ public class ClassDetector { List contours = new ArrayList<>(); Imgproc.findContours(cls_diagram, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); /* - * 对每个轮廓contour,检测是否为矩形,并将contour和检测结果存在Pair中。所有轮廓的检测结果最终存在all_rect_areas中 + * 对每个轮廓contour,检测是否为矩形,并将contour和检测结果存在Rectangle中。所有轮廓的检测结果最终存在all_rect_areas中 */ List all_rect_areas = new ArrayList<>(); // 这个rect_contours里只存那些检测结果为矩形的contour,用于后面边框涂白,防止矩形干扰关系符号和关系线识别 diff --git a/src/main/java/com/hy/java/uct/umlrecog/cddetector/ClassRelationDetector.java b/src/main/java/com/hy/java/uct/umlrecog/cddetector/ClassRelationDetector.java index 65e3be8aeaf5347f63ae8ee92762580389c16d07..e73382a40524640f2fdc38d635d9046bdf3b8b56 100644 --- a/src/main/java/com/hy/java/uct/umlrecog/cddetector/ClassRelationDetector.java +++ b/src/main/java/com/hy/java/uct/umlrecog/cddetector/ClassRelationDetector.java @@ -17,62 +17,71 @@ import com.hy.java.utility.common.Pair; public class ClassRelationDetector { private String cd_path = null; private String temp_res_path = null; - private Pair> classes = null; + private Pair> classes_in_cd = null; private Object result = null; public ClassRelationDetector(String repo_cd_path, Pair> classes) { this.cd_path = repo_cd_path; this.temp_res_path = cd_path.replaceAll(cd_path.substring(cd_path.lastIndexOf("\\") + 1, cd_path.lastIndexOf(".")), "temp result"); - this.classes = classes; + this.classes_in_cd = classes; } public void recog() { - // 关系类型检测 - // Mat temp = detectRelationType(classes); - // 直线检测 + // 先检测关系类型检测 + Mat temp = detectRelationType(classes_in_cd, 0.000555); + // 再检测关系线 // detectLines(temp); } /** * 识别关系符号 * - * @param classes2 + * @param classes_in_cd * @return */ - private static Mat detectRelationType(Pair> classes) { - // TODO Auto-generated method stub - System.out.println("识别所有关系符号"); - List class_rects = new ArrayList<>(); - // 识别图中所有“轮廓”并保存 + private Mat detectRelationType(Pair> classes_in_cd, double ratio) { + System.out.println("开始识别" + cd_path + "中所有关系符号"); + Mat cls_diagram = classes_in_cd.getLeft(); + List rela_shapes = new ArrayList<>(); + /* + * 识别图中所有“轮廓”并存在contours中 + */ List contours = new ArrayList<>(); - Imgproc.findContours(classes.getLeft(), contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); - // 对每个轮廓,检测是否为“特殊形状” + Imgproc.findContours(classes_in_cd.getLeft(), contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); + /* + * 对每个轮廓contour,检测是否为某种关系符号,并将contour和检测结果存在Rectangle中。所有轮廓的检测结果最终存在rela_shapes中 + */ + // 根据图片像素计算轮廓面积阈值。如果轮廓面积太小或太大,则直接忽略 + int cd_width = cls_diagram.width(); + int cd_height = cls_diagram.height(); + long cd_area = cd_width * cd_height; + double min_cls_area = cd_area * ratio; + double max_cls_area = cd_area * 0.5; for (MatOfPoint contour : contours) { - // 如果轮廓面积太小或太大,则直接忽略。阈值可以根据图片像素动态计算 - if (Imgproc.contourArea(contour) < 35 || Imgproc.contourArea(contour) > 1000) { + // 如果轮廓面积太小或太大,则直接忽略 + double contour_area = Imgproc.contourArea(contour); + if (contour_area < min_cls_area || contour_area > max_cls_area) { continue; } // 如果轮廓面积合适,则检测是否为关系符号形状。采用多边形逼近法 MatOfPoint2f curve = new MatOfPoint2f(contour.toArray()); MatOfPoint2f approx_curve = new MatOfPoint2f(); - // 将轮廓向多边形做逼近 - double epsilon = 0.01 * Imgproc.arcLength(curve, true); - Imgproc.approxPolyDP(curve, approx_curve, epsilon, true); + Imgproc.approxPolyDP(curve, approx_curve, 0.01 * Imgproc.arcLength(curve, true), true); System.out.print(approx_curve.dump()); // 将每个关系符号存在别处。存完后将其从图中抹掉,防止其干扰直线识别 - class_rects.add(contour); + rela_shapes.add(contour); // 将关系符号从图中抹掉(涂白)。后面还需对所有边框进行涂白 - Imgproc.fillConvexPoly(classes.getLeft(), contour, new Scalar(15, 225, 25)); + Imgproc.fillConvexPoly(classes_in_cd.getLeft(), contour, new Scalar(15, 225, 25)); } // 对所有边框进行涂白 - Imgproc.drawContours(classes.getLeft(), class_rects, -1, new Scalar(255, 255, 255), 8); + Imgproc.drawContours(classes_in_cd.getLeft(), rela_shapes, -1, new Scalar(255, 255, 255), 8); // 将图片写入result文件 - Imgcodecs.imwrite("D:\\eclipse-committers\\uml-code-trace\\src\\test\\resources\\result.png", classes.getLeft()); - System.out.println("识别关系符号完毕,共" + class_rects.size() + "个"); - return classes.getLeft(); + Imgcodecs.imwrite(temp_res_path, classes_in_cd.getLeft()); + System.out.println("识别关系符号完毕,共" + rela_shapes.size() + "个"); + return classes_in_cd.getLeft(); } - private static void detectLines(Mat src) { + private void detectLines(Mat src) { // TODO Auto-generated method stub System.out.println("识别关系"); // 先检测边缘。然后从边缘集中检测直线 diff --git a/src/main/resources/cd/temp result.png b/src/main/resources/cd/temp result.png index 57e4abc065765d1484e301fc4f91be935dfaf34a..bd9e356c945ea18097229d8317c29bf4ad7b9636 100644 Binary files a/src/main/resources/cd/temp result.png and b/src/main/resources/cd/temp result.png differ