From a8a19b0a6e9777d72e394bf4cae9015ac9362843 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Tue, 26 Mar 2024 13:01:26 +0900 Subject: [PATCH 01/23] =?UTF-8?q?=20#80=20[REFACTOR]=20CustomAnalysisEntit?= =?UTF-8?q?y=20=EA=B4=80=EB=A0=A8=20=EA=B0=9D=EC=B2=B4=EB=93=A4=20domain?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 판단하는 비즈니스 로직을 포함하고 있어 이전하였습니다. --- .../api/mission/MissionController.java | 2 +- .../togetUp/api/mission/MissionService.java | 3 +-- .../mission/domain/CustomAnalysisEntity.java | 22 +++++++++++++++++++ .../CustomDetectedObject.java | 11 +++++----- .../api/mission/domain/CustomDetectedTag.java | 17 ++++++++++++++ .../mission/domain/MissionPerformResult.java | 1 - .../mission/domain/ObjectDetectionResult.java | 9 +++----- .../mission/domain/VisionAnalysisResult.java | 1 - .../mission/model/CustomAnalysisEntity.java | 21 ------------------ .../api/mission/model/CustomDetectedTag.java | 17 -------------- .../mission/service/MissionImageService.java | 2 +- .../mapper/ObjectDetectedV32Mapper.java | 2 +- .../mapper/ObjectDetectedV40Mapper.java | 2 +- .../service/mapper/TagDetectedV40Mapper.java | 2 +- .../azure/vision/AzureVision32Service.java | 2 +- .../togetUp/utils/ImageProcessor.java | 4 ++-- 16 files changed, 57 insertions(+), 61 deletions(-) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomAnalysisEntity.java rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{model => domain}/CustomDetectedObject.java (53%) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedTag.java delete mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomAnalysisEntity.java delete mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomDetectedTag.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java index 5abe4231..e9ed6cc7 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java @@ -2,7 +2,7 @@ import com.google.cloud.vision.v1.FaceAnnotation; import com.wakeUpTogetUp.togetUp.api.auth.AuthUser; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomAnalysisEntity; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.infra.aws.s3.FileService; import com.wakeUpTogetUp.togetUp.api.mission.dto.request.MissionCompleteReq; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionLogRes; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java index 3a9c764f..924ea725 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java @@ -6,8 +6,7 @@ import com.wakeUpTogetUp.togetUp.api.alarm.model.Alarm; import com.wakeUpTogetUp.togetUp.api.mission.dto.request.MissionCompleteReq; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionCompleteRes; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomAnalysisEntity; -import com.wakeUpTogetUp.togetUp.api.mission.model.Emotion; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog; import com.wakeUpTogetUp.togetUp.api.mission.domain.MissionPerformResult; import com.wakeUpTogetUp.togetUp.infra.azure.vision.AzureVision32Service; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomAnalysisEntity.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomAnalysisEntity.java new file mode 100644 index 00000000..f634146e --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomAnalysisEntity.java @@ -0,0 +1,22 @@ +package com.wakeUpTogetUp.togetUp.api.mission.domain; + +import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; +import lombok.Getter; + +@Getter +public abstract class CustomAnalysisEntity { + + protected final String targetName; + + private final double confidence; + + private final BoundingBox box; + + public CustomAnalysisEntity(String targetName, double confidence, BoundingBox box) { + this.targetName = targetName; + this.confidence = confidence; + this.box = box; + } + + public abstract boolean isMatchEntity(String target); +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomDetectedObject.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedObject.java similarity index 53% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomDetectedObject.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedObject.java index 20ac51d3..df99cdc1 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomDetectedObject.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedObject.java @@ -1,16 +1,17 @@ -package com.wakeUpTogetUp.togetUp.api.mission.model; +package com.wakeUpTogetUp.togetUp.api.mission.domain; +import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; import lombok.Builder; import lombok.Getter; @Getter public class CustomDetectedObject extends CustomAnalysisEntity { - private String parent; + private final String parent; @Builder - private CustomDetectedObject(String object, String parent, double confidence, BoundingBox box) { - super(object, confidence, box); + private CustomDetectedObject(String objectName, String parent, double confidence, BoundingBox box) { + super(objectName, confidence, box); this.parent = parent; } @@ -20,7 +21,7 @@ public boolean isMatchEntity(String targetObject) { } public String concatObjectAndParent() { - return name + parent; + return targetName + parent; } } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedTag.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedTag.java new file mode 100644 index 00000000..21461368 --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedTag.java @@ -0,0 +1,17 @@ +package com.wakeUpTogetUp.togetUp.api.mission.domain; + +import lombok.Builder; +import lombok.Getter; + +@Getter +public class CustomDetectedTag extends CustomAnalysisEntity { + @Builder + public CustomDetectedTag(String tagName, double confidence) { + super(tagName, confidence, null); + } + + @Override + public boolean isMatchEntity(String target) { + return targetName.toLowerCase().contains(target.toLowerCase()); + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/MissionPerformResult.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/MissionPerformResult.java index a8f9bbec..afb86fc7 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/MissionPerformResult.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/MissionPerformResult.java @@ -1,6 +1,5 @@ package com.wakeUpTogetUp.togetUp.api.mission.domain; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomAnalysisEntity; import java.util.List; import lombok.Builder; import lombok.Getter; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionResult.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionResult.java index 45bfe498..c25f7987 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionResult.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionResult.java @@ -1,8 +1,5 @@ package com.wakeUpTogetUp.togetUp.api.mission.domain; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomAnalysisEntity; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomDetectedObject; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomDetectedTag; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -55,13 +52,13 @@ public void print() { private void printDetectedObjects() { System.out.println("[OBJECT]"); System.out.println("objects.size() = " + objects.size()); - objects.forEach(object -> System.out.println(object.getName())); - objects.forEach(object -> System.out.println(object.getName())); + objects.forEach(object -> System.out.println(object.getTargetName())); + objects.forEach(object -> System.out.println(object.getTargetName())); } private void printDetectedTags() { System.out.println("[TAG]"); System.out.println("tags.size() = " + tags.size()); - tags.forEach(tag -> System.out.println(tag.getName())); + tags.forEach(tag -> System.out.println(tag.getTargetName())); } } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionAnalysisResult.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionAnalysisResult.java index 0ced9b49..a1df5095 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionAnalysisResult.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionAnalysisResult.java @@ -1,6 +1,5 @@ package com.wakeUpTogetUp.togetUp.api.mission.domain; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomAnalysisEntity; import java.util.List; public abstract class VisionAnalysisResult { diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomAnalysisEntity.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomAnalysisEntity.java deleted file mode 100644 index e9fab596..00000000 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomAnalysisEntity.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.wakeUpTogetUp.togetUp.api.mission.model; - -import lombok.Getter; - -@Getter -public abstract class CustomAnalysisEntity { - - protected final String name; - - private final double confidence; - - private final BoundingBox box; - - public CustomAnalysisEntity(String name, double confidence, BoundingBox box) { - this.name = name; - this.confidence = confidence; - this.box = box; - } - - public abstract boolean isMatchEntity(String target); -} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomDetectedTag.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomDetectedTag.java deleted file mode 100644 index a1f2d17d..00000000 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/CustomDetectedTag.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.wakeUpTogetUp.togetUp.api.mission.model; - -import lombok.Builder; -import lombok.Getter; - -@Getter -public class CustomDetectedTag extends CustomAnalysisEntity { - @Builder - public CustomDetectedTag(String name, double confidence) { - super(name, confidence, new BoundingBox()); - } - - @Override - public boolean isMatchEntity(String target) { - return name.toLowerCase().contains(target.toLowerCase()); - } -} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java index 7e7c2950..1c11552b 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java @@ -1,7 +1,7 @@ package com.wakeUpTogetUp.togetUp.api.mission.service; import com.google.cloud.vision.v1.FaceAnnotation; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomAnalysisEntity; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.utils.ImageProcessor; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; import java.io.IOException; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV32Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV32Mapper.java index 1e3c3493..86638312 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV32Mapper.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV32Mapper.java @@ -2,7 +2,7 @@ import com.microsoft.azure.cognitiveservices.vision.computervision.models.DetectedObject; import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomDetectedObject; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedObject; import java.util.List; import java.util.stream.Collectors; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV40Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV40Mapper.java index b6886820..786a1a4f 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV40Mapper.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV40Mapper.java @@ -2,7 +2,7 @@ import com.azure.ai.vision.imageanalysis.DetectedObject; import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomDetectedObject; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedObject; import java.util.List; import java.util.stream.Collectors; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/TagDetectedV40Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/TagDetectedV40Mapper.java index dc24a733..d2594bd7 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/TagDetectedV40Mapper.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/TagDetectedV40Mapper.java @@ -1,7 +1,7 @@ package com.wakeUpTogetUp.togetUp.api.mission.service.mapper; import com.azure.ai.vision.imageanalysis.ContentTag; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomDetectedTag; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedTag; import java.util.List; import java.util.stream.Collectors; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java index 24190fb6..bd417866 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java @@ -3,7 +3,7 @@ import com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVisionClient; import com.microsoft.azure.cognitiveservices.vision.computervision.models.ImageAnalysis; import com.microsoft.azure.cognitiveservices.vision.computervision.models.VisualFeatureTypes; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomDetectedObject; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedObject; import com.wakeUpTogetUp.togetUp.api.mission.service.mapper.ObjectDetectedV32Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java index dc2adbaf..08e8bce6 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java @@ -5,7 +5,7 @@ import com.google.cloud.vision.v1.FaceAnnotation; import com.google.cloud.vision.v1.Vertex; import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; -import com.wakeUpTogetUp.togetUp.api.mission.model.CustomAnalysisEntity; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; @@ -192,7 +192,7 @@ public byte[] drawODResultOnImage(MultipartFile file, List int fontSize = minDwDh / 25; g2d.setFont(new Font("Arial", Font.PLAIN, fontSize)); g2d.drawString( - entity.getName() + " : " + String.format("%.3f", entity.getConfidence()), + entity.getTargetName() + " : " + String.format("%.3f", entity.getConfidence()), box.getX(), box.getY() - (float) (originalImage.getHeight() / 100)); } g2d.dispose(); From d7264b2fe12df618a9098103780d047b1a4e8d48 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Tue, 26 Mar 2024 13:04:12 +0900 Subject: [PATCH 02/23] =?UTF-8?q?=20#80=20[REMOVE]=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=AA=A8=EB=8D=B8?= =?UTF-8?q?=EB=A1=9C=20=EA=B0=9D=EC=B2=B4=20=EC=9D=B8=EC=8B=9D=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../togetUp/api/mission/domain/Letterbox.java | 85 ---------- .../togetUp/api/mission/domain/ODResult.java | 65 -------- .../mission/domain/ObjectDetectionModel.java | 22 --- .../service/ObjectDetectionService.java | 152 ------------------ .../togetUp/config/ODConfig.java | 50 ------ 5 files changed, 374 deletions(-) delete mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/Letterbox.java delete mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ODResult.java delete mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionModel.java delete mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/ObjectDetectionService.java delete mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/config/ODConfig.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/Letterbox.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/Letterbox.java deleted file mode 100644 index b5071a2e..00000000 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/Letterbox.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.wakeUpTogetUp.togetUp.api.mission.domain; - -import org.opencv.core.Core; -import org.opencv.core.Mat; -import org.opencv.core.Size; -import org.opencv.imgproc.Imgproc; -import org.springframework.stereotype.Component; - -@Component -public class Letterbox { - - private Size newShape = new Size(1280, 1280); - private double[] color = new double[]{114, 114, 114}; - private Boolean auto = false; - private Boolean scaleUp = false; - private Integer stride = 32; - - private double ratio; - private double dw; - private double dh; - - public double getRatio() { - return ratio; - } - - public double getDw() { - return dw; - } - - public Integer getWidth() { - return (int) this.newShape.width; - } - - public Integer getHeight() { - return (int) this.newShape.height; - } - - public double getDh() { - return dh; - } - - public void setNewShape(Size newShape) { - this.newShape = newShape; - } - - public void setStride(Integer stride) { - this.stride = stride; - } - - public Mat letterbox(Mat image) { // 단계 제약 조건을 충족하도록 이미지 크기 조정 및 채우기, 매개 변수 기록 - int[] shape = {image.rows(), image.cols()}; // 현재 모양 [height, width] - // Scale ratio (new / old) - double r = Math.min(this.newShape.height / shape[0], this.newShape.width / shape[1]); - - if (!this.scaleUp) { // 축소만, 확대는 하지 않음(일단 mAP를 위해서) - r = Math.min(r, 1.0); - } - - // Compute padding - Size newUnpad = new Size(Math.round(shape[1] * r), Math.round(shape[0] * r)); - double dw = this.newShape.width - newUnpad.width, dh = this.newShape.height - newUnpad.height; - if (this.auto) { // 최소 직사각형 - dw = dw % this.stride; - dh = dh % this.stride; - } - dw /= 2; // 채울 때 양쪽을 절반씩 채워 그림을 중심에 놓으십시오 - dh /= 2; - - // resize - if (shape[1] != newUnpad.width || shape[0] != newUnpad.height) { - Imgproc.resize(image, image, newUnpad, 0, 0, Imgproc.INTER_LINEAR); - } - - int top = (int) Math.round(dh - 0.1), bottom = (int) Math.round(dh + 0.1); - int left = (int) Math.round(dw - 0.1), right = (int) Math.round(dw + 0.1); - - // 그림을 정사각형으로 채우기 - Core.copyMakeBorder(image, image, top, bottom, left, right, Core.BORDER_CONSTANT, new org.opencv.core.Scalar(this.color)); - - this.ratio = r; - this.dh = dh; - this.dw = dw; - return image; - } -} \ No newline at end of file diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ODResult.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ODResult.java deleted file mode 100644 index a77ad331..00000000 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ODResult.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.wakeUpTogetUp.togetUp.api.mission.domain; - -import java.text.DecimalFormat; - -public class ODResult { - private final Integer batchId; - private final Float x0; - private final Float y0; - private final Float x1; - private final Float y1; - private final Integer clsId; - private final Float score; - - public ODResult(float[] x) { - this.batchId = (int) x[0]; - this.x0 = x[1]; - this.y0 = x[2]; - this.x1 = x[3]; - this.y1 = x[4]; - this.clsId = (int) x[5]; - this.score = x[6]; - } - - public Integer getBatchId() { - return batchId; - } - - public Float getX0() { - return x0; - } - - public Float getY0() { - return y0; - } - - public Float getX1() { - return x1; - } - - public Float getY1() { - return y1; - } - - public Integer getClsId() { - return clsId; - } - - public String getScore() { - DecimalFormat df = new DecimalFormat("0.00%"); - return df.format(this.score); - } - - @Override - public String toString() { - return "Object: " + - " \t batchId=" + batchId + - " \t x0=" + x0 + - " \t y0=" + y0 + - " \t x1=" + x1 + - " \t y1=" + y1 + - " \t clsId=" + clsId + - " \t score=" + getScore() + - " \t ;"; - } -} \ No newline at end of file diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionModel.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionModel.java deleted file mode 100644 index 16245a9e..00000000 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionModel.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.wakeUpTogetUp.togetUp.api.mission.domain; - -import ai.onnxruntime.OrtEnvironment; -import ai.onnxruntime.OrtException; -import ai.onnxruntime.OrtSession; - -import javax.annotation.PostConstruct; -import lombok.Getter; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -@Component -@Getter -public class ObjectDetectionModel { - private OrtSession session; - private OrtEnvironment environment; - private OrtSession.SessionOptions sessionOptions; - - @Value("${my.path.model-path}") - private String modelPath; - -} \ No newline at end of file diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/ObjectDetectionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/ObjectDetectionService.java deleted file mode 100644 index 8cf3b875..00000000 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/ObjectDetectionService.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.wakeUpTogetUp.togetUp.api.mission.service; - -import ai.onnxruntime.OnnxTensor; -import ai.onnxruntime.OrtException; -import ai.onnxruntime.OrtSession; -import com.wakeUpTogetUp.togetUp.api.mission.domain.Letterbox; -import com.wakeUpTogetUp.togetUp.api.mission.domain.ODResult; -import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionModel; -import com.wakeUpTogetUp.togetUp.common.Status; -import com.wakeUpTogetUp.togetUp.config.ODConfig; -import com.wakeUpTogetUp.togetUp.exception.BaseException; -import com.wakeUpTogetUp.togetUp.utils.ImageProcessor; -import java.nio.FloatBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import lombok.RequiredArgsConstructor; -import org.opencv.core.Mat; -import org.opencv.core.MatOfByte; -import org.opencv.core.Point; -import org.opencv.core.Scalar; -import org.opencv.imgcodecs.Imgcodecs; -import org.opencv.imgproc.Imgproc; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; - -@Service -@RequiredArgsConstructor -public class ObjectDetectionService { - - private final ObjectDetectionModel odm; - private final ODConfig odConfig; - private final Letterbox letterbox; - private final ImageProcessor imageProcessor; - -// @Value("${my.path.save-pic-path}") -// private String savePicPath; - - public ArrayList detectObject(MultipartFile missionImage) { - long startTime = System.currentTimeMillis(); - - try { - // 기본 정보 출력 - odm.getSession().getInputInfo().keySet().forEach(x -> { - try { - System.out.println("input name = " + x); - System.out.println(odm.getSession().getInputInfo().get(x).getInfo().toString()); - } catch (OrtException e) { - throw new RuntimeException(e); - } - }); - } catch (Exception e) { - e.printStackTrace(); - throw new BaseException(Status.LOAD_MODEL_FAILURE); - } - - try { - // image 읽기 - Mat img = Imgcodecs.imdecode(new MatOfByte(missionImage.getBytes()), - Imgcodecs.IMREAD_COLOR); -// Mat img = Imgcodecs.imdecode( -// new MatOfByte(imageProcessor.compress(missionImage, 0.5f)), -// Imgcodecs.IMREAD_COLOR); - Imgproc.cvtColor(img, img, Imgproc.COLOR_BGR2RGB); - Mat image = img.clone(); - - // 아래 상자의 굵기, 글자의 크기, 글자의 종류, 글자의 색을 먼저 정의합니다. (비례에 따라 굵기를 설정하는 것이 좋습니다.) - int minDwDh = Math.min(img.width(), img.height()); - int thickness = minDwDh / odConfig.getLineThicknessRatio(); - double fontSize = minDwDh / odConfig.getFontSizeRatio(); - int fontFace = Imgproc.FONT_HERSHEY_SIMPLEX; - Scalar fontColor = new Scalar(0, 0, 0); - - // image 크기 변경 - image = letterbox.letterbox(image); - double ratio = letterbox.getRatio(); - double dw = letterbox.getDw(); - double dh = letterbox.getDh(); - int rows = letterbox.getHeight(); - int cols = letterbox.getWidth(); - int channels = image.channels(); - - // Mat 객체의 픽셀 값을 Float[] 객체에 할당합니다. - float[] pixels = new float[channels * rows * cols]; - for (int i = 0; i < rows; i++) { - for (int j = 0; j < cols; j++) { - double[] pixel = image.get(j, i); - for (int k = 0; k < channels; k++) { - // 이러한 설정은 image.transpose (2, 0, 1) 작업을 동시에 수행하는 것과 같습니다 - pixels[rows * cols * k + j * cols + i] = (float) pixel[k] / 255.0f; - } - } - } - - // OnnxTensor 개체 만들기 - long[] shape = {1L, (long) channels, (long) rows, (long) cols}; - OnnxTensor tensor = OnnxTensor.createTensor(odm.getEnvironment(), - FloatBuffer.wrap(pixels), shape); - HashMap stringOnnxTensorHashMap = new HashMap<>(); - stringOnnxTensorHashMap.put(odm.getSession().getInputInfo().keySet().iterator().next(), - tensor); - - // 모델 실행 - OrtSession.Result output = odm.getSession().run(stringOnnxTensorHashMap); - - // 결과를 얻기 - // 디버깅 - System.out.println("info = " + output.get(0).getInfo().toString()); - float[][] outputData = (float[][]) output.get(0).getValue(); - - ArrayList detectedObejectList = new ArrayList(); - Arrays.stream(outputData).iterator().forEachRemaining(x -> { - ODResult odResult = new ODResult(x); - System.out.println("odResult : " + odResult); - -// // 그림틀 - Point topLeft = new Point((odResult.getX0() - dw) / ratio, - (odResult.getY0() - dh) / ratio); - Point bottomRight = new Point((odResult.getX1() - dw) / ratio, - (odResult.getY1() - dh) / ratio); - Scalar color = new Scalar(odConfig.getColor(odResult.getClsId())); - Imgproc.rectangle(img, topLeft, bottomRight, color, thickness); - - // 틀에 글을 쓰다 - String boxName = odConfig.getName(odResult.getClsId()) + ": " + odResult.getScore(); - Point boxNameLoc = new Point((odResult.getX0() - dw) / ratio, - (odResult.getY0() - dh) / ratio - 3); - - Imgproc.putText(img, boxName, boxNameLoc, fontFace, fontSize, fontColor, thickness); - - // 감지된 클래스 리스트 생성 - detectedObejectList.add(odConfig.getName(odResult.getClsId())); - }); - -// // 그림 저장 - Imgproc.cvtColor(img, img, Imgproc.COLOR_RGB2BGR); -// Imgcodecs.imwrite(savePicPath, img); - - // 걸린 시간 계산 - long endTime = System.currentTimeMillis(); - - long timeElapsed = endTime - startTime; - System.out.println("Execution time in milliseconds: " + timeElapsed); - - return detectedObejectList; - - } catch (Exception e) { - e.printStackTrace(); - throw new BaseException(Status.NO_DETECTED_OBJECT); - } - } -} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/config/ODConfig.java b/src/main/java/com/wakeUpTogetUp/togetUp/config/ODConfig.java deleted file mode 100644 index b2e0d7ea..00000000 --- a/src/main/java/com/wakeUpTogetUp/togetUp/config/ODConfig.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.wakeUpTogetUp.togetUp.config; - -import lombok.Getter; - -import java.util.Random; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.HashMap; -import org.springframework.stereotype.Component; - -@Component -@Getter -public class ODConfig { - - private final Integer lineThicknessRatio = 333; - private final Double fontSizeRatio = 1145.14; - private final List names = new ArrayList<>(Arrays.asList( - "person", "bicycle", "car", "motorcycle", "airplane", "bus", - "train", "boat", "traffic light", "bird", "cat", "dog", - "horse", "backpack", "umbrella", "handbag", "tie", "suitcase", - "frisbee", "skis", "surfboard", "snowboard", "sports ball", - "baseball bat", "baseball glove", "skateboard", "tennis racket", - "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", - "banana", "apple", "sandwich", "orange", "broccoli", "carrot", - "hot dog", "pizza", "donut", "cake", "chair", "couch", - "potted plant", "bed", "tv", "laptop", "mouse", "keyboard", - "cell phone", "oven", "toaster", "refrigerator", "book", "clock", - "vase", "scissors", "teddy bear", "hair drier", "toothbrush")); - - private Map colors; - - public ODConfig() { - this.colors = new HashMap<>(); - names.forEach(name->{ - Random random = new Random(); - double[] color = {random.nextDouble()*256, random.nextDouble()*256, random.nextDouble()*256}; - colors.put(name, color); - }); - } - - public String getName(int clsId) { - return names.get(clsId); - } - - public double[] getColor(int clsId) { - return colors.get(getName(clsId)); - } -} \ No newline at end of file From f72bae99f8172b9f15303fe40d52fcd3168875c4 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Tue, 26 Mar 2024 13:10:47 +0900 Subject: [PATCH 03/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=EC=99=B8=EB=B6=80?= =?UTF-8?q?=20=EC=84=9C=EB=B9=84=EC=8A=A4=20mapper=EB=A5=BC=20infra=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wakeUpTogetUp/togetUp/api/mission/model/BoundingBox.java | 2 +- .../togetUp/infra/azure/vision/AzureVision32Service.java | 2 +- .../togetUp/infra/azure/vision/AzureVision40Service.java | 4 ++-- .../azure/vision}/mapper/ObjectDetectedV32Mapper.java | 4 ++-- .../azure/vision}/mapper/ObjectDetectedV40Mapper.java | 4 ++-- .../azure/vision}/mapper/TagDetectedV40Mapper.java | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) rename src/main/java/com/wakeUpTogetUp/togetUp/{api/mission/service => infra/azure/vision}/mapper/ObjectDetectedV32Mapper.java (91%) rename src/main/java/com/wakeUpTogetUp/togetUp/{api/mission/service => infra/azure/vision}/mapper/ObjectDetectedV40Mapper.java (91%) rename src/main/java/com/wakeUpTogetUp/togetUp/{api/mission/service => infra/azure/vision}/mapper/TagDetectedV40Mapper.java (87%) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/BoundingBox.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/BoundingBox.java index 8691e837..dc001f1d 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/BoundingBox.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/BoundingBox.java @@ -8,7 +8,7 @@ @Getter @Builder -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.MODULE) @AllArgsConstructor(access = AccessLevel.PRIVATE) public class BoundingBox { private int x; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java index bd417866..85a53680 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java @@ -4,7 +4,7 @@ import com.microsoft.azure.cognitiveservices.vision.computervision.models.ImageAnalysis; import com.microsoft.azure.cognitiveservices.vision.computervision.models.VisualFeatureTypes; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedObject; -import com.wakeUpTogetUp.togetUp.api.mission.service.mapper.ObjectDetectedV32Mapper; +import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.ObjectDetectedV32Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import java.io.IOException; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java index 88ccc323..613b1d7b 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java @@ -13,8 +13,8 @@ import com.azure.ai.vision.imageanalysis.ImageAnalysisResultReason; import com.azure.ai.vision.imageanalysis.ImageAnalyzer; import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult; -import com.wakeUpTogetUp.togetUp.api.mission.service.mapper.ObjectDetectedV40Mapper; -import com.wakeUpTogetUp.togetUp.api.mission.service.mapper.TagDetectedV40Mapper; +import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.ObjectDetectedV40Mapper; +import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.TagDetectedV40Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import java.io.IOException; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV32Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV32Mapper.java similarity index 91% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV32Mapper.java rename to src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV32Mapper.java index 86638312..2b9b1e66 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV32Mapper.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV32Mapper.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.api.mission.service.mapper; +package com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper; import com.microsoft.azure.cognitiveservices.vision.computervision.models.DetectedObject; import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; @@ -22,7 +22,7 @@ private CustomDetectedObject toCustomDetectedObject(DetectedObject detectedObjec : null; return CustomDetectedObject.builder() - .object(detectedObject.objectProperty()) + .objectName(detectedObject.objectProperty()) .parent(parent) .confidence(detectedObject.confidence()) .box(BoundingBox.builder() diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV40Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV40Mapper.java similarity index 91% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV40Mapper.java rename to src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV40Mapper.java index 786a1a4f..b2454316 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/ObjectDetectedV40Mapper.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV40Mapper.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.api.mission.service.mapper; +package com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper; import com.azure.ai.vision.imageanalysis.DetectedObject; import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; @@ -17,7 +17,7 @@ public List toCustomDetectedObjects(List o private CustomDetectedObject toCustomDetectedObject(DetectedObject detectedObject) { return CustomDetectedObject.builder() - .object(detectedObject.getName()) + .objectName(detectedObject.getName()) .parent(null) .confidence(detectedObject.getConfidence()) .box(BoundingBox.builder() diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/TagDetectedV40Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV40Mapper.java similarity index 87% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/TagDetectedV40Mapper.java rename to src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV40Mapper.java index d2594bd7..61622d04 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/mapper/TagDetectedV40Mapper.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV40Mapper.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.api.mission.service.mapper; +package com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper; import com.azure.ai.vision.imageanalysis.ContentTag; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedTag; @@ -17,7 +17,7 @@ public List customDetectedTags(List tags) { private CustomDetectedTag toCustomDetectedTag(ContentTag tag) { return CustomDetectedTag.builder() - .name(tag.getName()) + .tagName(tag.getName()) .confidence(tag.getConfidence()) .build(); } From de5e00f4213f594e55a45ac9c8e71c95b6e67c39 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 17:47:56 +0900 Subject: [PATCH 04/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=EC=A2=8C=ED=91=9C?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../togetUp/api/mission/model/BoundingBox.java | 11 +++++++++-- .../togetUp/api/mission/model/Coord.java | 13 +++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Coord.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/BoundingBox.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/BoundingBox.java index dc001f1d..64a3a9c6 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/BoundingBox.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/BoundingBox.java @@ -11,11 +11,18 @@ @NoArgsConstructor(access = AccessLevel.MODULE) @AllArgsConstructor(access = AccessLevel.PRIVATE) public class BoundingBox { - private int x; - private int y; + private Coord coord; private int w; private int h; + + public int getX() { + return coord.getX(); + } + + public int getY() { + return coord.getY(); + } } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Coord.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Coord.java new file mode 100644 index 00000000..947472d4 --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Coord.java @@ -0,0 +1,13 @@ +package com.wakeUpTogetUp.togetUp.api.mission.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class Coord { + + private final int x; + + private final int y; +} From b86dcb7e2f7d9b5e090a67d5fd4bb8dade211dd4 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 17:56:13 +0900 Subject: [PATCH 05/23] =?UTF-8?q?=20#80=20[REFACTOR]=20VisionAnalysisResul?= =?UTF-8?q?t=20=EC=83=81=EC=86=8D=EA=B4=80=EA=B3=84=20=EB=B3=80=EA=B2=BD?= =?UTF-8?q?=20=EB=B0=8F=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 부모 클래스 MissionPerformResult 삭제 - 필드 targetName 추가 --- .../mission/domain/MissionPerformResult.java | 26 ----------- .../mission/domain/ObjectDetectionResult.java | 46 +++++++++++-------- .../mission/domain/VisionAnalysisResult.java | 12 +++-- 3 files changed, 35 insertions(+), 49 deletions(-) delete mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/MissionPerformResult.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/MissionPerformResult.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/MissionPerformResult.java deleted file mode 100644 index afb86fc7..00000000 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/MissionPerformResult.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.wakeUpTogetUp.togetUp.api.mission.domain; - -import java.util.List; -import lombok.Builder; -import lombok.Getter; -public class MissionPerformResult { - private final int MAX_MATCHES_LIMIT = 3; - private final String targetObject; - - @Getter - private final VisionAnalysisResult analysisResult; - - @Builder - private MissionPerformResult(String object, VisionAnalysisResult analysisResult) { - this.targetObject = object; - this.analysisResult = analysisResult; - } - - public boolean isFail() { - return analysisResult.isFail(targetObject); - } - - public List getMatches() { - return analysisResult.getMatches(targetObject, MAX_MATCHES_LIMIT); - } -} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionResult.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionResult.java index c25f7987..081e9d71 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionResult.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/ObjectDetectionResult.java @@ -4,45 +4,50 @@ import java.util.List; import java.util.stream.Collectors; import lombok.Builder; -import lombok.Getter; -@Getter public class ObjectDetectionResult extends VisionAnalysisResult { private final List objects; - private final List tags; @Builder - private ObjectDetectionResult(List objects, List tags) { + private ObjectDetectionResult(String target, List objects, List tags) { + super(target); this.objects = objects; this.tags = tags; } @Override - public List getEntities() { + public boolean isFail() { + return !hasAnyMatchTag() && !hasAnyMatchObject(); + } + + private boolean hasAnyMatchTag() { + return tags.stream() + .anyMatch(tag -> tag.isMatchEntity(targetName)); + } + + private boolean hasAnyMatchObject() { return objects.stream() - .map(CustomAnalysisEntity.class::cast) - .collect(Collectors.toList()); + .anyMatch(object -> object.isMatchEntity(targetName)); } @Override - public boolean isFail(String targetObject) { - return tags.stream() - .noneMatch(tag -> tag.isMatchEntity(targetObject)); + public List getEntities() { + return objects.stream() + .map(CustomAnalysisEntity.class::cast) + .collect(Collectors.toList()); } @Override - public List getMatches(String targetObject, int size) { + public List getMatches(int size) { return objects.stream() - .filter(object -> object.isMatchEntity(targetObject)) + .filter(object -> object.isMatchEntity(targetName)) .sorted(Comparator.comparing(CustomDetectedObject::getConfidence).reversed()) .limit(size) .collect(Collectors.toList()); } - - // TODO: 디버그용 검증 후 삭제요망 @Override public void print() { printDetectedObjects(); @@ -50,15 +55,18 @@ public void print() { } private void printDetectedObjects() { - System.out.println("[OBJECT]"); + System.out.println("\n[OBJECT]"); System.out.println("objects.size() = " + objects.size()); - objects.forEach(object -> System.out.println(object.getTargetName())); - objects.forEach(object -> System.out.println(object.getTargetName())); + objects.forEach(object -> { + System.out.println(); + System.out.println("object = " + object.getName()); + System.out.println("parent = " + object.getParent());}); } private void printDetectedTags() { - System.out.println("[TAG]"); + System.out.println("\n[TAG]"); System.out.println("tags.size() = " + tags.size()); - tags.forEach(tag -> System.out.println(tag.getTargetName())); + System.out.println(); + tags.forEach(tag -> System.out.println(tag.getName())); } } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionAnalysisResult.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionAnalysisResult.java index a1df5095..d162f0af 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionAnalysisResult.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionAnalysisResult.java @@ -1,15 +1,19 @@ package com.wakeUpTogetUp.togetUp.api.mission.domain; import java.util.List; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +@AllArgsConstructor(access = AccessLevel.PROTECTED) public abstract class VisionAnalysisResult { - public abstract List getEntities(); + protected final String targetName; + + public abstract boolean isFail(); - protected abstract boolean isFail(String object); + public abstract List getEntities(); - protected abstract List getMatches(String object, int size); + public abstract List getMatches(int size); - // TODO: 디버그용 삭제요망 public abstract void print(); } From f76356ff924bbc9fec3d265b3d0ebf64fa338204 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 17:57:30 +0900 Subject: [PATCH 06/23] =?UTF-8?q?=20#80=20[REFACTOR]=20CustomAnalysisEntit?= =?UTF-8?q?y=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - targetName 필드 삭제 --- .../mission/domain/CustomAnalysisEntity.java | 7 ++---- .../mission/domain/CustomDetectedObject.java | 14 ++++++----- .../api/mission/domain/CustomDetectedTag.java | 13 ++++++---- .../mapper/ObjectDetectedV32Mapper.java | 9 ++++--- .../mapper/ObjectDetectedV40Mapper.java | 10 +++++--- .../vision/mapper/TagDetectedV32Mapper.java | 24 +++++++++++++++++++ .../vision/mapper/TagDetectedV40Mapper.java | 2 +- 7 files changed, 57 insertions(+), 22 deletions(-) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV32Mapper.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomAnalysisEntity.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomAnalysisEntity.java index f634146e..7645cd4a 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomAnalysisEntity.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomAnalysisEntity.java @@ -6,17 +6,14 @@ @Getter public abstract class CustomAnalysisEntity { - protected final String targetName; - private final double confidence; private final BoundingBox box; - public CustomAnalysisEntity(String targetName, double confidence, BoundingBox box) { - this.targetName = targetName; + protected CustomAnalysisEntity(double confidence, BoundingBox box) { this.confidence = confidence; this.box = box; } - public abstract boolean isMatchEntity(String target); + protected abstract boolean isMatchEntity(Object target); } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedObject.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedObject.java index df99cdc1..e466bd1e 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedObject.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedObject.java @@ -7,21 +7,23 @@ @Getter public class CustomDetectedObject extends CustomAnalysisEntity { + private final String name; private final String parent; @Builder - private CustomDetectedObject(String objectName, String parent, double confidence, BoundingBox box) { - super(objectName, confidence, box); + private CustomDetectedObject(String name, String parent, double confidence, BoundingBox box) { + super(confidence, box); + this.name = name; this.parent = parent; } @Override - public boolean isMatchEntity(String targetObject) { - return concatObjectAndParent().toLowerCase().contains(targetObject.toLowerCase()); + public boolean isMatchEntity(Object target) { + return concatObjectAndParent() + .contains(target.toString().toLowerCase()); } public String concatObjectAndParent() { - return targetName + parent; + return (name + parent).toLowerCase(); } - } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedTag.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedTag.java index 21461368..3aca2b05 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedTag.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedTag.java @@ -5,13 +5,18 @@ @Getter public class CustomDetectedTag extends CustomAnalysisEntity { + + private final String name; + @Builder - public CustomDetectedTag(String tagName, double confidence) { - super(tagName, confidence, null); + public CustomDetectedTag(String name, double confidence) { + super(confidence, null); + this.name = name; } @Override - public boolean isMatchEntity(String target) { - return targetName.toLowerCase().contains(target.toLowerCase()); + protected boolean isMatchEntity(Object target) { + return name.toLowerCase() + .contains(target.toString().toLowerCase()); } } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV32Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV32Mapper.java index 2b9b1e66..437456a1 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV32Mapper.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV32Mapper.java @@ -3,6 +3,7 @@ import com.microsoft.azure.cognitiveservices.vision.computervision.models.DetectedObject; import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedObject; +import com.wakeUpTogetUp.togetUp.api.mission.model.Coord; import java.util.List; import java.util.stream.Collectors; import org.springframework.stereotype.Component; @@ -20,14 +21,16 @@ private CustomDetectedObject toCustomDetectedObject(DetectedObject detectedObjec String parent = detectedObject.parent() != null ? detectedObject.parent().objectProperty() : null; + Coord coord = new Coord( + detectedObject.rectangle().x(), + detectedObject.rectangle().y()); return CustomDetectedObject.builder() - .objectName(detectedObject.objectProperty()) + .name(detectedObject.objectProperty()) .parent(parent) .confidence(detectedObject.confidence()) .box(BoundingBox.builder() - .x(detectedObject.rectangle().x()) - .y(detectedObject.rectangle().y()) + .coord(coord) .w(detectedObject.rectangle().w()) .h(detectedObject.rectangle().h()) .build()) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV40Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV40Mapper.java index b2454316..27b5f593 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV40Mapper.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/ObjectDetectedV40Mapper.java @@ -3,6 +3,7 @@ import com.azure.ai.vision.imageanalysis.DetectedObject; import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedObject; +import com.wakeUpTogetUp.togetUp.api.mission.model.Coord; import java.util.List; import java.util.stream.Collectors; import org.springframework.stereotype.Component; @@ -16,13 +17,16 @@ public List toCustomDetectedObjects(List o } private CustomDetectedObject toCustomDetectedObject(DetectedObject detectedObject) { + Coord coord = new Coord( + detectedObject.getBoundingBox().getX(), + detectedObject.getBoundingBox().getY()); + return CustomDetectedObject.builder() - .objectName(detectedObject.getName()) + .name(detectedObject.getName()) .parent(null) .confidence(detectedObject.getConfidence()) .box(BoundingBox.builder() - .x(detectedObject.getBoundingBox().getX()) - .y(detectedObject.getBoundingBox().getY()) + .coord(coord) .w(detectedObject.getBoundingBox().getW()) .h(detectedObject.getBoundingBox().getH()) .build()) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV32Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV32Mapper.java new file mode 100644 index 00000000..7c4ad792 --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV32Mapper.java @@ -0,0 +1,24 @@ +package com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper; + +import com.microsoft.azure.cognitiveservices.vision.computervision.models.ImageTag; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedTag; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.stereotype.Component; + +@Component +public class TagDetectedV32Mapper { + + public List toCustomDetectedTags(List tags) { + return tags.stream() + .map(this::toCustomDetectedTag) + .collect(Collectors.toList()); + } + + private CustomDetectedTag toCustomDetectedTag(ImageTag tag) { + return CustomDetectedTag.builder() + .name(tag.name()) + .confidence(tag.confidence()) + .build(); + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV40Mapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV40Mapper.java index 61622d04..a6da101b 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV40Mapper.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/mapper/TagDetectedV40Mapper.java @@ -17,7 +17,7 @@ public List customDetectedTags(List tags) { private CustomDetectedTag toCustomDetectedTag(ContentTag tag) { return CustomDetectedTag.builder() - .tagName(tag.getName()) + .name(tag.getName()) .confidence(tag.getConfidence()) .build(); } From 615dfba43b5638ac30aae38593a4c1c2aace2b00 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 17:59:51 +0900 Subject: [PATCH 07/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=ED=91=9C=EC=A0=95?= =?UTF-8?q?=20=EC=9D=B8=EC=8B=9D=20=EA=B2=B0=EA=B3=BC=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/mission/MissionController.java | 13 ++--- .../domain/CustomDetectedFaceAnnotation.java | 47 ++++++++++++++++ .../FaceAnnotationRecognitionResult.java | 56 +++++++++++++++++++ .../model/{Emotion.java => Expression.java} | 8 +-- 4 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedFaceAnnotation.java create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/FaceAnnotationRecognitionResult.java rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/{Emotion.java => Expression.java} (52%) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java index e9ed6cc7..7c049238 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java @@ -1,6 +1,5 @@ package com.wakeUpTogetUp.togetUp.api.mission; -import com.google.cloud.vision.v1.FaceAnnotation; import com.wakeUpTogetUp.togetUp.api.auth.AuthUser; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.infra.aws.s3.FileService; @@ -79,10 +78,9 @@ BaseResponse getObjectDetectionMissions( public BaseResponse recognizeObject( @Parameter(hidden = true) @AuthUser Integer userId, @Parameter(required = true, description = "미션 수행 사진") @RequestPart @ImageFile MultipartFile missionImage, - @Parameter(required = true, description = "탐지할 객체") @PathVariable String object - ) throws Exception { + @Parameter(required = true, description = "탐지할 객체") @PathVariable String object) { List detectedObjects = missionService.getDetectionResult(object, missionImage); - CustomFile file = missionImageService.processODResultImage(missionImage, detectedObjects); + CustomFile file = missionImageService.processResultImage(missionImage, detectedObjects, object); String imageUrl = fileService.uploadFile(file, "mission"); return new BaseResponse<>(Status.MISSION_SUCCESS, new MissionPerfomRes(imageUrl)); @@ -103,10 +101,9 @@ public BaseResponse recognizeObject( public BaseResponse recognizeFaceExpression( @Parameter(hidden = true) @AuthUser Integer userId, @Parameter(required = true, description = "미션 수행 사진") @RequestPart @ImageFile MultipartFile missionImage, - @Parameter(required = true, description = "탐지할 표정(`joy`/`sorrow`/`anger`/`surprise`)") @PathVariable String object - ) throws Exception { - List faceAnnotations = missionService.getFaceRecognitionResult(object, missionImage); - CustomFile file = missionImageService.processFRResultImage(missionImage, faceAnnotations, object); + @Parameter(required = true, description = "탐지할 표정(`joy`/`sorrow`/`anger`/`surprise`)") @PathVariable String object) { + List faceAnnotations = missionService.getFaceRecognitionResult(object, missionImage); + CustomFile file = missionImageService.processResultImage(missionImage, faceAnnotations, object); String imageUrl = fileService.uploadFile(file, "mission"); return new BaseResponse<>(Status.MISSION_SUCCESS, new MissionPerfomRes(imageUrl)); diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedFaceAnnotation.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedFaceAnnotation.java new file mode 100644 index 00000000..c1a9e21b --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/CustomDetectedFaceAnnotation.java @@ -0,0 +1,47 @@ +package com.wakeUpTogetUp.togetUp.api.mission.domain; + +import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; +import com.wakeUpTogetUp.togetUp.api.mission.model.Expression; +import com.wakeUpTogetUp.togetUp.common.Status; +import com.wakeUpTogetUp.togetUp.exception.BaseException; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class CustomDetectedFaceAnnotation extends CustomAnalysisEntity { + + private final int joyLikelihood; + private final int sorrowLikelihood; + private final int angerLikelihood; + private final int surpriseLikelihood; + + @Builder + private CustomDetectedFaceAnnotation(double confidence, BoundingBox box, int joyLikelihood, + int sorrowLikelihood, int angerLikelihood, int surpriseLikelihood) { + super(confidence, box); + this.joyLikelihood = joyLikelihood; + this.sorrowLikelihood = sorrowLikelihood; + this.angerLikelihood = angerLikelihood; + this.surpriseLikelihood = surpriseLikelihood; + } + + @Override + protected boolean isMatchEntity(Object target) { + return getLikelihood((Expression) target) >= 3; + } + + private int getLikelihood(Expression expression) { + switch (expression) { + case JOY: + return joyLikelihood; + case SORROW: + return sorrowLikelihood; + case ANGER: + return angerLikelihood; + case SURPRISE: + return surpriseLikelihood; + default: + throw new BaseException(Status.INVALID_OBJECT_NAME); + } + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/FaceAnnotationRecognitionResult.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/FaceAnnotationRecognitionResult.java new file mode 100644 index 00000000..643d0e56 --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/FaceAnnotationRecognitionResult.java @@ -0,0 +1,56 @@ +package com.wakeUpTogetUp.togetUp.api.mission.domain; + +import com.wakeUpTogetUp.togetUp.api.mission.model.Expression; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; +import lombok.Builder; + +public class FaceAnnotationRecognitionResult extends VisionAnalysisResult { + + private final Expression expression; + private final List faceAnnotations; + + @Builder + public FaceAnnotationRecognitionResult(String target, List faceAnnotations) { + super(target); + this.expression = Expression.fromName(targetName); + this.faceAnnotations = faceAnnotations; + } + + @Override + public boolean isFail() { + return faceAnnotations.stream() + .noneMatch(faceAnnotation -> faceAnnotation.isMatchEntity(this.expression)); + } + + @Override + public List getEntities() { + return faceAnnotations.stream() + .map(CustomAnalysisEntity.class::cast) + .collect(Collectors.toList()); + } + + @Override + public List getMatches(int size) { + return faceAnnotations.stream() + .filter(faceAnnotation -> faceAnnotation.isMatchEntity(this.expression)) + .sorted(Comparator.comparing(CustomDetectedFaceAnnotation::getConfidence).reversed()) + .limit(size) + .collect(Collectors.toList()); + } + + @Override + public void print() { + System.out.println("\n[FACE ANNOTATION]"); + System.out.println("emotions.size() = " + faceAnnotations.size()); + + faceAnnotations.forEach(faceAnnotation -> { + System.out.println("JOY = " + faceAnnotation.getJoyLikelihood()); + System.out.println("SORROW = " + faceAnnotation.getSorrowLikelihood()); + System.out.println("ANGER = " + faceAnnotation.getAngerLikelihood()); + System.out.println("SURPRISE = " + faceAnnotation.getSurpriseLikelihood()); + System.out.println(); + }); + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Emotion.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Expression.java similarity index 52% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Emotion.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Expression.java index 43ffc308..d1c3c367 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Emotion.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/Expression.java @@ -3,17 +3,17 @@ import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; -public enum Emotion { +public enum Expression { JOY, SORROW, ANGER, SURPRISE; - public static Emotion fromName(String object) { + public static Expression fromName(String name) { try { - return Emotion.valueOf(object.toUpperCase()); + return Expression.valueOf(name.toUpperCase()); } catch (IllegalArgumentException exception) { - throw new BaseException(Status.BAD_REQUEST_PARAM); + throw new BaseException("해당하는 감정 열거형 값이 없습니다.", exception, Status.BAD_REQUEST_PARAM); } } } From 7830ae389203d4a4cfe863184555a23a11a05451 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 18:01:16 +0900 Subject: [PATCH 08/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=ED=91=9C=EC=A0=95?= =?UTF-8?q?=20=EC=9D=B8=EC=8B=9D=20=EA=B2=B0=EA=B3=BC=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../togetUp/api/mission/MissionService.java | 83 +++++-------------- .../google/vision/GoogleVisionService.java | 20 +++-- .../vision/mapper/GoogleVisionMapper.java | 48 +++++++++++ 3 files changed, 82 insertions(+), 69 deletions(-) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/mapper/GoogleVisionMapper.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java index 924ea725..7732a254 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java @@ -1,18 +1,15 @@ package com.wakeUpTogetUp.togetUp.api.mission; -import com.google.cloud.vision.v1.FaceAnnotation; -import com.google.cloud.vision.v1.Likelihood; import com.wakeUpTogetUp.togetUp.api.alarm.AlarmRepository; import com.wakeUpTogetUp.togetUp.api.alarm.model.Alarm; +import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionAnalysisResult; import com.wakeUpTogetUp.togetUp.api.mission.dto.request.MissionCompleteReq; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionCompleteRes; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog; -import com.wakeUpTogetUp.togetUp.api.mission.domain.MissionPerformResult; import com.wakeUpTogetUp.togetUp.infra.azure.vision.AzureVision32Service; import com.wakeUpTogetUp.togetUp.infra.azure.vision.AzureVision40Service; import com.wakeUpTogetUp.togetUp.infra.google.vision.GoogleVisionService; -import com.wakeUpTogetUp.togetUp.api.mission.service.ObjectDetectionService; import com.wakeUpTogetUp.togetUp.api.notification.NotificationService; import com.wakeUpTogetUp.togetUp.api.users.UserAvatarService; import com.wakeUpTogetUp.togetUp.api.users.UserRepository; @@ -23,9 +20,7 @@ import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; -import java.util.Comparator; import java.util.List; -import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -40,7 +35,8 @@ @Slf4j public class MissionService { - private final ObjectDetectionService objectDetectionService; + private final int MAX_MATCHES_LIMIT = 3; + private final AzureVision32Service azureVision32Service; private final AzureVision40Service azureVision40Service; private final GoogleVisionService googleVisionService; @@ -51,70 +47,32 @@ public class MissionService { private final UserRepository userRepository; private final NotificationService notificationService; - public List getDetectionResult(String object, MultipartFile missionImage) - throws Exception { - MissionPerformResult result = MissionPerformResult.builder() - .object(object) - .analysisResult(azureVision40Service.detect(missionImage)) - .build(); - - // TODO: 디버그용 메서드 검증 후 삭제요망 - result.getAnalysisResult().print(); + public List getDetectionResult(String object, MultipartFile missionImage) { + VisionAnalysisResult result = + azureVision32Service.getObjectDetectionResult(missionImage) + .target(object) + .build(); + result.print(); if (result.isFail()) { throw new BaseException(Status.MISSION_FAILURE); } - return result.getMatches(); + return result.getMatches(MAX_MATCHES_LIMIT); } - public List getFaceRecognitionResult(String object, MultipartFile missionImage) { - Emotion emotion = Emotion.fromName(object); - List faceAnnotations = googleVisionService.getFaceRecognitionResult(missionImage); - - if (faceAnnotations.isEmpty()) { - throw new BaseException(Status.NO_DETECTED_OBJECT); - } + public List getFaceRecognitionResult(String object, MultipartFile missionImage) { + VisionAnalysisResult result = + googleVisionService.getFaceRecognitionResult(missionImage) + .target(object) + .build(); + result.print(); - List highestConfidenceFaces = faceAnnotations.stream() - .filter(face -> getLikelihood(emotion, face).getNumber() >= 3) - .sorted(Comparator.comparing(FaceAnnotation::getDetectionConfidence).reversed()) - .limit(3) - .collect(Collectors.toList()); - - if (highestConfidenceFaces.isEmpty()) { + if (result.isFail()) { throw new BaseException(Status.MISSION_FAILURE); } - return highestConfidenceFaces; - } - - private Likelihood getLikelihood(Emotion emotion, FaceAnnotation face) { - switch (emotion) { - case JOY: - return face.getJoyLikelihood(); - case SORROW: - return face.getSorrowLikelihood(); - case ANGER: - return face.getAngerLikelihood(); - case SURPRISE: - return face.getSurpriseLikelihood(); - default: - throw new BaseException(Status.INVALID_OBJECT_NAME); - } - } - - // 모델로 객체 인식 - public void recognizeObjectByModel(String object, MultipartFile missionImage) { - for (String objectDetected : objectDetectionService.detectObject(missionImage)) { - log.info("objectDetected = " + objectDetected); - - if (objectDetected.equals(object)) { - return; - } - } - - throw new BaseException(Status.MISSION_FAILURE); + return result.getMatches(MAX_MATCHES_LIMIT); } @Transactional @@ -142,8 +100,6 @@ public MissionCompleteRes afterMissionComplete(int userId, MissionCompleteReq re private void sendNotificationIfRoomExists(Alarm alarm, User user) { if (alarm.isRoomAlarm()) { - // 미션 성공 후 처리 로직과 알림 보내기 로직을 독립적으로 분리 - // 알림을 보내는데 실패해도 모든 과정이 롤백되지 않음 try { notificationService.sendNotificationToUsersInRoom(alarm.getId(), user.getId()); } catch (BaseException e) { @@ -165,5 +121,4 @@ private void createMissionLog(User user, MissionCompleteReq req) { missionLogRepository.save(missionLog); } -} - +} \ No newline at end of file diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java index abdaf9a9..e8448a67 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java @@ -1,9 +1,12 @@ package com.wakeUpTogetUp.togetUp.infra.google.vision; import com.google.cloud.vision.v1.AnnotateImageResponse; -import com.google.cloud.vision.v1.FaceAnnotation; import com.google.cloud.vision.v1.Feature.Type; -import java.util.List; +import com.wakeUpTogetUp.togetUp.api.mission.domain.FaceAnnotationRecognitionResult; +import com.wakeUpTogetUp.togetUp.api.mission.domain.FaceAnnotationRecognitionResult.FaceAnnotationRecognitionResultBuilder; +import com.wakeUpTogetUp.togetUp.common.Status; +import com.wakeUpTogetUp.togetUp.exception.BaseException; +import com.wakeUpTogetUp.togetUp.infra.google.vision.mapper.GoogleVisionMapper; import lombok.RequiredArgsConstructor; import org.springframework.cloud.gcp.vision.CloudVisionTemplate; import org.springframework.stereotype.Service; @@ -14,10 +17,17 @@ public class GoogleVisionService { private final CloudVisionTemplate cloudVisionTemplate; - public List getFaceRecognitionResult(MultipartFile file) { + private final GoogleVisionMapper googleVisionMapper; + + public FaceAnnotationRecognitionResultBuilder getFaceRecognitionResult(MultipartFile file) { AnnotateImageResponse response = - this.cloudVisionTemplate.analyzeImage(file.getResource(), Type.FACE_DETECTION); + cloudVisionTemplate.analyzeImage(file.getResource(), Type.FACE_DETECTION); + + if (response.getFaceAnnotationsList().isEmpty()) { + throw new BaseException(Status.NO_DETECTED_OBJECT); + } - return response.getFaceAnnotationsList(); + return FaceAnnotationRecognitionResult.builder() + .faceAnnotations(googleVisionMapper.toCustomRecognizedEmotions(response.getFaceAnnotationsList())); } } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/mapper/GoogleVisionMapper.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/mapper/GoogleVisionMapper.java new file mode 100644 index 00000000..0988d9c5 --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/mapper/GoogleVisionMapper.java @@ -0,0 +1,48 @@ +package com.wakeUpTogetUp.togetUp.infra.google.vision.mapper; + +import com.google.cloud.vision.v1.FaceAnnotation; +import com.google.cloud.vision.v1.Vertex; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedFaceAnnotation; +import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; +import com.wakeUpTogetUp.togetUp.api.mission.model.Coord; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.stereotype.Component; + +@Component +public class GoogleVisionMapper { + + public List toCustomRecognizedEmotions(List faceAnnotations) { + return faceAnnotations.stream() + .map(this::toCustomRecognizedEmotion) + .collect(Collectors.toList()); + } + + private CustomDetectedFaceAnnotation toCustomRecognizedEmotion(FaceAnnotation faceAnnotation) { + return CustomDetectedFaceAnnotation.builder() + .joyLikelihood(faceAnnotation.getJoyLikelihoodValue()) + .sorrowLikelihood(faceAnnotation.getSorrowLikelihoodValue()) + .angerLikelihood(faceAnnotation.getAngerLikelihoodValue()) + .surpriseLikelihood(faceAnnotation.getSurpriseLikelihoodValue()) + .confidence(faceAnnotation.getDetectionConfidence()) + .box(toBoundingBox(faceAnnotation.getBoundingPoly().getVerticesList())) + .build(); + } + + private BoundingBox toBoundingBox(List vertexs) { + int x1 = vertexs.get(0).getX(); + int y1 = vertexs.get(0).getY(); + int x2 = vertexs.get(2).getX(); + int y2 = vertexs.get(2).getY(); + + Coord coord = new Coord(x1, y1); + int width = x2 - x1; + int height = y2 - y1; + + return BoundingBox.builder() + .coord(coord) + .w(width) + .h(height) + .build(); + } +} From de8996397485382f8c78e820d66771dcd7ad48b1 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 18:07:44 +0900 Subject: [PATCH 09/23] =?UTF-8?q?=20#80=20[REFACTOR]=20ImageProcessor=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B1=85=EC=9E=84=EC=9D=84=20?= =?UTF-8?q?=EC=97=AC=EB=9F=AC=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ImageUtil: 일반적인 기능 처리 (이미지 파일 읽기, 메타 데이터 가져오기 등) - ImageDrawer: 이미지 위에 그림 그리기 - ImageProcessor: 압축, 리사이징 등 이미지 전체 관련 처리 --- .../togetUp/exception/BaseException.java | 10 + .../infra/aws/s3/model/ImageContentType.java | 9 + .../wakeUpTogetUp/togetUp/utils/FileUtil.java | 12 + .../togetUp/utils/ImageDrawer.java | 124 +++++++++ .../togetUp/utils/ImageProcessor.java | 263 +++++++----------- .../togetUp/utils/ImageUtil.java | 50 ++++ 6 files changed, 313 insertions(+), 155 deletions(-) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageDrawer.java create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageUtil.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/exception/BaseException.java b/src/main/java/com/wakeUpTogetUp/togetUp/exception/BaseException.java index 8ee7ba3a..83b74f4a 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/exception/BaseException.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/exception/BaseException.java @@ -11,4 +11,14 @@ @AllArgsConstructor public class BaseException extends RuntimeException { private Status status; + + public BaseException(String message, Throwable cause, Status status) { + super(message, cause); + this.status = status; + } + + public BaseException(Throwable cause, Status status) { + super(cause); + this.status = status; + } } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/model/ImageContentType.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/model/ImageContentType.java index 52d682c3..33a2168a 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/model/ImageContentType.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/model/ImageContentType.java @@ -1,5 +1,7 @@ package com.wakeUpTogetUp.togetUp.infra.aws.s3.model; +import com.wakeUpTogetUp.togetUp.common.Status; +import com.wakeUpTogetUp.togetUp.exception.BaseException; import java.util.Arrays; public enum ImageContentType { @@ -25,6 +27,13 @@ public String getExtension() { return extension; } + public static ImageContentType getByContentType(String contentType) { + return Arrays.stream(ImageContentType.values()) + .filter(type -> type.contentType.equals(contentType)) + .findAny() + .orElseThrow(() -> new BaseException(Status.INVALID_FILE_CONTENT_TYPE_EXCEPTION)); + } + public static boolean exists(String contentType, String extension) { return Arrays.stream(ImageContentType.values()) .anyMatch(type -> type.fieldsMatches(contentType, extension)); diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/FileUtil.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/FileUtil.java index 88f4dba3..7d7d8367 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/FileUtil.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/FileUtil.java @@ -1,9 +1,13 @@ package com.wakeUpTogetUp.togetUp.utils; +import com.wakeUpTogetUp.togetUp.common.Status; +import com.wakeUpTogetUp.togetUp.exception.BaseException; +import java.io.IOException; import java.util.Locale; import java.util.UUID; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class FileUtil { @@ -11,6 +15,14 @@ public class FileUtil { private static final String FILE_NAME_FORMAT = "%s/%s/%s"; private static final String FILE_DATE_TIME_FORMAT = "yyyy/MM/dd"; + public static byte[] getBytes(MultipartFile file) { + try { + return file.getBytes(); + } catch (IOException e) { + throw new BaseException("파일 읽기를 실패했습니다.", e, Status.INVALID_IMAGE); + } + } + public static String extractExtension(String fileName) { FileValidator.validateFileName(fileName); diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageDrawer.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageDrawer.java new file mode 100644 index 00000000..f049d2c0 --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageDrawer.java @@ -0,0 +1,124 @@ +package com.wakeUpTogetUp.togetUp.utils; + +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; +import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; +import com.wakeUpTogetUp.togetUp.api.mission.model.Coord; +import com.wakeUpTogetUp.togetUp.common.Status; +import com.wakeUpTogetUp.togetUp.exception.BaseException; +import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.ImageContentType; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Random; +import javax.imageio.ImageIO; +import org.apache.commons.imaging.formats.tiff.TiffImageMetadata; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +@Component +public class ImageDrawer extends ImageUtil { + + private final Random rand = new Random(); + private BufferedImage image; + private Color color; + private int thickness; + private int fontSize; + + private void setup(MultipartFile file) { + setOrientedImage(file); + + this.color = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256)); + int minWH = Math.min(image.getWidth(), image.getHeight()); + this.thickness = minWH / 150; + this.fontSize = minWH / 20; + } + + private void setOrientedImage(MultipartFile file) { + this.image = readImage(FileUtil.getBytes(file)); + TiffImageMetadata metadata = getImageMetadata(file); + image = ImageProcessor.orientImage(image, metadata); + } + + public byte[] drawResultOnImage(MultipartFile file, List entities, String object) { + setup(file); + + drawEntityRectangles(entities); + drawEntityLabel(entities, object); + + String format = ImageContentType + .getByContentType(file.getContentType()) + .getExtension(); + + + + /** + * + */ + + System.out.println("X = " + entities.get(0).getBox().getX()); + System.out.println("Y = " + entities.get(0).getBox().getY()); + + File outputFile2 = new File("src/main/resources/images/image_drawn.jpg"); + try { + ImageIO.write(image, "jpg", outputFile2); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Error saving the image file: " + e.getMessage()); + } + + /** + * + */ + + + try (ByteArrayOutputStream outputImageStream = new ByteArrayOutputStream()) { + ImageIO.write(image, format, outputImageStream); + return outputImageStream.toByteArray(); + } catch (IOException e) { + throw new BaseException(IMAGE_WRITE_ERROR_MESSAGE, e, Status.INVALID_IMAGE); + } + } + + private void drawEntityRectangles(List entities) { + Graphics2D g2d = image.createGraphics(); + + for (CustomAnalysisEntity entity : entities) { + BoundingBox box = entity.getBox(); + + drawRectangle(g2d, box); + } + g2d.dispose(); + } + + private void drawEntityLabel(List entities, String object) { + Graphics2D g2d = image.createGraphics(); + + for (CustomAnalysisEntity entity : entities) { + BoundingBox box = entity.getBox(); + Coord coord = new Coord(box.getX(), box.getY() - (image.getHeight() / 100)); + String entityLabel = String.format("%s : %.3f", object, entity.getConfidence()); + + drawString(g2d, coord, entityLabel); + } + g2d.dispose(); + } + + private void drawRectangle(Graphics2D g2d, BoundingBox box) { + g2d.setColor(color); + g2d.setStroke(new BasicStroke(thickness)); + g2d.draw(new Rectangle2D.Float(box.getX(), box.getY(), box.getW(), box.getH())); + } + + private void drawString(Graphics2D g2d, Coord coord, String content) { + g2d.setColor(color); + g2d.setFont(new Font("Arial", Font.PLAIN, fontSize)); + g2d.drawString(content, coord.getX(), coord.getY()); + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java index 08e8bce6..c36dd562 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java @@ -1,71 +1,89 @@ package com.wakeUpTogetUp.togetUp.utils; -import static org.apache.commons.imaging.Imaging.getMetadata; - -import com.google.cloud.vision.v1.FaceAnnotation; -import com.google.cloud.vision.v1.Vertex; -import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; -import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.Font; +import com.wakeUpTogetUp.togetUp.common.Status; +import com.wakeUpTogetUp.togetUp.exception.BaseException; +import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.ImageContentType; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.geom.AffineTransform; -import java.awt.geom.Rectangle2D; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Iterator; -import java.util.List; -import java.util.Random; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import org.apache.commons.imaging.ImageReadException; -import org.apache.commons.imaging.common.ImageMetadata; -import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata; import org.apache.commons.imaging.formats.tiff.TiffField; import org.apache.commons.imaging.formats.tiff.TiffImageMetadata; import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants; -import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; -@Component -public class ImageProcessor { +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class ImageProcessor extends ImageUtil { - public byte[] compress(byte[] imageToByte, float quality) throws IOException { - BufferedImage originalImage = readImage(imageToByte); + public static byte[] compressUntil(MultipartFile file, int sizeOfMB) { + ImageContentType contentType = ImageContentType.getByContentType(file.getContentType()); + byte[] data = FileUtil.getBytes(file); + int sizeLimit = 1024 * 1024 * sizeOfMB; - ByteArrayOutputStream compressedImageStream = new ByteArrayOutputStream(); - Iterator writers = ImageIO.getImageWritersByFormatName("jpg"); + if (data.length < sizeLimit) { + return data; + } - if (writers.hasNext()) { - ImageWriter writer = writers.next(); - ImageWriteParam param = writer.getDefaultWriteParam(); + // TODO: 디버그용 삭제 + System.out.println("[압축]"); + System.out.println("original size: " + data.length); + // TODO: 무한루프 빠지지 않게 처리하기 + // TODO: 최적의 quality 찾기 + while (data.length >= sizeLimit) { + data = compress(data, 0.5f, contentType); + System.out.println(data.length); + } + + TiffImageMetadata metadata = getImageMetadata(file); + return orientByteImage(data, metadata, contentType); + } - if (param.canWriteCompressed()) { - param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); - param.setCompressionQuality(quality); // 0.0 to 1.0 + private static byte[] compress(byte[] imageByte, float quality, ImageContentType contentType) { + BufferedImage originalImage = readImage(imageByte); + + try (ByteArrayOutputStream compressedImageStream = new ByteArrayOutputStream()) { + Iterator writers = + ImageIO.getImageWritersByFormatName(contentType.getExtension()); + + if (writers.hasNext()) { + ImageWriter writer = writers.next(); + ImageWriteParam param = writer.getDefaultWriteParam(); + setCompressImageWriterParam(param, quality); + + writer.setOutput(ImageIO.createImageOutputStream(compressedImageStream)); + writer.write(null, new IIOImage(originalImage, null, null), param); + writer.dispose(); + } else { + throw new IllegalStateException("No writers found"); } - writer.setOutput(ImageIO.createImageOutputStream(compressedImageStream)); - writer.write(null, new IIOImage(originalImage, null, null), param); - writer.dispose(); - } else { - throw new IllegalStateException("No writers found"); + return compressedImageStream.toByteArray(); + } catch (IOException e) { + throw new BaseException(IMAGE_WRITE_ERROR_MESSAGE, e, Status.INVALID_IMAGE); } - compressedImageStream.close(); + } - return compressedImageStream.toByteArray(); + private static void setCompressImageWriterParam(ImageWriteParam param, float quality) { + if (param.canWriteCompressed()) { + param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + param.setCompressionQuality(quality); + } } - public byte[] resize(byte[] imageToByte, double ratio) throws IOException { - BufferedImage originalImage = readImage(imageToByte); + public static byte[] resize(byte[] imageByte, double ratio) throws IOException { + BufferedImage originalImage = readImage(imageByte); int scaledWidth = (int) (originalImage.getWidth() * ratio); int scaledHeight = (int) (originalImage.getHeight() * ratio); @@ -86,8 +104,8 @@ public byte[] resize(byte[] imageToByte, double ratio) throws IOException { return compressedImageStream.toByteArray(); } - public byte[] rotate(byte[] imageToByte, int degrees) throws IOException { - BufferedImage originalImage = readImage(imageToByte); + public static byte[] rotate(byte[] imageByte, int degrees) throws IOException { + BufferedImage originalImage = readImage(imageByte); AffineTransform transform = new AffineTransform(); transform.rotate(Math.toRadians(degrees), @@ -104,14 +122,56 @@ public byte[] rotate(byte[] imageToByte, int degrees) throws IOException { return rotatedImageStream.toByteArray(); } - public byte[] orientImage(byte[] imageToByte, TiffImageMetadata metadata) - throws IOException, ImageReadException { - TiffField orientationField = metadata != null - ? metadata.findField(TiffTagConstants.TIFF_TAG_ORIENTATION) - : null; - int orientation = orientationField != null ? orientationField.getIntValue() : 1; + protected static byte[] orientByteImage(byte[] imageByte, TiffImageMetadata metadata, ImageContentType contentType) { + int orientation = getOrientation(metadata); + BufferedImage originalImage = readImage(imageByte); + BufferedImage rotatedImage = transformImage(originalImage, orientation); + + BufferedImage newImage = new BufferedImage( + rotatedImage.getWidth(), + rotatedImage.getHeight(), + BufferedImage.TYPE_INT_RGB); + + Graphics2D g = newImage.createGraphics(); + g.drawImage(rotatedImage, 0, 0, null); + g.dispose(); - BufferedImage originalImage = readImage(imageToByte); + try (ByteArrayOutputStream rotatedImageStream = new ByteArrayOutputStream();) { + ImageIO.write(newImage, contentType.getExtension(), rotatedImageStream); + return rotatedImageStream.toByteArray(); + } catch (IOException e) { + throw new BaseException(IMAGE_WRITE_ERROR_MESSAGE, e, Status.INVALID_IMAGE); + } + } + + protected static BufferedImage orientImage(BufferedImage image, TiffImageMetadata metadata) { + int orientation = getOrientation(metadata); + image = transformImage(image, orientation); + + BufferedImage newImage = new BufferedImage( + image.getWidth(), + image.getHeight(), + BufferedImage.TYPE_INT_RGB); + + Graphics2D g = newImage.createGraphics(); + g.drawImage(image, 0, 0, null); + + return newImage; + } + + private static int getOrientation(TiffImageMetadata metadata) { + try { + TiffField tiffField = metadata != null + ? metadata.findField(TiffTagConstants.TIFF_TAG_ORIENTATION) + : null; + + return tiffField != null ? tiffField.getIntValue() : 1; + } catch (ImageReadException e) { + throw new BaseException(e, Status.INVALID_IMAGE); + } + } + + private static BufferedImage transformImage(BufferedImage originalImage, int orientation) { AffineTransform affineTransform = new AffineTransform(); switch (orientation) { @@ -151,115 +211,8 @@ public byte[] orientImage(byte[] imageToByte, TiffImageMetadata metadata) break; } - AffineTransformOp op = - new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR); - BufferedImage rotatedImage = op.filter(originalImage, null); - - // AffineTransformOp에 의해 반환된 BufferedImage의 타입이 원본과 다를 수 있어 때로 약간의 색상 변화나 문제가 발생할 수 있다. - // 새로운 BufferedImage를 생성하고 그 위에 결과 이미지를 그린다. - BufferedImage newImage = - new BufferedImage(rotatedImage.getWidth(), rotatedImage.getHeight(), BufferedImage.TYPE_INT_RGB); - - Graphics2D g = newImage.createGraphics(); - g.drawImage(rotatedImage, 0, 0, null); - g.dispose(); - - ByteArrayOutputStream rotatedImageStream = new ByteArrayOutputStream(); - ImageIO.write(newImage, "jpg", rotatedImageStream); - rotatedImageStream.close(); - - return rotatedImageStream.toByteArray(); - } - - - // TODO : 인식 결과 그림 그리기 하나로 통일하기 - public byte[] drawODResultOnImage(MultipartFile file, List entities) - throws IOException { - BufferedImage originalImage = readImage(file.getBytes()); - Graphics2D g2d = originalImage.createGraphics(); - - for (CustomAnalysisEntity entity : entities) { - BoundingBox box = entity.getBox(); - - int minDwDh = Math.min(originalImage.getWidth(), originalImage.getHeight()); - - int thickness = minDwDh / 150; - Random rand = new Random(); - g2d.setColor(new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256))); - g2d.setStroke(new BasicStroke(thickness)); - g2d.draw(new Rectangle2D.Float(box.getX(), box.getY(), box.getW(), box.getH())); - - int fontSize = minDwDh / 25; - g2d.setFont(new Font("Arial", Font.PLAIN, fontSize)); - g2d.drawString( - entity.getTargetName() + " : " + String.format("%.3f", entity.getConfidence()), - box.getX(), box.getY() - (float) (originalImage.getHeight() / 100)); - } - g2d.dispose(); - - var outputImageStream = new ByteArrayOutputStream(); - ImageIO.write(originalImage, "jpg", outputImageStream); - outputImageStream.close(); - - return outputImageStream.toByteArray(); - } - - public byte[] drawFRResultOnImage(MultipartFile file, List faceAnnotations, String object) - throws IOException { - BufferedImage originalImage = readImage(file.getBytes()); + AffineTransformOp op = new AffineTransformOp(affineTransform, AffineTransformOp.TYPE_BILINEAR); - Graphics2D g2d = originalImage.createGraphics(); - - for (FaceAnnotation face : faceAnnotations) { - List coord = face.getBoundingPoly().getVerticesList(); - - int x1 = coord.get(0).getX(); - int y1 = coord.get(0).getY(); - int x2 = coord.get(2).getX(); - int y2 = coord.get(2).getY(); - - int width = x2 - x1; - int height = y2 - y1; - - int minDwDh = Math.min(originalImage.getWidth(), originalImage.getHeight()); - int thickness = minDwDh / 150; - - Random rand = new Random(); - g2d.setColor(new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256))); - g2d.setStroke(new BasicStroke(thickness)); - g2d.draw(new Rectangle2D.Float(x1, y1, width, height)); - - int fontSize = minDwDh / 25; - g2d.setFont(new Font("Arial", Font.PLAIN, fontSize)); - g2d.drawString( - object, - x1, y1 - (float) (originalImage.getHeight() / 100)); - } - g2d.dispose(); - - var outputImageStream = new ByteArrayOutputStream(); - ImageIO.write(originalImage, "jpg", outputImageStream); - outputImageStream.close(); - - return outputImageStream.toByteArray(); - } - - private BufferedImage readImage(byte[] data) throws IOException { - return ImageIO.read(new ByteArrayInputStream(data)); - } - - public TiffImageMetadata getImageMetadata(MultipartFile file) - throws IOException, ImageReadException { - return readExifMetadata(file.getBytes()); - } - - private TiffImageMetadata readExifMetadata(byte[] jpegData) - throws IOException, ImageReadException { - ImageMetadata imageMetadata = getMetadata(jpegData); - if (imageMetadata == null) { - return null; - } - JpegImageMetadata jpegMetadata = (JpegImageMetadata) imageMetadata; - return jpegMetadata.getExif(); + return op.filter(originalImage, null); } } \ No newline at end of file diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageUtil.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageUtil.java new file mode 100644 index 00000000..51fe35df --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageUtil.java @@ -0,0 +1,50 @@ +package com.wakeUpTogetUp.togetUp.utils; + +import static org.apache.commons.imaging.Imaging.getMetadata; + +import com.wakeUpTogetUp.togetUp.common.Status; +import com.wakeUpTogetUp.togetUp.exception.BaseException; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import javax.imageio.ImageIO; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.imaging.common.ImageMetadata; +import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata; +import org.apache.commons.imaging.formats.tiff.TiffImageMetadata; +import org.springframework.web.multipart.MultipartFile; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ImageUtil { + + protected static final String IMAGE_IO_ERROR_MESSAGE = "이미지 입출력을 실패했습니다"; + protected static final String IMAGE_WRITE_ERROR_MESSAGE = "이미지 쓰기에 실패했습니다."; + private static final String EXTRACT_METADATA_ERROR_MESSAGE = "파일 메타데이터 추출에 실패했습니다."; + + protected static BufferedImage readImage(byte[] data) { + try { + return ImageIO.read(new ByteArrayInputStream(data)); + } catch (IOException e) { + throw new BaseException(IMAGE_IO_ERROR_MESSAGE, e, Status.INVALID_IMAGE); + } + } + + protected static TiffImageMetadata getImageMetadata(MultipartFile file) { + return readExifMetadata(FileUtil.getBytes(file)); + } + + // TODO: 다른 파일 형식 메타 데이터도 가져오게 + private static TiffImageMetadata readExifMetadata(byte[] data) { + try{ + ImageMetadata imageMetadata = getMetadata(data); + if (imageMetadata == null) { + return null; + } + JpegImageMetadata jpegMetadata = (JpegImageMetadata) imageMetadata; + return jpegMetadata.getExif(); + } catch (Exception e) { + throw new BaseException(EXTRACT_METADATA_ERROR_MESSAGE, e, Status.INVALID_IMAGE); + } + } +} \ No newline at end of file From b06d70a8b4d1e5d2f7ca7985e3ea98a52fae0d7b Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 18:09:20 +0900 Subject: [PATCH 10/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=EC=9D=B8=EC=8B=9D?= =?UTF-8?q?=20api=20request=20=EC=A1=B0=EA=B1=B4=20=EB=A7=8C=EC=A1=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=B4=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=95=95=EC=B6=95=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mission/service/MissionImageService.java | 36 ++++-------- .../azure/vision/AzureVision32Service.java | 55 ++++++++++++------- .../azure/vision/AzureVision40Service.java | 43 ++++++++++----- 3 files changed, 77 insertions(+), 57 deletions(-) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java index 1c11552b..8a3c6241 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java @@ -1,42 +1,30 @@ package com.wakeUpTogetUp.togetUp.api.mission.service; -import com.google.cloud.vision.v1.FaceAnnotation; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; -import com.wakeUpTogetUp.togetUp.utils.ImageProcessor; +import com.wakeUpTogetUp.togetUp.utils.FileUtil; +import com.wakeUpTogetUp.togetUp.utils.ImageDrawer; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; -import java.io.IOException; import java.util.List; import lombok.RequiredArgsConstructor; -import org.apache.commons.imaging.ImageReadException; -import org.apache.commons.imaging.formats.tiff.TiffImageMetadata; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @Service @RequiredArgsConstructor public class MissionImageService { - private final ImageProcessor imageProcessor; - public CustomFile processODResultImage( - MultipartFile file, List entities) throws IOException, ImageReadException { + private final ImageDrawer imageDrawer; + + public CustomFile processResultImage( + MultipartFile file, + List entities, + String object + ) { if (entities.isEmpty()) { - return CustomFile.fromProcessedFile(file, file.getBytes()); + return CustomFile.fromProcessedFile(file, FileUtil.getBytes(file)); } - // TODO : 파일 품질 손상 고치기 - TiffImageMetadata metadata = imageProcessor.getImageMetadata(file); - byte[] drawnImageBytes = imageProcessor.drawODResultOnImage(file, entities); - byte[] orientedImageBytes = imageProcessor.orientImage(drawnImageBytes, metadata); - - return CustomFile.fromProcessedFile(file, orientedImageBytes); - } - - public CustomFile processFRResultImage( - MultipartFile file, List faceAnnotations, String object) throws Exception { - TiffImageMetadata metadata = imageProcessor.getImageMetadata(file); - byte[] drawnImageBytes = imageProcessor.drawFRResultOnImage(file, faceAnnotations, object); - byte[] orientedImageBytes = imageProcessor.orientImage(drawnImageBytes, metadata); - - return CustomFile.fromProcessedFile(file, orientedImageBytes); + byte[] drawnImageBytes = imageDrawer.drawResultOnImage(file, entities, object); + return CustomFile.fromProcessedFile(file, drawnImageBytes); } } \ No newline at end of file diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java index 85a53680..d1fab44a 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java @@ -3,11 +3,13 @@ import com.microsoft.azure.cognitiveservices.vision.computervision.ComputerVisionClient; import com.microsoft.azure.cognitiveservices.vision.computervision.models.ImageAnalysis; import com.microsoft.azure.cognitiveservices.vision.computervision.models.VisualFeatureTypes; -import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomDetectedObject; +import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult; +import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult.ObjectDetectionResultBuilder; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.ObjectDetectedV32Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; -import java.io.IOException; +import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.TagDetectedV32Mapper; +import com.wakeUpTogetUp.togetUp.utils.ImageProcessor; import java.util.List; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; @@ -18,26 +20,41 @@ @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public class AzureVision32Service { - private final ComputerVisionClient client; - private final ObjectDetectedV32Mapper mapper; + private final int IMAGE_SIZE_LIMIT = 4; - public List detectObjects(MultipartFile file) { - List features = List.of(VisualFeatureTypes.OBJECTS); + private final ComputerVisionClient client; + private final ObjectDetectedV32Mapper objectDetectedV32Mapper; + private final TagDetectedV32Mapper tagDetectedV32Mapper; + public ObjectDetectionResultBuilder getObjectDetectionResult(MultipartFile file) { try { - ImageAnalysis analysis = client.computerVision() - .analyzeImageInStream() - .withImage(file.getBytes()) - .withVisualFeatures(features) - .execute(); - - if (analysis.objects() == null) { - throw new BaseException(Status.NO_DETECTED_OBJECT); - } - - return mapper.toCustomDetectedObjects(analysis.objects()); - } catch (IOException e) { - throw new BaseException(Status.INVALID_IMAGE); + byte[] data = ImageProcessor.compressUntil(file, IMAGE_SIZE_LIMIT); + + ImageAnalysis analysis = getAnalysisResult(data); + validateNotDetected(analysis); + + return ObjectDetectionResult.builder() + .objects(objectDetectedV32Mapper.toCustomDetectedObjects(analysis.objects())) + .tags(tagDetectedV32Mapper.toCustomDetectedTags(analysis.tags())); + } catch (Exception e) { + throw new BaseException(Status.INTERNAL_SERVER_ERROR); + } + } + + private ImageAnalysis getAnalysisResult(byte[] data) { + List features = + List.of(VisualFeatureTypes.OBJECTS, VisualFeatureTypes.TAGS); + + return client.computerVision() + .analyzeImageInStream() + .withImage(data) + .withVisualFeatures(features) + .execute(); + } + + private void validateNotDetected(ImageAnalysis analysis) { + if (analysis.objects() == null && analysis.tags() == null) { + throw new BaseException(Status.NO_DETECTED_OBJECT); } } } \ No newline at end of file diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java index 613b1d7b..80ac4c26 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java @@ -13,10 +13,12 @@ import com.azure.ai.vision.imageanalysis.ImageAnalysisResultReason; import com.azure.ai.vision.imageanalysis.ImageAnalyzer; import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult; +import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult.ObjectDetectionResultBuilder; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.ObjectDetectedV40Mapper; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.TagDetectedV40Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; +import com.wakeUpTogetUp.togetUp.utils.ImageProcessor; import java.io.IOException; import java.nio.ByteBuffer; import lombok.AccessLevel; @@ -28,44 +30,57 @@ @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public class AzureVision40Service { + private final int IMAGE_SIZE_LIMIT = 10; + private final VisionServiceOptions serviceOptions; private final ImageAnalysisOptions analysisOptions; private final ObjectDetectedV40Mapper objectDetectedV40Mapper; private final TagDetectedV40Mapper tagDetectedV40Mapper; - public ObjectDetectionResult detect(MultipartFile file) throws Exception { - VisionSource imageSource = getVisionSource(file); + public ObjectDetectionResultBuilder getObjectDetectionResult(MultipartFile file) { + byte[] data = ImageProcessor.compressUntil(file, IMAGE_SIZE_LIMIT); - try (ImageAnalyzer analyzer = new ImageAnalyzer(serviceOptions, imageSource, analysisOptions); + try (ImageAnalyzer analyzer = new ImageAnalyzer(serviceOptions, getVisionSource(data), + analysisOptions); ImageAnalysisResult result = analyzer.analyze()) { - if (result.getReason() != ImageAnalysisResultReason.ANALYZED) { - ImageAnalysisErrorDetails errorDetails = ImageAnalysisErrorDetails.fromResult(result); - printErrorDetails(errorDetails); - - throw new BaseException(Status.IMAGE_ANALYSIS_FAIL); - } - + catchNotAnalyzedError(result); printDetectionResult(result); printResultDetails(ImageAnalysisResultDetails.fromResult(result)); return ObjectDetectionResult.builder() .objects(objectDetectedV40Mapper.toCustomDetectedObjects(result.getObjects())) - .tags(tagDetectedV40Mapper.customDetectedTags(result.getTags())) - .build(); + .tags(tagDetectedV40Mapper.customDetectedTags(result.getTags())); + } catch (IOException e) { + throw new BaseException(Status.INVALID_IMAGE); + } catch (Exception e) { + throw new BaseException(Status.INTERNAL_SERVER_ERROR); } } - private VisionSource getVisionSource(MultipartFile file) throws IOException { + private VisionSource getVisionSource(byte[] data) { ImageSourceBuffer imageSourceBuffer = new ImageSourceBuffer(); try (ImageWriter imageWriter = imageSourceBuffer.getWriter()) { - imageWriter.write(ByteBuffer.wrap(file.getBytes())); + imageWriter.write(ByteBuffer.wrap(data)); } return VisionSource.fromImageSourceBuffer(imageSourceBuffer); } + private void catchNotAnalyzedError(ImageAnalysisResult result) { + if (isNotAnalyzed(result)) { + ImageAnalysisErrorDetails errorDetails = ImageAnalysisErrorDetails.fromResult(result); + printErrorDetails(errorDetails); + + throw new BaseException(Status.IMAGE_ANALYSIS_FAIL); + } + } + + private boolean isNotAnalyzed(ImageAnalysisResult result) { + return result.getReason() != ImageAnalysisResultReason.ANALYZED; + } + private void printDetectionResult(ImageAnalysisResult result) { System.out.println(" Image height = " + result.getImageHeight()); System.out.println(" Image width = " + result.getImageWidth()); From 8cc3fa2e5a9dc77e2a9a53a8577fb7de3bd82c45 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 18:17:51 +0900 Subject: [PATCH 11/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=EC=9C=A0=ED=8B=B8=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../togetUp/api/mission/service/MissionImageService.java | 2 +- .../togetUp/infra/azure/vision/AzureVision32Service.java | 2 +- .../togetUp/infra/azure/vision/AzureVision40Service.java | 2 +- .../wakeUpTogetUp/togetUp/utils/{ => image}/ImageDrawer.java | 3 ++- .../togetUp/utils/{ => image}/ImageProcessor.java | 3 ++- .../com/wakeUpTogetUp/togetUp/utils/{ => image}/ImageUtil.java | 3 ++- 6 files changed, 9 insertions(+), 6 deletions(-) rename src/main/java/com/wakeUpTogetUp/togetUp/utils/{ => image}/ImageDrawer.java (97%) rename src/main/java/com/wakeUpTogetUp/togetUp/utils/{ => image}/ImageProcessor.java (98%) rename src/main/java/com/wakeUpTogetUp/togetUp/utils/{ => image}/ImageUtil.java (95%) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java index 8a3c6241..31c4f3d5 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java @@ -2,7 +2,7 @@ import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.utils.FileUtil; -import com.wakeUpTogetUp.togetUp.utils.ImageDrawer; +import com.wakeUpTogetUp.togetUp.utils.image.ImageDrawer; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java index d1fab44a..10fb90f7 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java @@ -9,7 +9,7 @@ import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.TagDetectedV32Mapper; -import com.wakeUpTogetUp.togetUp.utils.ImageProcessor; +import com.wakeUpTogetUp.togetUp.utils.image.ImageProcessor; import java.util.List; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java index 80ac4c26..a9206cf3 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java @@ -18,7 +18,7 @@ import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.TagDetectedV40Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; -import com.wakeUpTogetUp.togetUp.utils.ImageProcessor; +import com.wakeUpTogetUp.togetUp.utils.image.ImageProcessor; import java.io.IOException; import java.nio.ByteBuffer; import lombok.AccessLevel; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageDrawer.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java similarity index 97% rename from src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageDrawer.java rename to src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java index f049d2c0..6608c9e2 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageDrawer.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.utils; +package com.wakeUpTogetUp.togetUp.utils.image; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.api.mission.model.BoundingBox; @@ -6,6 +6,7 @@ import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.ImageContentType; +import com.wakeUpTogetUp.togetUp.utils.FileUtil; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java similarity index 98% rename from src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java rename to src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java index c36dd562..ced21ea7 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageProcessor.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java @@ -1,8 +1,9 @@ -package com.wakeUpTogetUp.togetUp.utils; +package com.wakeUpTogetUp.togetUp.utils.image; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.ImageContentType; +import com.wakeUpTogetUp.togetUp.utils.FileUtil; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageUtil.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageUtil.java similarity index 95% rename from src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageUtil.java rename to src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageUtil.java index 51fe35df..11258d5f 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/ImageUtil.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageUtil.java @@ -1,9 +1,10 @@ -package com.wakeUpTogetUp.togetUp.utils; +package com.wakeUpTogetUp.togetUp.utils.image; import static org.apache.commons.imaging.Imaging.getMetadata; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; +import com.wakeUpTogetUp.togetUp.utils.FileUtil; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; From 91a98d302a92412b7ab898a30b2f2e6d0b6b110e Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 18:18:40 +0900 Subject: [PATCH 12/23] =?UTF-8?q?=20#80=20[REFACTOR]=20file=20util=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=93=A4=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../togetUp/api/mission/service/MissionImageService.java | 2 +- .../common/annotation/validator/ImageFileValidator.java | 2 +- .../com/wakeUpTogetUp/togetUp/infra/aws/s3/FileService.java | 2 +- .../com/wakeUpTogetUp/togetUp/utils/{ => file}/FileUtil.java | 3 ++- .../wakeUpTogetUp/togetUp/utils/{ => file}/FileValidator.java | 2 +- .../com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java | 2 +- .../com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java | 2 +- .../java/com/wakeUpTogetUp/togetUp/utils/image/ImageUtil.java | 2 +- 8 files changed, 9 insertions(+), 8 deletions(-) rename src/main/java/com/wakeUpTogetUp/togetUp/utils/{ => file}/FileUtil.java (93%) rename src/main/java/com/wakeUpTogetUp/togetUp/utils/{ => file}/FileValidator.java (97%) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java index 31c4f3d5..2fe8b013 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java @@ -1,7 +1,7 @@ package com.wakeUpTogetUp.togetUp.api.mission.service; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; -import com.wakeUpTogetUp.togetUp.utils.FileUtil; +import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; import com.wakeUpTogetUp.togetUp.utils.image.ImageDrawer; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; import java.util.List; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/common/annotation/validator/ImageFileValidator.java b/src/main/java/com/wakeUpTogetUp/togetUp/common/annotation/validator/ImageFileValidator.java index 24e2b9f9..22c3810b 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/common/annotation/validator/ImageFileValidator.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/common/annotation/validator/ImageFileValidator.java @@ -1,6 +1,6 @@ package com.wakeUpTogetUp.togetUp.common.annotation.validator; -import com.wakeUpTogetUp.togetUp.utils.FileValidator; +import com.wakeUpTogetUp.togetUp.utils.file.FileValidator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import org.springframework.web.multipart.MultipartFile; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/FileService.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/FileService.java index b55e0fbb..fa5fd73c 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/FileService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/FileService.java @@ -5,7 +5,7 @@ import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; -import com.wakeUpTogetUp.togetUp.utils.FileUtil; +import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/FileUtil.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/file/FileUtil.java similarity index 93% rename from src/main/java/com/wakeUpTogetUp/togetUp/utils/FileUtil.java rename to src/main/java/com/wakeUpTogetUp/togetUp/utils/file/FileUtil.java index 7d7d8367..d206576f 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/FileUtil.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/file/FileUtil.java @@ -1,7 +1,8 @@ -package com.wakeUpTogetUp.togetUp.utils; +package com.wakeUpTogetUp.togetUp.utils.file; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; +import com.wakeUpTogetUp.togetUp.utils.DateTimeProvider; import java.io.IOException; import java.util.Locale; import java.util.UUID; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/FileValidator.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/file/FileValidator.java similarity index 97% rename from src/main/java/com/wakeUpTogetUp/togetUp/utils/FileValidator.java rename to src/main/java/com/wakeUpTogetUp/togetUp/utils/file/FileValidator.java index 0629aed0..36da6121 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/FileValidator.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/file/FileValidator.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.utils; +package com.wakeUpTogetUp.togetUp.utils.file; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.ImageContentType; import com.wakeUpTogetUp.togetUp.common.Status; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java index 6608c9e2..6b0ef369 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java @@ -6,7 +6,7 @@ import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.ImageContentType; -import com.wakeUpTogetUp.togetUp.utils.FileUtil; +import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java index ced21ea7..71ff8fbd 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java @@ -3,7 +3,7 @@ import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.ImageContentType; -import com.wakeUpTogetUp.togetUp.utils.FileUtil; +import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageUtil.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageUtil.java index 11258d5f..452c9662 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageUtil.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageUtil.java @@ -4,7 +4,7 @@ import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; -import com.wakeUpTogetUp.togetUp.utils.FileUtil; +import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; From ac20a50cfeefac29777e4d346a4811bb547e53c7 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 20:25:27 +0900 Subject: [PATCH 13/23] =?UTF-8?q?=20#80=20[REFACTOR]=20MissionImageService?= =?UTF-8?q?=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wakeUpTogetUp/togetUp/api/mission/MissionController.java | 1 - .../togetUp/api/mission/{service => }/MissionImageService.java | 2 +- .../togetUp/infra/azure/vision/AzureVision40Service.java | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{service => }/MissionImageService.java (94%) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java index 7c049238..e50392ff 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java @@ -8,7 +8,6 @@ import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionWithObjectListRes; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionCompleteRes; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionPerfomRes; -import com.wakeUpTogetUp.togetUp.api.mission.service.MissionImageService; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.common.annotation.validator.ImageFile; import com.wakeUpTogetUp.togetUp.common.dto.BaseResponse; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionImageService.java similarity index 94% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionImageService.java index 2fe8b013..1498705c 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionImageService.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.api.mission.service; +package com.wakeUpTogetUp.togetUp.api.mission; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java index a9206cf3..571c80ab 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java @@ -18,6 +18,7 @@ import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.TagDetectedV40Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; +import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; import com.wakeUpTogetUp.togetUp.utils.image.ImageProcessor; import java.io.IOException; import java.nio.ByteBuffer; From 4722bf92f73b59205f2707ba5336c1c3382efbd5 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 23:34:42 +0900 Subject: [PATCH 14/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=EB=AF=B8=EC=85=98?= =?UTF-8?q?=20=EC=88=98=ED=96=89=20=EA=B2=B0=EA=B3=BC=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - VisionServiceFactory을 구현하여 동적으로 분석 서비스를 반환하는 기능 구현 --- .../togetUp/api/mission/MissionService.java | 31 ++++------------- .../api/mission/VisionServiceFactory.java | 34 +++++++++++++++++++ .../api/mission/domain/VisionService.java | 8 +++++ .../api/mission/model/MissionType.java | 27 +++++++++++++++ .../azure/vision/AzureVision32Service.java | 11 +++--- .../azure/vision/AzureVision40Service.java | 12 ++++--- .../google/vision/GoogleVisionService.java | 13 ++++--- 7 files changed, 99 insertions(+), 37 deletions(-) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/VisionServiceFactory.java create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionService.java create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionType.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java index 7732a254..be87414b 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java @@ -7,9 +7,8 @@ import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionCompleteRes; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog; -import com.wakeUpTogetUp.togetUp.infra.azure.vision.AzureVision32Service; -import com.wakeUpTogetUp.togetUp.infra.azure.vision.AzureVision40Service; -import com.wakeUpTogetUp.togetUp.infra.google.vision.GoogleVisionService; +import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; +import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionLogRepository; import com.wakeUpTogetUp.togetUp.api.notification.NotificationService; import com.wakeUpTogetUp.togetUp.api.users.UserAvatarService; import com.wakeUpTogetUp.togetUp.api.users.UserRepository; @@ -37,9 +36,7 @@ public class MissionService { private final int MAX_MATCHES_LIMIT = 3; - private final AzureVision32Service azureVision32Service; - private final AzureVision40Service azureVision40Service; - private final GoogleVisionService googleVisionService; + private final VisionServiceFactory visionServiceFactory; private final AlarmRepository alarmRepository; private final MissionLogRepository missionLogRepository; private final UserService userService; @@ -47,25 +44,11 @@ public class MissionService { private final UserRepository userRepository; private final NotificationService notificationService; - public List getDetectionResult(String object, MultipartFile missionImage) { + public List getMissionResult(MissionType type, String object, MultipartFile missionImage) { VisionAnalysisResult result = - azureVision32Service.getObjectDetectionResult(missionImage) - .target(object) - .build(); - result.print(); - - if (result.isFail()) { - throw new BaseException(Status.MISSION_FAILURE); - } - - return result.getMatches(MAX_MATCHES_LIMIT); - } - - public List getFaceRecognitionResult(String object, MultipartFile missionImage) { - VisionAnalysisResult result = - googleVisionService.getFaceRecognitionResult(missionImage) - .target(object) - .build(); + visionServiceFactory + .getVisionService(type) + .getResult(missionImage, object); result.print(); if (result.isFail()) { diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/VisionServiceFactory.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/VisionServiceFactory.java new file mode 100644 index 00000000..39cbf92e --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/VisionServiceFactory.java @@ -0,0 +1,34 @@ +package com.wakeUpTogetUp.togetUp.api.mission; + +import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionService; +import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; +import com.wakeUpTogetUp.togetUp.common.Status; +import com.wakeUpTogetUp.togetUp.exception.BaseException; +import com.wakeUpTogetUp.togetUp.infra.azure.vision.AzureVision32Service; +import com.wakeUpTogetUp.togetUp.infra.azure.vision.AzureVision40Service; +import com.wakeUpTogetUp.togetUp.infra.google.vision.GoogleVisionService; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class VisionServiceFactory { + + private final AzureVision32Service azureVision32Service; + private final AzureVision40Service azureVision40Service; + private final GoogleVisionService googleVisionService; + + public VisionService getVisionService(MissionType missionType) { + switch (missionType) { + case OBJECT_DETECTION: + return azureVision40Service; + + case EXPRESSION_RECOGNITION: + return googleVisionService; + + default: + throw new BaseException(Status.INTERNAL_SERVER_ERROR); + } + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionService.java new file mode 100644 index 00000000..cbcef550 --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionService.java @@ -0,0 +1,8 @@ +package com.wakeUpTogetUp.togetUp.api.mission.domain; + +import org.springframework.web.multipart.MultipartFile; + +public interface VisionService { + + VisionAnalysisResult getResult(MultipartFile file, String target); +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionType.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionType.java new file mode 100644 index 00000000..98bee478 --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionType.java @@ -0,0 +1,27 @@ +package com.wakeUpTogetUp.togetUp.api.mission.model; + +import com.wakeUpTogetUp.togetUp.common.Status; +import com.wakeUpTogetUp.togetUp.exception.BaseException; +import java.util.Arrays; +import lombok.Getter; + +public enum MissionType { + + DIRECT_REGISTRATION("direct-registration"), + OBJECT_DETECTION("object-detection"), + EXPRESSION_RECOGNITION("face-recognition"); + + @Getter + private final String name; + + MissionType(String name) { + this.name = name; + } + + public static MissionType getByName(String name) { + return Arrays.stream(MissionType.values()) + .filter(type -> type.getName().equals(name)) + .findAny() + .orElseThrow(() -> new BaseException(Status.MISSION_NOT_FOUND)); + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java index 10fb90f7..bc6f59aa 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java @@ -4,7 +4,8 @@ import com.microsoft.azure.cognitiveservices.vision.computervision.models.ImageAnalysis; import com.microsoft.azure.cognitiveservices.vision.computervision.models.VisualFeatureTypes; import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult; -import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult.ObjectDetectionResultBuilder; +import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionAnalysisResult; +import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionService; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.ObjectDetectedV32Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; @@ -18,7 +19,7 @@ @Service @RequiredArgsConstructor(access = AccessLevel.PRIVATE) -public class AzureVision32Service { +public class AzureVision32Service implements VisionService { private final int IMAGE_SIZE_LIMIT = 4; @@ -26,7 +27,7 @@ public class AzureVision32Service { private final ObjectDetectedV32Mapper objectDetectedV32Mapper; private final TagDetectedV32Mapper tagDetectedV32Mapper; - public ObjectDetectionResultBuilder getObjectDetectionResult(MultipartFile file) { + public VisionAnalysisResult getResult(MultipartFile file, String target) { try { byte[] data = ImageProcessor.compressUntil(file, IMAGE_SIZE_LIMIT); @@ -34,8 +35,10 @@ public ObjectDetectionResultBuilder getObjectDetectionResult(MultipartFile file) validateNotDetected(analysis); return ObjectDetectionResult.builder() + .target(target) .objects(objectDetectedV32Mapper.toCustomDetectedObjects(analysis.objects())) - .tags(tagDetectedV32Mapper.toCustomDetectedTags(analysis.tags())); + .tags(tagDetectedV32Mapper.toCustomDetectedTags(analysis.tags())) + .build(); } catch (Exception e) { throw new BaseException(Status.INTERNAL_SERVER_ERROR); } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java index 571c80ab..0c9154aa 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java @@ -13,12 +13,12 @@ import com.azure.ai.vision.imageanalysis.ImageAnalysisResultReason; import com.azure.ai.vision.imageanalysis.ImageAnalyzer; import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult; -import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult.ObjectDetectionResultBuilder; +import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionAnalysisResult; +import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionService; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.ObjectDetectedV40Mapper; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.TagDetectedV40Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; -import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; import com.wakeUpTogetUp.togetUp.utils.image.ImageProcessor; import java.io.IOException; import java.nio.ByteBuffer; @@ -29,7 +29,7 @@ @Service @RequiredArgsConstructor(access = AccessLevel.PRIVATE) -public class AzureVision40Service { +public class AzureVision40Service implements VisionService { private final int IMAGE_SIZE_LIMIT = 10; @@ -38,7 +38,7 @@ public class AzureVision40Service { private final ObjectDetectedV40Mapper objectDetectedV40Mapper; private final TagDetectedV40Mapper tagDetectedV40Mapper; - public ObjectDetectionResultBuilder getObjectDetectionResult(MultipartFile file) { + public VisionAnalysisResult getResult(MultipartFile file, String target) { byte[] data = ImageProcessor.compressUntil(file, IMAGE_SIZE_LIMIT); try (ImageAnalyzer analyzer = new ImageAnalyzer(serviceOptions, getVisionSource(data), @@ -50,8 +50,10 @@ public ObjectDetectionResultBuilder getObjectDetectionResult(MultipartFile file) printResultDetails(ImageAnalysisResultDetails.fromResult(result)); return ObjectDetectionResult.builder() + .target(target) .objects(objectDetectedV40Mapper.toCustomDetectedObjects(result.getObjects())) - .tags(tagDetectedV40Mapper.customDetectedTags(result.getTags())); + .tags(tagDetectedV40Mapper.customDetectedTags(result.getTags())) + .build(); } catch (IOException e) { throw new BaseException(Status.INVALID_IMAGE); } catch (Exception e) { diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java index e8448a67..b5e9964a 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java @@ -3,7 +3,8 @@ import com.google.cloud.vision.v1.AnnotateImageResponse; import com.google.cloud.vision.v1.Feature.Type; import com.wakeUpTogetUp.togetUp.api.mission.domain.FaceAnnotationRecognitionResult; -import com.wakeUpTogetUp.togetUp.api.mission.domain.FaceAnnotationRecognitionResult.FaceAnnotationRecognitionResultBuilder; +import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionAnalysisResult; +import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionService; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import com.wakeUpTogetUp.togetUp.infra.google.vision.mapper.GoogleVisionMapper; @@ -14,12 +15,14 @@ @Service @RequiredArgsConstructor -public class GoogleVisionService { +public class GoogleVisionService implements VisionService { + private final CloudVisionTemplate cloudVisionTemplate; private final GoogleVisionMapper googleVisionMapper; - public FaceAnnotationRecognitionResultBuilder getFaceRecognitionResult(MultipartFile file) { + @Override + public VisionAnalysisResult getResult(MultipartFile file, String target) { AnnotateImageResponse response = cloudVisionTemplate.analyzeImage(file.getResource(), Type.FACE_DETECTION); @@ -28,6 +31,8 @@ public FaceAnnotationRecognitionResultBuilder getFaceRecognitionResult(Multipart } return FaceAnnotationRecognitionResult.builder() - .faceAnnotations(googleVisionMapper.toCustomRecognizedEmotions(response.getFaceAnnotationsList())); + .target(target) + .faceAnnotations(googleVisionMapper.toCustomRecognizedEmotions(response.getFaceAnnotationsList())) + .build(); } } From 2ac1790841b00781f4d4e0a1b7a07433beffcbfa Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 23:39:49 +0900 Subject: [PATCH 15/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=EB=AF=B8=EC=85=98?= =?UTF-8?q?=20=EC=9C=A0=ED=98=95=EC=97=90=20=EB=94=B0=EB=9D=BC=20CustomFil?= =?UTF-8?q?e=20=EB=B0=98=ED=99=98=20=EB=B0=A9=EC=8B=9D=EC=9D=84=20?= =?UTF-8?q?=EB=8F=99=EC=A0=81=EC=9C=BC=EB=A1=9C=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=A0=84=EB=9E=B5=20=ED=8C=A8=ED=84=B4=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../strategy/AnalysisConversionStrategy.java | 26 +++++++++++++++++++ .../strategy/MissionImageStrategy.java | 9 +++++++ .../strategy/MissionImageStrategyFactory.java | 24 +++++++++++++++++ .../strategy/SimpleConversionStrategy.java | 16 ++++++++++++ 4 files changed, 75 insertions(+) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/AnalysisConversionStrategy.java create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/MissionImageStrategy.java create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/MissionImageStrategyFactory.java create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/SimpleConversionStrategy.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/AnalysisConversionStrategy.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/AnalysisConversionStrategy.java new file mode 100644 index 00000000..6fce88db --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/AnalysisConversionStrategy.java @@ -0,0 +1,26 @@ +package com.wakeUpTogetUp.togetUp.api.mission.strategy; + +import com.wakeUpTogetUp.togetUp.api.mission.MissionImageService; +import com.wakeUpTogetUp.togetUp.api.mission.MissionService; +import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; +import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; +import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; +import java.util.List; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +@Component +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class AnalysisConversionStrategy implements MissionImageStrategy { + + private final MissionService missionService; + private final MissionImageService missionImageService; + + @Override + public CustomFile execute(MultipartFile missionImage, MissionType type, String object) { + List detectedObjects = missionService.getMissionResult(type, object, missionImage); + return missionImageService.processResultImage(missionImage, detectedObjects, object); + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/MissionImageStrategy.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/MissionImageStrategy.java new file mode 100644 index 00000000..fcfec742 --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/MissionImageStrategy.java @@ -0,0 +1,9 @@ +package com.wakeUpTogetUp.togetUp.api.mission.strategy; + +import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; +import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; +import org.springframework.web.multipart.MultipartFile; + +public interface MissionImageStrategy { + CustomFile execute(MultipartFile missionImage, MissionType type, String object); +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/MissionImageStrategyFactory.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/MissionImageStrategyFactory.java new file mode 100644 index 00000000..45a1c95a --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/MissionImageStrategyFactory.java @@ -0,0 +1,24 @@ +package com.wakeUpTogetUp.togetUp.api.mission.strategy; + +import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class MissionImageStrategyFactory { + + private final SimpleConversionStrategy simpleConversionStrategy; + private final AnalysisConversionStrategy imageProcessingStrategy; + + public MissionImageStrategy getStrategy(MissionType missionType) { + switch (missionType) { + case DIRECT_REGISTRATION: + return simpleConversionStrategy; + + default: + return imageProcessingStrategy; + } + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/SimpleConversionStrategy.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/SimpleConversionStrategy.java new file mode 100644 index 00000000..c90bd6fe --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/SimpleConversionStrategy.java @@ -0,0 +1,16 @@ +package com.wakeUpTogetUp.togetUp.api.mission.strategy; + +import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; +import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; +import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +@Component +public class SimpleConversionStrategy implements MissionImageStrategy { + + @Override + public CustomFile execute(MultipartFile missionImage, MissionType type, String object) { + return CustomFile.fromProcessedFile(missionImage, FileUtil.getBytes(missionImage)); + } +} From 22d075047590bd2590d6743663a8f928da7d492b Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Wed, 27 Mar 2024 23:40:16 +0900 Subject: [PATCH 16/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=EB=AF=B8=EC=85=98?= =?UTF-8?q?=20=EC=88=98=ED=96=89=20API=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../togetUp/api/alarm/AlarmService.java | 2 +- .../api/mission/MissionController.java | 51 +++++-------------- .../togetUp/api/mission/MissionFacade.java | 32 ++++++++++++ .../api/mission/MissionObjectRepository.java | 1 + .../togetUp/api/mission/MissionProvider.java | 14 ++++- .../togetUp/api/mission/MissionService.java | 1 - .../dto/response/MissionPerfomRes.java | 4 -- .../api/mission/model/MissionObject.java | 4 +- .../wakeUpTogetUp/togetUp/common/Status.java | 2 +- 9 files changed, 64 insertions(+), 47 deletions(-) create mode 100644 src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionFacade.java diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/alarm/AlarmService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/alarm/AlarmService.java index 96f65cf1..f50ad4b4 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/alarm/AlarmService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/alarm/AlarmService.java @@ -47,7 +47,7 @@ public Alarm createAlarmDeprecated(Integer userId, PostAlarmReq postAlarmReq) { if (postAlarmReq.getMissionObjectId() != null) { missionObject = missionObjectRepository.findById(postAlarmReq.getMissionObjectId()) - .orElseThrow(() -> new BaseException(Status.OBJECT_NOT_FOUND)); + .orElseThrow(() -> new BaseException(Status.MISSION_OBJECT_NOT_FOUND)); if (missionObject.getMission().getId() != mission.getId()) { throw new BaseException(Status.MISSION_ID_NOT_MATCH); diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java index e50392ff..1daf8b37 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java @@ -1,8 +1,6 @@ package com.wakeUpTogetUp.togetUp.api.mission; import com.wakeUpTogetUp.togetUp.api.auth.AuthUser; -import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; -import com.wakeUpTogetUp.togetUp.infra.aws.s3.FileService; import com.wakeUpTogetUp.togetUp.api.mission.dto.request.MissionCompleteReq; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionLogRes; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionWithObjectListRes; @@ -11,10 +9,10 @@ import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.common.annotation.validator.ImageFile; import com.wakeUpTogetUp.togetUp.common.dto.BaseResponse; -import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @@ -30,6 +28,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @@ -42,10 +41,9 @@ @RequestMapping("/app/mission") public class MissionController { + private final MissionFacade missionFacade; private final MissionProvider missionProvider; private final MissionService missionService; - private final MissionImageService missionImageService; - private final FileService fileService; @Operation(summary = "미션 목록 가져오기") @GetMapping("/{missionId}") @@ -61,10 +59,8 @@ BaseResponse getObjectDetectionMissions( return new BaseResponse<>(Status.SUCCESS, missionProvider.getMission(missionId)); } - // TODO: 객체 탐지, 표정 인식 통합 - // TODO: 객체 이름이 아닌 알람 ID를 요청값으로 받게 리팩토링하기 + 그냥 리팩토링 - @Operation(summary = "객체 탐지 미션") - @PostMapping(value = "/object-detection/{object}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @Operation(summary = "미션 수행 결과 불러오기") + @PostMapping(value = "/{missionName}/result", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.CREATED) @ApiResponses(value = { @ApiResponse( @@ -77,35 +73,14 @@ BaseResponse getObjectDetectionMissions( public BaseResponse recognizeObject( @Parameter(hidden = true) @AuthUser Integer userId, @Parameter(required = true, description = "미션 수행 사진") @RequestPart @ImageFile MultipartFile missionImage, - @Parameter(required = true, description = "탐지할 객체") @PathVariable String object) { - List detectedObjects = missionService.getDetectionResult(object, missionImage); - CustomFile file = missionImageService.processResultImage(missionImage, detectedObjects, object); - String imageUrl = fileService.uploadFile(file, "mission"); - - return new BaseResponse<>(Status.MISSION_SUCCESS, new MissionPerfomRes(imageUrl)); - } - - @Operation(summary = "표정 인식 미션") - @PostMapping(value = "/face-recognition/{object}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - @ResponseStatus(HttpStatus.CREATED) - @ApiResponses(value = { - @ApiResponse( - responseCode = "201", - description = "미션을 성공하였습니다.", - content = @Content(schema = @Schema(implementation = MissionPerfomRes.class))), - @ApiResponse(responseCode = "200", description = "탐지된 객체가 없습니다."), - @ApiResponse(responseCode = "200", description = "미션을 성공하지 못했습니다."), - @ApiResponse(responseCode = "500", description = "예상치 못한 서버 에러입니다. 제보 부탁드립니다.") - }) - public BaseResponse recognizeFaceExpression( - @Parameter(hidden = true) @AuthUser Integer userId, - @Parameter(required = true, description = "미션 수행 사진") @RequestPart @ImageFile MultipartFile missionImage, - @Parameter(required = true, description = "탐지할 표정(`joy`/`sorrow`/`anger`/`surprise`)") @PathVariable String object) { - List faceAnnotations = missionService.getFaceRecognitionResult(object, missionImage); - CustomFile file = missionImageService.processResultImage(missionImage, faceAnnotations, object); - String imageUrl = fileService.uploadFile(file, "mission"); - - return new BaseResponse<>(Status.MISSION_SUCCESS, new MissionPerfomRes(imageUrl)); + @Parameter(required = true, description = "미션 이름", examples = { + @ExampleObject(value = "direct-registration"), + @ExampleObject(value = "object-detection"), + @ExampleObject(value = "expression-recognition")}) @PathVariable String missionName, + @Parameter(required = true, description = "탐지할 미션 객체") @RequestParam String object + ) { + MissionPerfomRes response = missionFacade.performMission(missionImage, missionName, object); + return new BaseResponse<>(Status.MISSION_SUCCESS, response); } @Operation(summary = "미션 완료 - 수행 기록 생성 및 경험치, 레벨 정산 및 경우에 따라 아바타 해금") diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionFacade.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionFacade.java new file mode 100644 index 00000000..be73501d --- /dev/null +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionFacade.java @@ -0,0 +1,32 @@ +package com.wakeUpTogetUp.togetUp.api.mission; + +import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionPerfomRes; +import com.wakeUpTogetUp.togetUp.api.mission.strategy.MissionImageStrategyFactory; +import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; +import com.wakeUpTogetUp.togetUp.infra.aws.s3.FileService; +import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +@Component +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) +public class MissionFacade { + + private final MissionImageStrategyFactory missionImageStrategyFactory; + private final MissionProvider missionProvider; + private final FileService fileService; + + public MissionPerfomRes performMission(MultipartFile missionImage, String missionName, String object) { + MissionType type = MissionType.getByName(missionName); + missionProvider.validateMissionObject(type, object); + + CustomFile file = missionImageStrategyFactory + .getStrategy(type) + .execute(missionImage, type, object); + String imageUrl = fileService.uploadFile(file, "mission"); + + return new MissionPerfomRes(imageUrl); + } +} diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionObjectRepository.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionObjectRepository.java index 1ec4be00..9bce1623 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionObjectRepository.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionObjectRepository.java @@ -7,4 +7,5 @@ @Repository public interface MissionObjectRepository extends JpaRepository { + boolean existsByMission_NameAndName(String missionName, String name); } \ No newline at end of file diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionProvider.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionProvider.java index 2d8b990d..6777b4b0 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionProvider.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionProvider.java @@ -4,6 +4,7 @@ import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionWithObjectListRes; import com.wakeUpTogetUp.togetUp.api.mission.model.Mission; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog; +import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import com.wakeUpTogetUp.togetUp.utils.mapper.EntityDtoMapper; @@ -14,7 +15,9 @@ @Service @RequiredArgsConstructor public class MissionProvider { + private final MissionRepository missionRepository; + private final MissionObjectRepository missionObjectRepository; private final MissionLogRepository missionLogRepository; public GetMissionWithObjectListRes getMission(int missionId) { @@ -23,7 +26,6 @@ public GetMissionWithObjectListRes getMission(int missionId) { return EntityDtoMapper.INSTANCE.toGetMissionRes(mission); } - public GetMissionLogRes getMissionLog(Integer missionCompleteLogId) { MissionLog missionLog = missionLogRepository.findById(missionCompleteLogId) .orElseThrow( @@ -37,4 +39,14 @@ public List getMissionCompleteLogsByUserId(Integer userId) { return EntityDtoMapper.INSTANCE.toMissionLogResList(missionLogList); } + + public void validateMissionObject(MissionType type, String object) { + if (isNotExistMissionObjectName(type.getName(), object)) { + throw new BaseException(Status.MISSION_NOT_FOUND); + } + } + + private boolean isNotExistMissionObjectName(String missionName, String object) { + return !missionObjectRepository.existsByMission_NameAndName(missionName, object); + } } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java index be87414b..155272a8 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java @@ -8,7 +8,6 @@ import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; -import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionLogRepository; import com.wakeUpTogetUp.togetUp.api.notification.NotificationService; import com.wakeUpTogetUp.togetUp.api.users.UserAvatarService; import com.wakeUpTogetUp.togetUp.api.users.UserRepository; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/dto/response/MissionPerfomRes.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/dto/response/MissionPerfomRes.java index d04577b3..6bf630d3 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/dto/response/MissionPerfomRes.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/dto/response/MissionPerfomRes.java @@ -2,12 +2,8 @@ import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; @Getter -@Setter -@NoArgsConstructor @AllArgsConstructor public class MissionPerfomRes { private String filePath; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionObject.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionObject.java index a31241a0..88d9ebcd 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionObject.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionObject.java @@ -21,9 +21,11 @@ public class MissionObject { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(columnDefinition = "INT UNSIGNED") private Integer id; - // todo : enum 처리하기 + private String name; + private String kr; + private String icon; @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/common/Status.java b/src/main/java/com/wakeUpTogetUp/togetUp/common/Status.java index e8409ee2..dc451e71 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/common/Status.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/common/Status.java @@ -61,7 +61,7 @@ public enum Status { ALARM_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 알람 입니다."), MISSION_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 미션 입니다."), AVATAR_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 아바타 입니다."), - OBJECT_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 미션 객체입니다."), + MISSION_OBJECT_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 미션 객체입니다."), FILE_NOT_FOUND(HttpStatus.NOT_FOUND, "파일을 찾을 수 없습니다."), ACCOUNT_DOESNT_EXISTS(HttpStatus.NOT_FOUND, "계정이 존재하지 않습니다."), ROOM_USER_NOT_FOUND(HttpStatus.NOT_FOUND, "그룹의 해당 멤버가 없습니다."), From 071ce105fe04e0abfa2e87bf30804f5f260ba18c Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Thu, 28 Mar 2024 00:50:26 +0900 Subject: [PATCH 17/23] =?UTF-8?q?=20#80=20[FIX]=20=EC=95=84=EC=A7=81=20?= =?UTF-8?q?=EC=A7=80=EC=9B=90=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=8C=8C=EC=9D=BC=20=ED=98=95?= =?UTF-8?q?=EC=8B=9D=20=EC=A3=BC=EC=84=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../togetUp/infra/aws/s3/model/ImageContentType.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/model/ImageContentType.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/model/ImageContentType.java index 33a2168a..d48d6679 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/model/ImageContentType.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/aws/s3/model/ImageContentType.java @@ -6,10 +6,10 @@ public enum ImageContentType { JPG("image/jpeg", "jpg"), - JPEG("image/jpeg", "jpeg"), - PNG("image/png", "png"), - WEBP("image/webp", "webp"), - HEIF("application/octet-stream", "heic"); + JPEG("image/jpeg", "jpeg"); +// PNG("image/png", "png"), +// WEBP("image/webp", "webp"), +// HEIF("application/octet-stream", "heic"); private final String contentType; private final String extension; From 867e9ecf857aa8b2725378c67e63d1ce008cade9 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Thu, 28 Mar 2024 00:51:25 +0900 Subject: [PATCH 18/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=ED=8F=B0=ED=8A=B8?= =?UTF-8?q?=20=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=A1=B0=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../togetUp/utils/image/ImageDrawer.java | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java index 6b0ef369..d7106c59 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageDrawer.java @@ -14,7 +14,6 @@ import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.util.List; import java.util.Random; @@ -38,7 +37,7 @@ private void setup(MultipartFile file) { this.color = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256)); int minWH = Math.min(image.getWidth(), image.getHeight()); this.thickness = minWH / 150; - this.fontSize = minWH / 20; + this.fontSize = minWH / 23; } private void setOrientedImage(MultipartFile file) { @@ -57,28 +56,6 @@ public byte[] drawResultOnImage(MultipartFile file, List e .getByContentType(file.getContentType()) .getExtension(); - - - /** - * - */ - - System.out.println("X = " + entities.get(0).getBox().getX()); - System.out.println("Y = " + entities.get(0).getBox().getY()); - - File outputFile2 = new File("src/main/resources/images/image_drawn.jpg"); - try { - ImageIO.write(image, "jpg", outputFile2); - } catch (IOException e) { - e.printStackTrace(); - throw new RuntimeException("Error saving the image file: " + e.getMessage()); - } - - /** - * - */ - - try (ByteArrayOutputStream outputImageStream = new ByteArrayOutputStream()) { ImageIO.write(image, format, outputImageStream); return outputImageStream.toByteArray(); From bb64c34a36b2b9542af33da11ca0b7f626e2d094 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Thu, 28 Mar 2024 00:52:27 +0900 Subject: [PATCH 19/23] =?UTF-8?q?=20#80=20[FIX]=20=EC=95=95=EC=B6=95=20?= =?UTF-8?q?=EB=AC=B4=ED=95=9C=20=EB=A3=A8=ED=94=84=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0:=20=EC=B6=94=ED=9B=84=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20=EC=98=88=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java index 71ff8fbd..6c0cc47f 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/utils/image/ImageProcessor.java @@ -40,9 +40,8 @@ public static byte[] compressUntil(MultipartFile file, int sizeOfMB) { // TODO: 디버그용 삭제 System.out.println("[압축]"); System.out.println("original size: " + data.length); - // TODO: 무한루프 빠지지 않게 처리하기 - // TODO: 최적의 quality 찾기 - while (data.length >= sizeLimit) { + int cnt = 1; + while (data.length >= sizeLimit && cnt++ <= 3) { data = compress(data, 0.5f, contentType); System.out.println(data.length); } From f28f4b2dfd9a96b9bd706f14080b405e21d231f5 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Thu, 28 Mar 2024 00:53:04 +0900 Subject: [PATCH 20/23] =?UTF-8?q?=20#80=20[REFACTOR]=20=EB=AF=B8=EC=85=98?= =?UTF-8?q?=20=EC=88=98=ED=96=89=20API=20=EB=AA=85=EC=84=B8=EC=84=9C=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../togetUp/api/mission/MissionController.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java index 1daf8b37..0ba3542f 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionController.java @@ -6,13 +6,14 @@ import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionWithObjectListRes; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionCompleteRes; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.MissionPerfomRes; +import com.wakeUpTogetUp.togetUp.api.mission.service.MissionProvider; +import com.wakeUpTogetUp.togetUp.api.mission.service.MissionService; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.common.annotation.validator.ImageFile; import com.wakeUpTogetUp.togetUp.common.dto.BaseResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @@ -59,7 +60,10 @@ BaseResponse getObjectDetectionMissions( return new BaseResponse<>(Status.SUCCESS, missionProvider.getMission(missionId)); } - @Operation(summary = "미션 수행 결과 불러오기") + @Operation(summary = "미션 수행 결과 불러오기", + description = "미션 이름을 기반으로 미션을 수행합니다.\n" + + "- 사용 가능 미션 이름: `direct-registration`/`object-detection`/`expression-recognition`\n" + + "- 직접 촬영 미션(direct-registration)의 경우 object 필드가 필수적이지 않습니다.") @PostMapping(value = "/{missionName}/result", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.CREATED) @ApiResponses(value = { @@ -73,11 +77,8 @@ BaseResponse getObjectDetectionMissions( public BaseResponse recognizeObject( @Parameter(hidden = true) @AuthUser Integer userId, @Parameter(required = true, description = "미션 수행 사진") @RequestPart @ImageFile MultipartFile missionImage, - @Parameter(required = true, description = "미션 이름", examples = { - @ExampleObject(value = "direct-registration"), - @ExampleObject(value = "object-detection"), - @ExampleObject(value = "expression-recognition")}) @PathVariable String missionName, - @Parameter(required = true, description = "탐지할 미션 객체") @RequestParam String object + @Parameter(description = "미션 이름") @PathVariable String missionName, + @Parameter(description = "탐지할 미션 객체") @RequestParam(required = false) String object ) { MissionPerfomRes response = missionFacade.performMission(missionImage, missionName, object); return new BaseResponse<>(Status.MISSION_SUCCESS, response); From af6624479d17813ceff79f286d27a220a40a9d7c Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Thu, 28 Mar 2024 00:54:55 +0900 Subject: [PATCH 21/23] =?UTF-8?q?=20#80=20[REFACTOR]=20mission=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20repository=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wakeUpTogetUp/togetUp/api/alarm/AlarmService.java | 4 ++-- .../{ => repository}/MissionLogRepository.java | 2 +- .../{ => repository}/MissionObjectRepository.java | 2 +- .../mission/{ => repository}/MissionRepository.java | 2 +- .../api/mission/{ => service}/MissionProvider.java | 9 ++++++++- .../api/mission/{ => service}/MissionService.java | 11 ++++++----- .../togetUp/api/room/RoomController.java | 2 +- .../wakeUpTogetUp/togetUp/api/room/RoomService.java | 3 +-- 8 files changed, 21 insertions(+), 14 deletions(-) rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{ => repository}/MissionLogRepository.java (92%) rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{ => repository}/MissionObjectRepository.java (86%) rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{ => repository}/MissionRepository.java (91%) rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{ => service}/MissionProvider.java (84%) rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{ => service}/MissionService.java (93%) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/alarm/AlarmService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/alarm/AlarmService.java index f50ad4b4..08ddf545 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/alarm/AlarmService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/alarm/AlarmService.java @@ -5,8 +5,8 @@ import com.wakeUpTogetUp.togetUp.api.alarm.dto.response.AlarmSimpleRes; import com.wakeUpTogetUp.togetUp.api.alarm.dto.response.AlarmTimeLineRes; import com.wakeUpTogetUp.togetUp.api.alarm.model.Alarm; -import com.wakeUpTogetUp.togetUp.api.mission.MissionObjectRepository; -import com.wakeUpTogetUp.togetUp.api.mission.MissionRepository; +import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionObjectRepository; +import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionRepository; import com.wakeUpTogetUp.togetUp.api.mission.model.Mission; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionObject; import com.wakeUpTogetUp.togetUp.api.users.UserRepository; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionLogRepository.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/repository/MissionLogRepository.java similarity index 92% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionLogRepository.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/repository/MissionLogRepository.java index 41fa820d..7d5c86ec 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionLogRepository.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/repository/MissionLogRepository.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.api.mission; +package com.wakeUpTogetUp.togetUp.api.mission.repository; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionObjectRepository.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/repository/MissionObjectRepository.java similarity index 86% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionObjectRepository.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/repository/MissionObjectRepository.java index 9bce1623..5fedc5e6 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionObjectRepository.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/repository/MissionObjectRepository.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.api.mission; +package com.wakeUpTogetUp.togetUp.api.mission.repository; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionObject; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionRepository.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/repository/MissionRepository.java similarity index 91% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionRepository.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/repository/MissionRepository.java index c9b80e61..23605d0f 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionRepository.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/repository/MissionRepository.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.api.mission; +package com.wakeUpTogetUp.togetUp.api.mission.repository; import com.wakeUpTogetUp.togetUp.api.mission.model.Mission; import java.util.List; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionProvider.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionProvider.java similarity index 84% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionProvider.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionProvider.java index 6777b4b0..3ecfaf91 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionProvider.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionProvider.java @@ -1,10 +1,13 @@ -package com.wakeUpTogetUp.togetUp.api.mission; +package com.wakeUpTogetUp.togetUp.api.mission.service; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionLogRes; import com.wakeUpTogetUp.togetUp.api.mission.dto.response.GetMissionWithObjectListRes; import com.wakeUpTogetUp.togetUp.api.mission.model.Mission; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; +import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionLogRepository; +import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionObjectRepository; +import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionRepository; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import com.wakeUpTogetUp.togetUp.utils.mapper.EntityDtoMapper; @@ -41,6 +44,10 @@ public List getMissionCompleteLogsByUserId(Integer userId) { } public void validateMissionObject(MissionType type, String object) { + if (object == null) { + throw new BaseException(Status.BAD_REQUEST_PARAM); + } + if (isNotExistMissionObjectName(type.getName(), object)) { throw new BaseException(Status.MISSION_NOT_FOUND); } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionService.java similarity index 93% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionService.java index 155272a8..caf283ef 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionService.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.api.mission; +package com.wakeUpTogetUp.togetUp.api.mission.service; import com.wakeUpTogetUp.togetUp.api.alarm.AlarmRepository; import com.wakeUpTogetUp.togetUp.api.alarm.model.Alarm; @@ -8,6 +8,7 @@ import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; +import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionLogRepository; import com.wakeUpTogetUp.togetUp.api.notification.NotificationService; import com.wakeUpTogetUp.togetUp.api.users.UserAvatarService; import com.wakeUpTogetUp.togetUp.api.users.UserRepository; @@ -44,10 +45,10 @@ public class MissionService { private final NotificationService notificationService; public List getMissionResult(MissionType type, String object, MultipartFile missionImage) { - VisionAnalysisResult result = - visionServiceFactory - .getVisionService(type) - .getResult(missionImage, object); + VisionAnalysisResult result = visionServiceFactory + .getVisionService(type) + .getResult(missionImage, object); + result.print(); if (result.isFail()) { diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/room/RoomController.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/room/RoomController.java index fd29d61b..968c4609 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/room/RoomController.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/room/RoomController.java @@ -2,7 +2,7 @@ import com.wakeUpTogetUp.togetUp.api.alarm.dto.request.AlarmCreateReq; import com.wakeUpTogetUp.togetUp.api.auth.AuthUser; -import com.wakeUpTogetUp.togetUp.api.mission.MissionLogRepository; +import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionLogRepository; import com.wakeUpTogetUp.togetUp.api.room.dto.request.RoomReq; import com.wakeUpTogetUp.togetUp.api.room.dto.response.RoomDetailRes; import com.wakeUpTogetUp.togetUp.api.room.dto.response.RoomInfoRes; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/room/RoomService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/room/RoomService.java index 6a611ba1..13640151 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/room/RoomService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/room/RoomService.java @@ -5,7 +5,7 @@ import com.wakeUpTogetUp.togetUp.api.alarm.dto.request.AlarmCreateReq; import com.wakeUpTogetUp.togetUp.api.alarm.dto.request.PostAlarmReq; import com.wakeUpTogetUp.togetUp.api.alarm.model.Alarm; -import com.wakeUpTogetUp.togetUp.api.mission.MissionLogRepository; +import com.wakeUpTogetUp.togetUp.api.mission.repository.MissionLogRepository; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionLog; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionObject; import com.wakeUpTogetUp.togetUp.api.room.dto.request.RoomReq; @@ -31,7 +31,6 @@ import java.time.LocalTime; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; From 2448356ebddc1e836e1b4b2f2a20404201a6243c Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Thu, 28 Mar 2024 00:58:23 +0900 Subject: [PATCH 22/23] =?UTF-8?q?=20#80=20[FIX]=20=EC=A7=81=EC=A0=91=20?= =?UTF-8?q?=EC=B4=AC=EC=98=81=EC=9D=98=20=EA=B2=BD=EC=9A=B0=20object=20val?= =?UTF-8?q?idation=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wakeUpTogetUp/togetUp/api/mission/MissionFacade.java | 2 -- .../api/mission/{ => service}/MissionImageService.java | 2 +- .../api/mission/{domain => service}/VisionService.java | 3 ++- .../api/mission/{ => service}/VisionServiceFactory.java | 3 +-- .../api/mission/strategy/AnalysisConversionStrategy.java | 8 ++++++-- .../togetUp/infra/azure/vision/AzureVision32Service.java | 2 +- .../togetUp/infra/azure/vision/AzureVision40Service.java | 2 +- .../togetUp/infra/google/vision/GoogleVisionService.java | 2 +- 8 files changed, 13 insertions(+), 11 deletions(-) rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{ => service}/MissionImageService.java (94%) rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{domain => service}/VisionService.java (56%) rename src/main/java/com/wakeUpTogetUp/togetUp/api/mission/{ => service}/VisionServiceFactory.java (91%) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionFacade.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionFacade.java index be73501d..12e973fa 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionFacade.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionFacade.java @@ -15,12 +15,10 @@ public class MissionFacade { private final MissionImageStrategyFactory missionImageStrategyFactory; - private final MissionProvider missionProvider; private final FileService fileService; public MissionPerfomRes performMission(MultipartFile missionImage, String missionName, String object) { MissionType type = MissionType.getByName(missionName); - missionProvider.validateMissionObject(type, object); CustomFile file = missionImageStrategyFactory .getStrategy(type) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionImageService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java similarity index 94% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionImageService.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java index 1498705c..2fe8b013 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/MissionImageService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/MissionImageService.java @@ -1,4 +1,4 @@ -package com.wakeUpTogetUp.togetUp.api.mission; +package com.wakeUpTogetUp.togetUp.api.mission.service; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.utils.file.FileUtil; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/VisionService.java similarity index 56% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionService.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/VisionService.java index cbcef550..f46c6fb8 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/domain/VisionService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/VisionService.java @@ -1,5 +1,6 @@ -package com.wakeUpTogetUp.togetUp.api.mission.domain; +package com.wakeUpTogetUp.togetUp.api.mission.service; +import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionAnalysisResult; import org.springframework.web.multipart.MultipartFile; public interface VisionService { diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/VisionServiceFactory.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/VisionServiceFactory.java similarity index 91% rename from src/main/java/com/wakeUpTogetUp/togetUp/api/mission/VisionServiceFactory.java rename to src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/VisionServiceFactory.java index 39cbf92e..6fa77f93 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/VisionServiceFactory.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/service/VisionServiceFactory.java @@ -1,6 +1,5 @@ -package com.wakeUpTogetUp.togetUp.api.mission; +package com.wakeUpTogetUp.togetUp.api.mission.service; -import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionService; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/AnalysisConversionStrategy.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/AnalysisConversionStrategy.java index 6fce88db..434f7c50 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/AnalysisConversionStrategy.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/strategy/AnalysisConversionStrategy.java @@ -1,7 +1,8 @@ package com.wakeUpTogetUp.togetUp.api.mission.strategy; -import com.wakeUpTogetUp.togetUp.api.mission.MissionImageService; -import com.wakeUpTogetUp.togetUp.api.mission.MissionService; +import com.wakeUpTogetUp.togetUp.api.mission.service.MissionImageService; +import com.wakeUpTogetUp.togetUp.api.mission.service.MissionProvider; +import com.wakeUpTogetUp.togetUp.api.mission.service.MissionService; import com.wakeUpTogetUp.togetUp.api.mission.domain.CustomAnalysisEntity; import com.wakeUpTogetUp.togetUp.api.mission.model.MissionType; import com.wakeUpTogetUp.togetUp.infra.aws.s3.model.CustomFile; @@ -17,9 +18,12 @@ public class AnalysisConversionStrategy implements MissionImageStrategy { private final MissionService missionService; private final MissionImageService missionImageService; + private final MissionProvider missionProvider; @Override public CustomFile execute(MultipartFile missionImage, MissionType type, String object) { + missionProvider.validateMissionObject(type, object); + List detectedObjects = missionService.getMissionResult(type, object, missionImage); return missionImageService.processResultImage(missionImage, detectedObjects, object); } diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java index bc6f59aa..97d171c1 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision32Service.java @@ -5,7 +5,7 @@ import com.microsoft.azure.cognitiveservices.vision.computervision.models.VisualFeatureTypes; import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult; import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionAnalysisResult; -import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionService; +import com.wakeUpTogetUp.togetUp.api.mission.service.VisionService; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.ObjectDetectedV32Mapper; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java index 0c9154aa..c51e0690 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/azure/vision/AzureVision40Service.java @@ -14,7 +14,7 @@ import com.azure.ai.vision.imageanalysis.ImageAnalyzer; import com.wakeUpTogetUp.togetUp.api.mission.domain.ObjectDetectionResult; import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionAnalysisResult; -import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionService; +import com.wakeUpTogetUp.togetUp.api.mission.service.VisionService; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.ObjectDetectedV40Mapper; import com.wakeUpTogetUp.togetUp.infra.azure.vision.mapper.TagDetectedV40Mapper; import com.wakeUpTogetUp.togetUp.common.Status; diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java b/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java index b5e9964a..0291266c 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/infra/google/vision/GoogleVisionService.java @@ -4,7 +4,7 @@ import com.google.cloud.vision.v1.Feature.Type; import com.wakeUpTogetUp.togetUp.api.mission.domain.FaceAnnotationRecognitionResult; import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionAnalysisResult; -import com.wakeUpTogetUp.togetUp.api.mission.domain.VisionService; +import com.wakeUpTogetUp.togetUp.api.mission.service.VisionService; import com.wakeUpTogetUp.togetUp.common.Status; import com.wakeUpTogetUp.togetUp.exception.BaseException; import com.wakeUpTogetUp.togetUp.infra.google.vision.mapper.GoogleVisionMapper; From 7ab6d3dd6e5898c03dcdc7663ddab1bc6cc203bb Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Thu, 28 Mar 2024 00:58:51 +0900 Subject: [PATCH 23/23] =?UTF-8?q?=20#80=20[FIX]=20MissionType=20name=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wakeUpTogetUp/togetUp/api/mission/model/MissionType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionType.java b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionType.java index 98bee478..d17c92d6 100644 --- a/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionType.java +++ b/src/main/java/com/wakeUpTogetUp/togetUp/api/mission/model/MissionType.java @@ -9,7 +9,7 @@ public enum MissionType { DIRECT_REGISTRATION("direct-registration"), OBJECT_DETECTION("object-detection"), - EXPRESSION_RECOGNITION("face-recognition"); + EXPRESSION_RECOGNITION("expression-recognition"); @Getter private final String name;