diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/controller/BlurDetectionController.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/controller/BlurDetectionController.java new file mode 100644 index 0000000..ec0f9b3 --- /dev/null +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/controller/BlurDetectionController.java @@ -0,0 +1,68 @@ +package com.sz.admin.monitor.controller; + +import com.mybatisflex.core.query.QueryWrapper; +import com.sz.admin.monitor.pojo.dto.blurDetection.BlurDetectionDTO; +import com.sz.admin.monitor.pojo.dto.blurDetection.BlurDetectionUpdateDTO; +import com.sz.admin.monitor.pojo.po.BlurDetection; +import com.sz.admin.monitor.pojo.vo.blurDetection.BlurDetectionVO; +import com.sz.admin.monitor.service.BlurDetectionService; +import com.sz.core.common.entity.ApiResult; +import com.sz.core.util.BeanCopyUtils; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * ClassName: BlurDetectionController + * Package: com.sz.admin.monitor.controller + * Description: + */ +@Tag(name = "模糊检测") +@RestController +@RequestMapping("blur-detection") +@RequiredArgsConstructor +public class BlurDetectionController { + private final BlurDetectionService blurDetectionService; + + /** + * 新增模糊检测配置 + */ + @Operation(summary = "新增模糊检测配置") + @PostMapping("/add") + public ApiResult add(@RequestBody BlurDetectionDTO blurDetectionDTO) { + BlurDetection detection = BeanCopyUtils.copy(blurDetectionDTO, BlurDetection.class); + return ApiResult.success(blurDetectionService.save(detection)); + } + + /** + * 更新配置信息 + */ + @Operation(summary = "更新配置信息") + @PutMapping("/update") + public ApiResult update(@RequestBody BlurDetectionUpdateDTO blurDetectionUpdateDTO) { + return ApiResult.success(blurDetectionService.updateById(BeanCopyUtils.copy(blurDetectionUpdateDTO, BlurDetection.class))); + } + + @Operation(summary = "新增或者更新配置信息") + @PostMapping("/addOrUpdate") + public ApiResult addOrUpdate(@RequestBody BlurDetectionDTO blurDetectionDTO) { + return ApiResult.success(blurDetectionService.saveOrUpdateBlur(blurDetectionDTO)); + } + + @GetMapping("/get") + @Operation(summary = "根据摄像头id查询模糊配置") + public ApiResult getById(@RequestParam Long id) { + QueryWrapper wrapper = blurDetectionService.query().eq(BlurDetection::getCameraId, id); + BlurDetection blurDetection = blurDetectionService.getOne(wrapper); + if (blurDetection == null) { + return ApiResult.success(null); + } + return ApiResult.success(BeanCopyUtils.copy(blurDetection, BlurDetectionVO.class)); + } + + +} diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/mapper/BlurDetectionMapper.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/mapper/BlurDetectionMapper.java new file mode 100644 index 0000000..9bb8c49 --- /dev/null +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/mapper/BlurDetectionMapper.java @@ -0,0 +1,12 @@ +package com.sz.admin.monitor.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.sz.admin.monitor.pojo.po.BlurDetection; + +/** + * ClassName: BlurDetectionMapper + * Package: com.sz.admin.monitor.mapper + * Description: + */ +public interface BlurDetectionMapper extends BaseMapper { +} diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/dto/blurDetection/BlurDetectionDTO.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/dto/blurDetection/BlurDetectionDTO.java new file mode 100644 index 0000000..09c6cfd --- /dev/null +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/dto/blurDetection/BlurDetectionDTO.java @@ -0,0 +1,13 @@ +package com.sz.admin.monitor.pojo.dto.blurDetection; + +import com.sz.admin.monitor.pojo.po.BlurDetection; +import lombok.Data; + +/** + * ClassName: BlurDetectionDTO + * Package: com.sz.admin.monitor.pojo.dto.blurDetection + * Description: + */ +@Data +public class BlurDetectionDTO extends BlurDetection { +} diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/dto/blurDetection/BlurDetectionUpdateDTO.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/dto/blurDetection/BlurDetectionUpdateDTO.java new file mode 100644 index 0000000..ae38819 --- /dev/null +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/dto/blurDetection/BlurDetectionUpdateDTO.java @@ -0,0 +1,36 @@ +package com.sz.admin.monitor.pojo.dto.blurDetection; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.time.LocalDateTime; + +/** + * ClassName: BlurDetectionUpdateDTO + * Package: com.sz.admin.monitor.pojo.dto.blurDetection + * Description: + */ +@Data +@Schema(description = "BlurDetection更新DTO") +public class BlurDetectionUpdateDTO { + + /** + * 主键 + */ + private Long id; + + /** + * 开关:0-关闭 1-开启 + */ + private Integer enable; + + /** + * 上报的url + */ + private String url; + + +} diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/po/BlurDetection.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/po/BlurDetection.java new file mode 100644 index 0000000..47d02b9 --- /dev/null +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/po/BlurDetection.java @@ -0,0 +1,61 @@ +package com.sz.admin.monitor.pojo.po; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import com.sz.mysql.EntityChangeListener; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * ClassName: BlurDetection + * Package: com.sz.admin.monitor.pojo.po + * Description: 模糊检测表 + */ +@Data +@Table(value = "ry_blur_detection", onInsert = EntityChangeListener.class, onUpdate = EntityChangeListener.class) +@Schema(description = "模糊检测表") +public class BlurDetection implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @Id(keyType = KeyType.Auto) + private Long id; + + /** + * 摄像头id + */ + private Long cameraId; + + /** + * 摄像头名称 + */ + private String cameraName; + + /** + * 开关:0-关闭 1-开启 + */ + private Integer enable; + + /** + * 上报的url + */ + private String url; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/po/CameraSnapshot.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/po/CameraSnapshot.java index e73d124..1f5314c 100644 --- a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/po/CameraSnapshot.java +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/po/CameraSnapshot.java @@ -39,7 +39,7 @@ public class CameraSnapshot implements Serializable { @Schema(description = "图片保存路径") private String imagePath; - @Schema(description = "1-定时巡检, 2-守望归位检测, 3-手动抓拍") + @Schema(description = "1-定时巡检, 2-守望归位检测, 3-手动抓拍,4-模糊检测") private Integer checkType; @Schema(description = "0-正常, 1-移位") diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/vo/blurDetection/BlurDetectionVO.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/vo/blurDetection/BlurDetectionVO.java new file mode 100644 index 0000000..6ff2045 --- /dev/null +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/vo/blurDetection/BlurDetectionVO.java @@ -0,0 +1,54 @@ +package com.sz.admin.monitor.pojo.vo.blurDetection; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.time.LocalDateTime; + +/** + * ClassName: BlurDetectionVO + * Package: com.sz.admin.monitor.pojo.vo.blurDetection + * Description: + */ +@Data +@Schema(description = "BlurDetection返回vo") +public class BlurDetectionVO { + + /** + * 主键 + */ + private Long id; + + /** + * 摄像头id + */ + private Long cameraId; + + /** + * 摄像头名称 + */ + private String cameraName; + + /** + * 开关:0-关闭 1-开启 + */ + private Integer enable; + + /** + * 上报的url + */ + private String url; + + /** + * 创建时间 + */ + private LocalDateTime createTime; + + /** + * 更新时间 + */ + private LocalDateTime updateTime; +} diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/vo/camerasnapshot/CameraSnapshotVO.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/vo/camerasnapshot/CameraSnapshotVO.java index 833ebd9..3cda6ae 100644 --- a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/vo/camerasnapshot/CameraSnapshotVO.java +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/pojo/vo/camerasnapshot/CameraSnapshotVO.java @@ -32,7 +32,7 @@ public class CameraSnapshotVO { @Schema(description = "图片保存路径") private String imagePath; - @Schema(description = "1-定时巡检, 2-守望归位检测, 3-手动抓拍") + @Schema(description = "1-定时巡检, 2-守望归位检测, 3-手动抓拍,4-模糊检测") private Integer checkType; @Schema(description = "0-正常, 1-移位") diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/sdk/ManageNVR.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/sdk/ManageNVR.java index dbb7f2c..1458be0 100644 --- a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/sdk/ManageNVR.java +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/sdk/ManageNVR.java @@ -62,30 +62,29 @@ public class ManageNVR { */ @Bean public Object nvrInit() { - return null; // //海康sdk注册 -// HCNetSDK hcNetSDK = hkNVR.registerPlugin(); -// Nvr nvr = new Nvr(); -// nvr.setDriver(0); -// // 从数据库中查询出所有的nvr -// List devicesList = nvrService.list(QueryWrapper.create(nvr)); -// if (null == devicesList) { -// return hcNetSDK; -// } -// // 遍历每个nvr,进行一个注册 -// for (Nvr n : devicesList) { -// int lUserId = hkNVR.loginVcr(n.getIp(), n.getPort().toString(), n.getAccount(), n.getPassword()); -// if (lUserId == -1) { -// // 如果注册失败,将状态设置为离线 -// nvrService.upStatusById(n.getId(), 0); -// } else { -// //将vcr的唯一Id和登录回调句柄luserid存储 -// log.info("NVR登录成功,ID:{}", lUserId); -// vcrlUserIdContainer.addData(n.getId().intValue(), lUserId); -// nvrService.upStatusById(n.getId(), 1); -// } -// } -// return hcNetSDK; + HCNetSDK hcNetSDK = hkNVR.registerPlugin(); + Nvr nvr = new Nvr(); + nvr.setDriver(0); + // 从数据库中查询出所有的nvr + List devicesList = nvrService.list(QueryWrapper.create(nvr)); + if (null == devicesList) { + return hcNetSDK; + } + // 遍历每个nvr,进行一个注册 + for (Nvr n : devicesList) { + int lUserId = hkNVR.loginVcr(n.getIp(), n.getPort().toString(), n.getAccount(), n.getPassword()); + if (lUserId == -1) { + // 如果注册失败,将状态设置为离线 + nvrService.upStatusById(n.getId(), 0); + } else { + //将vcr的唯一Id和登录回调句柄luserid存储 + log.info("NVR登录成功,ID:{}", lUserId); + vcrlUserIdContainer.addData(n.getId().intValue(), lUserId); + nvrService.upStatusById(n.getId(), 1); + } + } + return hcNetSDK; } // @Bean diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/BlurDetectionService.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/BlurDetectionService.java new file mode 100644 index 0000000..e8eba63 --- /dev/null +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/BlurDetectionService.java @@ -0,0 +1,14 @@ +package com.sz.admin.monitor.service; + +import com.mybatisflex.core.service.IService; +import com.sz.admin.monitor.pojo.dto.blurDetection.BlurDetectionDTO; +import com.sz.admin.monitor.pojo.po.BlurDetection; + +/** + * ClassName: BlurDetectionService + * Package: com.sz.admin.monitor.service + * Description: + */ +public interface BlurDetectionService extends IService { + Boolean saveOrUpdateBlur(BlurDetectionDTO blurDetectionDTO); +} diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/CameraSnapshotService.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/CameraSnapshotService.java index 8a5bd87..27e6f7e 100644 --- a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/CameraSnapshotService.java +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/CameraSnapshotService.java @@ -25,4 +25,5 @@ public interface CameraSnapshotService extends IService { // 根据摄像头ID查询快照列表 List getExistSnapshotList(Long id); + void deleteByCameraIdAndType(Long cameraId, int i); } diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/impl/BlurDetectionServiceImpl.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/impl/BlurDetectionServiceImpl.java new file mode 100644 index 0000000..41f4d9f --- /dev/null +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/impl/BlurDetectionServiceImpl.java @@ -0,0 +1,61 @@ +package com.sz.admin.monitor.service.impl; + +import cn.hutool.core.util.ObjUtil; +import com.mybatisflex.core.update.UpdateChain; +import com.mybatisflex.spring.service.impl.ServiceImpl; +import com.sz.admin.monitor.mapper.BlurDetectionMapper; +import com.sz.admin.monitor.mapper.CameraSnapshotMapper; +import com.sz.admin.monitor.pojo.dto.blurDetection.BlurDetectionDTO; +import com.sz.admin.monitor.pojo.po.BlurDetection; +import com.sz.admin.monitor.service.BlurDetectionService; +import com.sz.admin.monitor.service.CameraSnapshotService; +import com.sz.core.util.BeanCopyUtils; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; + +/** + * ClassName: BlurDetectionServiceImpl + * Package: com.sz.admin.monitor.service.impl + * Description: + */ +@Service +public class BlurDetectionServiceImpl extends ServiceImpl implements BlurDetectionService { + @Resource + private BlurDetectionMapper blurDetectionMapper; + @Resource + private CameraSnapshotService cameraSnapshotService; + @Override + @Transactional + public Boolean saveOrUpdateBlur(BlurDetectionDTO blurDetectionDTO) { + Long id = blurDetectionDTO.getId(); + Long cameraId = blurDetectionDTO.getCameraId(); + Integer enable = blurDetectionDTO.getEnable(); + if(ObjUtil.isNotNull(id)) + { + // 修改 + if(enable==0) + { + // 关闭,直接将enable状态修改成0 + boolean update = UpdateChain.of(BlurDetection.class) + .set(BlurDetection::getEnable, 0) + .where(BlurDetection::getId) + .eq(id) + .update(); + }else { + // 删除之前的基准图。抓拍一张最新的基准图保存到数据库 + cameraSnapshotService.deleteByCameraIdAndType(cameraId,4); + cameraSnapshotService.captureAndSave(cameraId, 4); + // 保存数据库 + blurDetectionMapper.update(BeanCopyUtils.copy(blurDetectionDTO, BlurDetection.class)); + } + }else { + // 新增 + cameraSnapshotService.captureAndSave(cameraId, 4); + blurDetectionMapper.insert(BeanCopyUtils.copy(blurDetectionDTO, BlurDetection.class)); + } + return true; + } +} diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/impl/CameraSnapshotServiceImpl.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/impl/CameraSnapshotServiceImpl.java index 905a020..5b81fc7 100644 --- a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/impl/CameraSnapshotServiceImpl.java +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/service/impl/CameraSnapshotServiceImpl.java @@ -43,7 +43,6 @@ public class CameraSnapshotServiceImpl extends ServiceImpl impl // 进行拉流代理 JSONObject jsonObject =zlMediaKitUtils.addStreamProxy(String.valueOf(id), mainRtsp); // JSONObject jsonObject = zlMediaKitUtils.addStreamProxy("test", "rtsp://132.239.12.145:554/axis-media/media.amp"); + log.info("进行拉流代理的结果:{}", jsonObject.toString()); + if ("-1".equals(jsonObject.get("code").toString())) { + throw new BusinessException(AdminResponseEnum.DEVICE_ADD_PROXY_FAIL, null, "服务失败"); + } if ("0".equals(jsonObject.get("code").toString())) { //拉流代理成功 return zlMediaKitUtils.getPlayUrl(String.valueOf(id)); diff --git a/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/utils/BlurDetectorV2.java b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/utils/BlurDetectorV2.java new file mode 100644 index 0000000..a0de618 --- /dev/null +++ b/sz-service/sz-service-admin/src/main/java/com/sz/admin/monitor/utils/BlurDetectorV2.java @@ -0,0 +1,322 @@ +package com.sz.admin.monitor.utils; + +import org.bytedeco.opencv.opencv_core.*; +import org.bytedeco.opencv.opencv_imgproc.*; + +import static org.bytedeco.opencv.global.opencv_core.*; +import static org.bytedeco.opencv.global.opencv_imgcodecs.*; +import static org.bytedeco.opencv.global.opencv_imgproc.*; + +public class BlurDetectorV2 { + + // =============================== + // 数据返回类 (替代 Python 中的 dict) + // =============================== + public static class DetectResult { + public String type; + public String value; + public String code; + public String desc; + public double conf; + public double score; // 显式记录分数,替代正则解析 + public double ratio; // 双图比较时的比率 + + public DetectResult(String type, String value, String code, String desc, double conf, double score, double ratio) { + this.type = type; + this.value = value; + this.code = code; + this.desc = desc; + this.conf = conf; + this.score = score; + this.ratio = ratio; + } + + @Override + public String toString() { + return String.format("Result{value='%s', code='%s', desc='%s'}", value, code, desc); + } + } + + // =============================== + // 光照归一化 + // =============================== + private static Mat normalizeLighting(Mat gray) { + Mat dst = new Mat(); + try (CLAHE clahe = createCLAHE(3.0, new Size(8, 8))) { + clahe.apply(gray, dst); + } + return dst; + } + + // =============================== + // Laplacian 清晰度 + // =============================== + private static double laplacianScore(Mat gray) { + try (Mat lap = new Mat(); Mat mean = new Mat(); Mat stddev = new Mat()) { + Laplacian(gray, lap, CV_64F); + meanStdDev(lap, mean, stddev); + double sd = stddev.createIndexer().getDouble(); + return sd * sd; // 方差 + } + } + + // =============================== + // Tenengrad 梯度 + // =============================== + private static double tenengradScore(Mat gray) { + try (Mat gx = new Mat(); Mat gy = new Mat(); + Mat gx2 = new Mat(); Mat gy2 = new Mat(); + Mat g = new Mat()) { + + Sobel(gray, gx, CV_64F, 1, 0, 3, 1.0, 0.0, BORDER_DEFAULT); + Sobel(gray, gy, CV_64F, 0, 1, 3, 1.0, 0.0, BORDER_DEFAULT); + + multiply(gx, gx, gx2); + multiply(gy, gy, gy2); + add(gx2, gy2, g); + + return mean(g).get(0); + } + } + + // =============================== + // Edge Density(边缘密度) + // =============================== + private static double edgeDensity(Mat gray) { + try (Mat edges = new Mat()) { + Canny(gray, edges, 80, 150); + int nonZero = countNonZero(edges); + return (double) nonZero / (edges.rows() * edges.cols()); + } + } + + + // =============================== + // FFT 高频能量 (最终完美版) + // =============================== + private static double fftHighFrequency(Mat gray) { + // 第一层:初始化所有基础操作矩阵,这些变量在此块内不可被重新赋值 + try (Mat f32 = new Mat(); + Mat zeros = Mat.zeros(gray.size(), CV_32F).asMat(); + MatVector planes = new MatVector(2); + Mat complexI = new Mat(); + Mat mag = new Mat(); + Mat ones = Mat.ones(gray.size(), CV_32F).asMat(); + Mat tmp = new Mat()) { + + // 1. 转为浮点并合并为双通道复数矩阵 + gray.convertTo(f32, CV_32F); + planes.put(0, f32); + planes.put(1, zeros); + merge(planes, complexI); + + // 2. 傅里叶变换 + dft(complexI, complexI); + + // 3. 计算幅度: magnitude = log(abs(fshift) + 1) + split(complexI, planes); + magnitude(planes.get(0), planes.get(1), mag); + add(mag, ones, mag); + log(mag, mag); + + // 4. fftshift 平移 (将低频移到中心) + // 声明新的变量 croppedMag 来接收裁剪结果,避免给 mag 重新赋值引发报错 + try (Mat croppedMag = new Mat(mag, new Rect(0, 0, mag.cols() & -2, mag.rows() & -2))) { + + int cx = croppedMag.cols() / 2; + int cy = croppedMag.rows() / 2; + + // 第三层:声明所有的子矩阵 (ROI) 和 mask,确保它们用完后被自动释放 + try (Mat q0 = new Mat(croppedMag, new Rect(0, 0, cx, cy)); + Mat q1 = new Mat(croppedMag, new Rect(cx, 0, cx, cy)); + Mat q2 = new Mat(croppedMag, new Rect(0, cy, cx, cy)); + Mat q3 = new Mat(croppedMag, new Rect(cx, cy, cx, cy)); + Mat mask = new Mat(croppedMag.size(), CV_32F, new Scalar(1.0))) { + + // 象限交换 (Shift) + q0.copyTo(tmp); + q3.copyTo(q0); + tmp.copyTo(q3); + q1.copyTo(tmp); + q2.copyTo(q1); + tmp.copyTo(q2); + + // 5. Mask 屏蔽中心低频 + int r = Math.min(cx, cy) / 4; + rectangle(mask, + new Point(cx - r, cy - r), + new Point(cx + r, cy + r), + new Scalar(0.0), + -1, 8, 0); + + // 6. 对应元素相乘 (只保留高频部分) + multiply(croppedMag, mask, croppedMag); + + // 7. 计算整体高频均值 + return mean(croppedMag).get(0); + } + } + } + } + + // =============================== + // 白墙和纯色背景图检测 + // =============================== + private static boolean isWhiteWall(Mat image) { + try (Mat hsv = new Mat(); + Mat mask = new Mat(); + Mat lower = new Mat(1, 1, CV_8UC3, new Scalar(0, 0, 200, 0)); + Mat upper = new Mat(1, 1, CV_8UC3, new Scalar(180, 40, 255, 0)); + Mat gray = new Mat()) { + + cvtColor(image, hsv, COLOR_BGR2HSV); + inRange(hsv, lower, upper, mask); + + double ratio = (double) countNonZero(mask) / (mask.rows() * mask.cols()); + + cvtColor(image, gray, COLOR_BGR2GRAY); + double lap = laplacianScore(gray); + double edge = edgeDensity(gray); + + if (ratio > 0.7 && lap < 15) { + return true; + } + if (lap < 10 && edge < 0.02) { + return true; + } + return false; + } + } + + // =============================== + // ROI中心区域 (切片等价实现) + // =============================== + private static Mat extractRoi(Mat image) { + int h = image.rows(); + int w = image.cols(); + + int y = h / 5; + int x = w / 5; + int roiH = (4 * h / 5) - y; + int roiW = (4 * w / 5) - x; + + return new Mat(image, new Rect(x, y, roiW, roiH)); + } + + // =============================== + // 模糊检测单图主函数 + // =============================== + public static DetectResult detectBlur(Mat image, String detectTypeKey, double threshold) { + if (image == null || image.empty()) { + throw new IllegalArgumentException("image read error"); + } + + // =============================== + // 白墙过滤 + // =============================== + if (isWhiteWall(image)) { + return new DetectResult(detectTypeKey, "1", "4001", "白墙/纯色背景 score=0", 0.0, 0.0, 0.0); + } + + try (Mat roiImage = extractRoi(image); + Mat gray = new Mat()) { + + cvtColor(roiImage, gray, COLOR_BGR2GRAY); + + try (Mat normGray = normalizeLighting(gray)) { + // =============================== + // 计算指标 + // =============================== + double lap = laplacianScore(normGray); + double ten = tenengradScore(normGray); + double edge = edgeDensity(normGray); + double fft = fftHighFrequency(normGray); + + // =============================== + // 归一化 + // =============================== + double lap_n = Math.min(lap / 2000.0, 1.0); + double ten_n = Math.min(ten / 10000.0, 1.0); + double edge_n = Math.min(edge * 10.0, 1.0); + double fft_n = Math.min(fft / 10.0, 1.0); + + // =============================== + // 综合评分 + // =============================== + double score = (0.35 * lap_n + 0.30 * ten_n + 0.20 * edge_n + 0.15 * fft_n) * 100.0; + String descStr = String.format("score=%.2f", score); + + // =============================== + // 判断 + // =============================== + if (score < threshold) { + return new DetectResult(detectTypeKey, "1", "2000", "模糊 " + descStr, 1.0, score, 0.0); + } else { + return new DetectResult(detectTypeKey, "0", "2000", "正常 " + descStr, 1.0, score, 0.0); + } + } + } + } + + public static DetectResult detectBlur(String imagePath) { + try (Mat img = imread(imagePath)) { + return detectBlur(img, "bpmh", 60.0); + } + } + + // =============================== + // 双图检测 + // =============================== + public static DetectResult doubleDetectBlur(String imgPath, String refPath, double ratioThreshold) { + boolean useRef = true; + + if (refPath == null || refPath.isEmpty()) { + useRef = false; + } + + try (Mat imgMat = imread(imgPath); + Mat refMat = useRef ? imread(refPath) : null) { + + if (refMat == null || refMat.empty()) { + useRef = false; + } + + // 单图模式兜底 + if (!useRef) { + return detectBlur(imgMat, "bpmh", 60.0); + } + + // 双图模式 + DetectResult imgResult = detectBlur(imgMat, "bpmh", 60.0); + DetectResult refResult = detectBlur(refMat, "bpmh", 60.0); + + double scoreImg = imgResult.score; + double scoreRef = refResult.score; + + if (scoreRef < 1e-6) { + return new DetectResult("bpmh", "0", "2000", "参考图异常", 0.0, scoreImg, 0.0); + } + + double ratio = scoreRef / scoreImg; + System.out.println(scoreImg + ", " + scoreRef); + + if (ratio < ratioThreshold) { + return new DetectResult("bpmh", "1", "2000", String.format("模糊 ratio=%.2f", ratio), 1.0, scoreImg, ratio); + } else { + return new DetectResult("bpmh", "0", "2000", String.format("正常 ratio=%.2f", ratio), 1.0, scoreImg, ratio); + } + } + } + + // =============================== + // 测试入口 + // =============================== + public static void main(String[] args) { + String img = "D:\\work\\images\\CAPTURE_266_20260317123336607_ee638f3b.jpg"; // 基准图提前给定 + String ref = "D:\\work\\images\\CAPTURE_258_20260317115524685_a2c29ddb.jpg"; // 摄像头后面传入图像 + + // 默认 ratio_threshold=0.85 + DetectResult result = doubleDetectBlur(img, ref, 0.85); + System.out.println(result.toString()); + } +} \ No newline at end of file diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/AudioRender.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/AudioRender.dll index fe06119..3bf543e 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/AudioRender.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/AudioRender.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCCore.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCCore.dll index 46629ad..fadba3d 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCCore.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCCore.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDK.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDK.dll index de7fc79..2b0a138 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDK.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDK.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AnalyzeData.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AnalyzeData.dll index 4160e3d..c4298ef 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AnalyzeData.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AnalyzeData.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AudioIntercom.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AudioIntercom.dll index 09e995b..888d607 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AudioIntercom.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AudioIntercom.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AudioRender.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AudioRender.dll index fe06119..3bf543e 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AudioRender.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/AudioRender.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCAlarm.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCAlarm.dll index 79e6a70..adf4153 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCAlarm.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCAlarm.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCCoreDevCfg.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCCoreDevCfg.dll index 4a9fc40..f62213a 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCCoreDevCfg.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCCoreDevCfg.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCDisplay.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCDisplay.dll index 36ce3c1..3ad9fd7 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCDisplay.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCDisplay.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCGeneralCfgMgr.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCGeneralCfgMgr.dll index 694d431..53838f8 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCGeneralCfgMgr.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCGeneralCfgMgr.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCIndustry.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCIndustry.dll index e6949ae..a4bcec0 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCIndustry.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCIndustry.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCPlayBack.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCPlayBack.dll index bd0d967..7d43335 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCPlayBack.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCPlayBack.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCPreview.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCPreview.dll index 3499614..50c1df1 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCPreview.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCPreview.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCVoiceTalk.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCVoiceTalk.dll index b6c222e..aa67fa9 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCVoiceTalk.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/HCVoiceTalk.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/OpenAL32.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/OpenAL32.dll index e268aee..24ca039 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/OpenAL32.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/OpenAL32.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/StreamTransClient.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/StreamTransClient.dll index a6d42f3..480b4cd 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/StreamTransClient.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/StreamTransClient.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/SystemTransform.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/SystemTransform.dll index 24c2e7a..12ba69f 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/SystemTransform.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/SystemTransform.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/libiconv2.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/libiconv2.dll index 774f5e2..cddc745 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/libiconv2.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/HCNetSDKCom/libiconv2.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/PlayCtrl.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/PlayCtrl.dll index 377fd66..9b644aa 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/PlayCtrl.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/PlayCtrl.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/SuperRender.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/SuperRender.dll index 4170d83..2584252 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/SuperRender.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/SuperRender.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/hlog.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/hlog.dll index 80b2044..83266a5 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/hlog.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/hlog.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/hpr.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/hpr.dll index 61cccaa..1e3f1ad 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/hpr.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/hpr.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/libeay32.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/libeay32.dll index 118fa33..de8c6be 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/libeay32.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/libeay32.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/ssleay32.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/ssleay32.dll index bbe68b3..c086f10 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/ssleay32.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/ssleay32.dll differ diff --git a/sz-service/sz-service-admin/src/main/resources/lib/win/zlib1.dll b/sz-service/sz-service-admin/src/main/resources/lib/win/zlib1.dll index 19dd4da..23f8f92 100644 Binary files a/sz-service/sz-service-admin/src/main/resources/lib/win/zlib1.dll and b/sz-service/sz-service-admin/src/main/resources/lib/win/zlib1.dll differ