Browse Source

feat:图像分析

master
白凤吉 1 week ago
parent
commit
cbe63190cb
  1. 37
      src/main/java/com/iflytop/colortitration/app/common/utils/ImageAnalysisUtil.java

37
src/main/java/com/iflytop/colortitration/app/service/ImageAnalysisService.java → src/main/java/com/iflytop/colortitration/app/common/utils/ImageAnalysisUtil.java

@ -1,8 +1,4 @@
package com.iflytop.colortitration.app.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
package com.iflytop.colortitration.app.common.utils;
import javax.imageio.ImageIO;
import java.awt.*;
@ -13,22 +9,17 @@ import java.io.File;
import java.io.IOException;
/**
* 图像分析
* 工具类图像分析可扩展多种图像处理与分析方法方法均为静态调用
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class ImageAnalysisService {
public class ImageAnalysisUtil {
/**
* RGB 空间最大距离
*/
private static final double MAX_DISTANCE = Math.sqrt(3 * 255 * 255);
/**
* 泡沫过滤亮度与均值偏差倍数
*/
private static final double BUBBLE_STD_MULTIPLIER = 1.5;
/**
* 默认高斯平滑内核3x3
*/
@ -38,6 +29,10 @@ public class ImageAnalysisService {
1 / 16f, 2 / 16f, 1 / 16f
};
// 私有构造避免实例化
private ImageAnalysisUtil() {
}
/**
* 使用百分比容差0100%比较图像文件指定区域的平均颜色与目标颜色是否在容差范围内
*
@ -48,7 +43,7 @@ public class ImageAnalysisService {
* @return 如果区域平均颜色与目标颜色距离 <= 百分比转换后的绝对距离则返回 true否则返回 false
* @throws IOException 如果读取图像文件失败
*/
public boolean isRegionColorWithinTolerance(File imageFile, Color targetColor, double tolerancePercent, Rectangle region) throws IOException {
public static boolean isRegionColorWithinTolerance(File imageFile, Color targetColor, double tolerancePercent, Rectangle region) throws IOException {
BufferedImage image = loadImage(imageFile);
Rectangle validRegion = getValidRegion(image, region);
@ -83,7 +78,7 @@ public class ImageAnalysisService {
* @return 如果区域平均颜色与目标颜色距离 <= 百分比转换后的绝对距离则返回 true否则返回 false
* @throws IOException 如果读取图像文件失败
*/
public boolean analyzeRegionColorMatch(File imageFile, Color targetColor, double tolerancePercent, Rectangle region) throws IOException {
public static boolean analyzeRegionColorMatch(File imageFile, Color targetColor, double tolerancePercent, Rectangle region) throws IOException {
BufferedImage image = loadImage(imageFile);
BufferedImage smoothed = smoothImage(image);
Rectangle validRegion = getValidRegion(smoothed, region);
@ -143,7 +138,7 @@ public class ImageAnalysisService {
* @return 如果检测到符合特征的区域返回 true否则返回 false
* @throws IOException 读取图像失败
*/
public boolean isTestTubePresent(File backgroundFile, File currentFile, Rectangle region, double diffThresholdPercent, int minArea, double minAspectRatio) throws IOException {
public static boolean isTestTubePresent(File backgroundFile, File currentFile, Rectangle region, double diffThresholdPercent, int minArea, double minAspectRatio) throws IOException {
BufferedImage bg = smoothImage(loadImage(backgroundFile));
BufferedImage curr = smoothImage(loadImage(currentFile));
@ -187,7 +182,7 @@ public class ImageAnalysisService {
return aspect >= minAspectRatio;
}
// --------------- 私有 ---------------
// --------------- 私有辅助方法 ---------------
/**
* 读取图像文件并返回 BufferedImage 对象
@ -196,7 +191,7 @@ public class ImageAnalysisService {
* @return BufferedImage 图像对象
* @throws IOException 如果读取失败抛出异常
*/
private BufferedImage loadImage(File imageFile) throws IOException {
private static BufferedImage loadImage(File imageFile) throws IOException {
BufferedImage img = ImageIO.read(imageFile);
if (img == null) {
throw new IOException("无法从文件读取图像: " + imageFile);
@ -212,7 +207,7 @@ public class ImageAnalysisService {
* @return Rectangle 有效区域
* @throws IllegalArgumentException 如果区域超出图像范围
*/
private Rectangle getValidRegion(BufferedImage image, Rectangle region) {
private static Rectangle getValidRegion(BufferedImage image, Rectangle region) {
Rectangle bounds = new Rectangle(0, 0, image.getWidth(), image.getHeight());
Rectangle valid = bounds.intersection(region);
if (valid.isEmpty()) {
@ -227,7 +222,7 @@ public class ImageAnalysisService {
* @param src 源图像
* @return BufferedImage 平滑后的图像
*/
private BufferedImage smoothImage(BufferedImage src) {
private static BufferedImage smoothImage(BufferedImage src) {
Kernel kernel = new Kernel(3, 3, GAUSS_KERNEL);
return new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null).filter(src, null);
}
@ -239,7 +234,7 @@ public class ImageAnalysisService {
* @param c2 颜色二
* @return double 欧氏距离
*/
private double computeDistance(Color c1, Color c2) {
private static double computeDistance(Color c1, Color c2) {
return Math.sqrt(
Math.pow(c1.getRed() - c2.getRed(), 2) +
Math.pow(c1.getGreen() - c2.getGreen(), 2) +
@ -254,7 +249,7 @@ public class ImageAnalysisService {
* @return double 绝对距离阈值
* @throws IllegalArgumentException 如果百分比不在 0100 范围内
*/
private double convertTolerance(double percent) {
private static double convertTolerance(double percent) {
if (percent < 0 || percent > 100) {
throw new IllegalArgumentException("tolerancePercent 范围应在 0–100 之间");
}
Loading…
Cancel
Save