/
Sturon
/
Diplom
Обзор
Документация
Войти
/
Sturon
/
Diplom
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/src/main/java/ru/diplom/vision/service/MockDetectorService.java
125 строк
5 KB
Sturon
Initial
03 июн 2026, 15:01
03 июн 2026, 15:01
17b44a2
Код
Авторство
О чём код?
package ru.diplom.vision.service; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Random; import java.util.Set; import javax.imageio.ImageIO; import org.springframework.stereotype.Service; import ru.diplom.vision.domain.RegionOfInterest; @Service public class MockDetectorService { private static final List<String> DEFECT_TYPES = List.of( "surface-scratch", "edge-chip", "stamping-burr", "dark-spot" ); public DetectionResult detect(BufferedImage image, List<RegionOfInterest> rois) { long seed = calculateSeed(image); List<RegionOfInterest> zones = (rois == null || rois.isEmpty()) ? List.of(buildFullImageZone(image)) : rois; List<DefectCandidate> defects = new ArrayList<>(); for (RegionOfInterest zone : zones) { long zoneSeed = seed + (long) (zone.getZoneOrder() + 1) * 9_973L; Random random = new Random(zoneSeed); Rectangle bounds = new Rectangle(zone.getX(), zone.getY(), zone.getWidth(), zone.getHeight()); int bucket = Math.floorMod(zoneSeed, 5); int defectCount = bucket >= 3 ? 1 : 0; if (bucket == 4 && bounds.width > 140 && bounds.height > 140) { defectCount = 2; } for (int index = 0; index < defectCount; index++) { int width = Math.max(32, bounds.width / (5 + random.nextInt(4))); int height = Math.max(28, bounds.height / (6 + random.nextInt(4))); int xLimit = Math.max(bounds.x, bounds.x + bounds.width - width); int yLimit = Math.max(bounds.y, bounds.y + bounds.height - height); int x = xLimit == bounds.x ? bounds.x : bounds.x + random.nextInt(xLimit - bounds.x + 1); int y = yLimit == bounds.y ? bounds.y : bounds.y + random.nextInt(yLimit - bounds.y + 1); double confidence = 0.71 + random.nextDouble() * 0.25; defects.add(new DefectCandidate( DEFECT_TYPES.get(random.nextInt(DEFECT_TYPES.size())), roiName(zone), zone.getZoneOrder(), confidence, x, y, width, height, "Сгенерировано mock-детектором" )); } } String summary; if (defects.isEmpty()) { summary = "Дефекты не обнаружены ни в одной зоне"; } else { Set<String> zoneNames = new LinkedHashSet<>(); defects.forEach(defect -> zoneNames.add(defect.roiName())); summary = "Обнаружены дефекты в зонах: " + String.join(", ", zoneNames); } return new DetectionResult(defects, summary); } private RegionOfInterest buildFullImageZone(BufferedImage image) { RegionOfInterest roi = new RegionOfInterest(); roi.setName("Зона 1"); roi.setZoneOrder(0); roi.setX(0); roi.setY(0); roi.setWidth(image.getWidth()); roi.setHeight(image.getHeight()); return roi; } private String roiName(RegionOfInterest roi) { if (roi.getName() == null || roi.getName().isBlank()) { return "Зона " + (roi.getZoneOrder() + 1); } return roi.getName(); } private long calculateSeed(BufferedImage image) { try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(image, "png", outputStream); byte[] bytes = outputStream.toByteArray(); long hash = 1125899906842597L; for (byte value : bytes) { hash = 31 * hash + value; } return Math.abs(hash); } catch (IOException exception) { return Math.abs((long) image.getWidth() * 31 + image.getHeight() * 17); } } public record DetectionResult(List<DefectCandidate> defects, String summary) { } public record DefectCandidate( String defectType, String roiName, int roiOrder, double confidence, int x, int y, int width, int height, String notes ) { } }