From 5893636b8c8db58d8c6766332e3cc154b0713ac4 Mon Sep 17 00:00:00 2001 From: chief Date: Mon, 23 Nov 2020 21:56:33 +0800 Subject: [PATCH] =?UTF-8?q?Relationship=20Type=E5=88=9D=E5=B0=9D=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umlrecog/cddetector/ClassDetector.java | 2 +- .../cddetector/ClassRelationDetector.java | 59 ++++++++++-------- src/main/resources/cd/temp result.png | Bin 2400 -> 5383 bytes 3 files changed, 35 insertions(+), 26 deletions(-) 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 e5e2f8e..551c2fe 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 65e3be8..e73382a 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 GIT binary patch literal 5383 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 WT)vS|Uo>8wF1-5M`P?gS{O*5=eRRP9 -- Gitee