Browse Source

调用多模态更改为1.9B视觉大模型

master
wangxun 5 months ago
parent
commit
18ecb642fd
16 changed files with 492 additions and 62 deletions
  1. +21
    -4
      src/main/java/com/inspect/simulator/controller/ModelController.java
  2. +5
    -0
      src/main/java/com/inspect/simulator/domain/bigmodelr/ContentJson.java
  3. +17
    -0
      src/main/java/com/inspect/simulator/domain/visual/ApiVisualRequest.java
  4. +20
    -0
      src/main/java/com/inspect/simulator/domain/visual/ApiVisualResponse.java
  5. +18
    -0
      src/main/java/com/inspect/simulator/domain/visual/ImageData.java
  6. +18
    -0
      src/main/java/com/inspect/simulator/domain/visual/InferResult.java
  7. +19
    -0
      src/main/java/com/inspect/simulator/domain/visual/ResponseData.java
  8. +29
    -0
      src/main/java/com/inspect/simulator/domain/visual/VisualJson.java
  9. +1
    -1
      src/main/java/com/inspect/simulator/mapper/PatrolResultMapper.java
  10. +3
    -0
      src/main/java/com/inspect/simulator/mapper/ResultAnalysisMapper.java
  11. +4
    -0
      src/main/java/com/inspect/simulator/service/ModelService.java
  12. +1
    -1
      src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java
  13. +4
    -1
      src/main/java/com/inspect/simulator/service/impl/LuminosityRequestConsumerManager.java
  14. +311
    -51
      src/main/java/com/inspect/simulator/service/impl/ModelServiceImpl.java
  15. +4
    -4
      src/main/resources/mapper/PatrolResultMapper.xml
  16. +17
    -0
      src/main/resources/mapper/ResultAnalysisMapper.xml

+ 21
- 4
src/main/java/com/inspect/simulator/controller/ModelController.java View File

@ -1,12 +1,10 @@
package com.inspect.simulator.controller;
import com.inspect.simulator.domain.visual.ImageData;
import com.inspect.simulator.hikVision.utils.AjaxResult;
import com.inspect.simulator.service.ModelService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@ -24,4 +22,23 @@ public class ModelController {
return AjaxResult.success().put("data", i);
}
//视觉大模型
@PostMapping("/model/analysis")
@ResponseBody
public String Visualization(@RequestBody ImageData imageData)
{
return modelService.Visualization(imageData);
}
//视觉大模型
@PostMapping("/model/visualization")
@ResponseBody
public AjaxResult Visualization(@RequestBody String analyseRequestStr)
{
final int i =modelService.protractImgVisualization(analyseRequestStr);
return AjaxResult.success().put("data", i);
}
}

+ 5
- 0
src/main/java/com/inspect/simulator/domain/bigmodelr/ContentJson.java View File

@ -1,5 +1,6 @@
package com.inspect.simulator.domain.bigmodelr;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -7,6 +8,7 @@ import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) // 忽略null字段
public class ContentJson {
private Boolean isDefect;//是否存在异常 0-异常1-正常
@ -23,8 +25,11 @@ public class ContentJson {
private String taskPatrolId;
private String businessId;
private String useType;
private String imgUrl;
public ContentJson(boolean b, String 无描述内容, String 无缺陷类型, String s) {
}
}

+ 17
- 0
src/main/java/com/inspect/simulator/domain/visual/ApiVisualRequest.java View File

@ -0,0 +1,17 @@
package com.inspect.simulator.domain.visual;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiVisualRequest {
private ImageData data;
private String model;
}

+ 20
- 0
src/main/java/com/inspect/simulator/domain/visual/ApiVisualResponse.java View File

@ -0,0 +1,20 @@
package com.inspect.simulator.domain.visual;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class ApiVisualResponse {
private String traceId;
private Boolean success;
private List<ResponseData> data;
private Integer timeUsed;
}

+ 18
- 0
src/main/java/com/inspect/simulator/domain/visual/ImageData.java View File

@ -0,0 +1,18 @@
package com.inspect.simulator.domain.visual;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ImageData {
private String image_name;
private imageType image_type;
private String image_data;
public enum imageType {
url, BASE64,local
}
}

+ 18
- 0
src/main/java/com/inspect/simulator/domain/visual/InferResult.java View File

@ -0,0 +1,18 @@
package com.inspect.simulator.domain.visual;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class InferResult {
private List<Float> bbox; // [x1, y1, x2, y2] 格式的坐标
private String category;
private Float score;
}

+ 19
- 0
src/main/java/com/inspect/simulator/domain/visual/ResponseData.java View File

@ -0,0 +1,19 @@
package com.inspect.simulator.domain.visual;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseData {
private Integer error_code;
private String image_name;
private Integer image_height;
private Integer image_width;
private List<InferResult> infer_results;
}

+ 29
- 0
src/main/java/com/inspect/simulator/domain/visual/VisualJson.java View File

@ -0,0 +1,29 @@
package com.inspect.simulator.domain.visual;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL) // 忽略null字段
public class VisualJson {
private String defectType;//返回异常类型
private String filter;//2-表示使用光明大模型
private String objectId;
private String taskPatrolId;
private String businessId;
private String useType;//传参算法类型
private String imgUrl;
}

+ 1
- 1
src/main/java/com/inspect/simulator/mapper/PatrolResultMapper.java View File

@ -96,5 +96,5 @@ public interface PatrolResultMapper {
List<PatrolResult> selectPatrolResults(PatrolResultParam patrolResultParam);
String selectPatrolResultByTaskPatrolledId(String taskPatrolledId);
String selectPatrolResultByTaskPatrolledId(@Param("taskPatrolledId") String taskPatrolledId,@Param("objectId") String objectId);
}

+ 3
- 0
src/main/java/com/inspect/simulator/mapper/ResultAnalysisMapper.java View File

@ -2,6 +2,7 @@ package com.inspect.simulator.mapper;
import com.inspect.simulator.domain.analysis.vo.AnalysisResult;
import com.inspect.simulator.domain.bigmodelr.ContentJson;
import com.inspect.simulator.domain.visual.VisualJson;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -16,4 +17,6 @@ public interface ResultAnalysisMapper {
int addDmtModelInfo(@Param("list") List<ContentJson> contentJsonList);
int addVisualModelInfo(@Param("list") List<VisualJson> visualJsonList);
}

+ 4
- 0
src/main/java/com/inspect/simulator/service/ModelService.java View File

@ -4,6 +4,7 @@ package com.inspect.simulator.service;
import com.inspect.simulator.domain.assistant.Session;
import com.inspect.simulator.domain.bigmodelr.Multimodal;
import com.inspect.simulator.domain.bigmodelr.VisualModel;
import com.inspect.simulator.domain.visual.ImageData;
import java.util.List;
@ -19,6 +20,9 @@ public interface ModelService {
int bigModelPicAnalyse(String analyseRequestStr);
//视觉大模型服务接口
String Visualization(ImageData imageData);
int protractImgVisualization(String analyseRequestStr);
}

+ 1
- 1
src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java View File

@ -908,7 +908,7 @@ public class HikVisionServiceImpl implements HikVisionService {
picFtp(outputPath, inputStream, ftpUrlAddress, ftpUrlPort, ftpUrlAccount, ftpUrlPwd);
} catch (IOException e) {
System.err.println("处理图片时出错: " + e.getMessage());
log.info("处理图片时出错: " + e.getMessage());
e.printStackTrace();
}
return outputPath;


+ 4
- 1
src/main/java/com/inspect/simulator/service/impl/LuminosityRequestConsumerManager.java View File

@ -41,7 +41,10 @@ public class LuminosityRequestConsumerManager {
// 调用多模态
String requestInfo = String.valueOf(request);
if(requestInfo != null && !requestInfo.isEmpty()) {
modelService.bigModelPicAnalyse(requestInfo);
//多模态大模型
// modelService.bigModelPicAnalyse(requestInfo);
//视觉大模型1.9B
modelService.protractImgVisualization(requestInfo);
}
} catch (Exception e) {
log.info("LuminosityRequestConsumerManager error queueSize: {}, request: {}", getQueueSize(), request);


+ 311
- 51
src/main/java/com/inspect/simulator/service/impl/ModelServiceImpl.java View File

@ -11,6 +11,7 @@ import com.inspect.simulator.domain.algorithm.out.AnalyseResPoint;
import com.inspect.simulator.domain.algorithm.out.AnalyseResult;
import com.inspect.simulator.domain.assistant.*;
import com.inspect.simulator.domain.bigmodelr.*;
import com.inspect.simulator.domain.visual.*;
import com.inspect.simulator.mapper.PatrolResultMapper;
import com.inspect.simulator.mapper.ResultAnalysisMapper;
import com.inspect.simulator.service.ModelService;
@ -27,27 +28,31 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.SocketTimeoutException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
public class ModelServiceImpl implements ModelService {
// @Value("${file.dmtModelUrl:test}")
private String dmtModelUrl ="http://25.80.45.92:80/lmp-cloud-ias-server/api/vlm/chat/completions/";
//视觉大模型调用地址
private String visualizationUrl = "http://25.80.45.91:80/xlm-gateway-ygubrj/sfm-api-gateway/gateway/ai_version/rsv-rgohm4it/api/predict";
// @Value("${file.dmtModelUrl:test}")
private String dmtModelUrl = "http://25.80.45.92:80/lmp-cloud-ias-server/api/vlm/chat/completions/";
// @Value("${file.dmtModelHeader:test}")
// @Value("${file.dmtModelHeader:test}")
private String dmtModelHeader = "54c1ae2c5fd54afe85e74d6fe9161f7f";
private String hrFtpUrl = "ftp://ftpuser:atia2018@192.168.4.129:10012/";
@ -64,6 +69,7 @@ public class ModelServiceImpl implements ModelService {
// @Value("${file.ftpUrlPort:10000}")
private Integer ftpUrlPort = 10012;
// private Integer ftpUrlPort = 10990;
@Resource
private AnalysisRemoteService analysisRemoteService;
@ -82,6 +88,7 @@ public class ModelServiceImpl implements ModelService {
.readTimeout(60, TimeUnit.SECONDS) // 读取超时
.writeTimeout(30, TimeUnit.SECONDS) // 写入超时
.build();
public ModelServiceImpl() {
// 设置JSON序列化时忽略null值
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
@ -89,7 +96,7 @@ public class ModelServiceImpl implements ModelService {
//调用语义大模型接口
public String semanticsModel(Multimodal multimodal){
public String semanticsModel(Multimodal multimodal) {
// 重试次数
int maxRetries = 3;
@ -103,7 +110,7 @@ public class ModelServiceImpl implements ModelService {
// 发送请求并获取响应
ChatCompletionResponse response = semanticsModelResponse(request);
String content = String.valueOf(response.getChoices().get(0).getMessage().getContent());
System.out.println("语义大模型返回结果:"+content);
System.out.println("语义大模型返回结果:" + content);
return content;
} catch (IOException e) {
if (attempt == maxRetries) {
@ -119,6 +126,7 @@ public class ModelServiceImpl implements ModelService {
}
return "请求处理失败";
}
private ChatCompletionRequest buildRequestBody(Multimodal multimodal) {
ChatCompletionRequest request = new ChatCompletionRequest();
@ -164,8 +172,6 @@ public class ModelServiceImpl implements ModelService {
}
//智能体服务接口(语义大模型小助手)
public String intelligentAssistant(Session session) {
@ -187,7 +193,7 @@ public class ModelServiceImpl implements ModelService {
SessionResponse sessionResponse = sessionResponse(sessionBody);
Answer answerReturn = new Gson().fromJson(sessionResponse.getData().getAnswer(), Answer.class);
answer=answerReturn.getOutput();
answer = answerReturn.getOutput();
System.out.println("智能体服务API此次会话回复内容: " + answerReturn.getOutput());
}
@ -274,7 +280,6 @@ public class ModelServiceImpl implements ModelService {
}
@Override
public int bigModelPicAnalyse(String analyseRequestStr) {
@ -282,22 +287,22 @@ public class ModelServiceImpl implements ModelService {
log.info(Color.RED + "[dmt bigModel] bigModel: analyseRequestStr={}", analyseRequestStr);
AnalyseRequest analyseRequest = new Gson().fromJson(analyseRequestStr, AnalyseRequest.class);
Multimodal multimodal=new Multimodal();
Multimodal multimodal = new Multimodal();
multimodal.setImageData(analyseRequest.getObjectList().get(0).getImageUrlList()[0]);
//调用多模态大模型,
String multimodalResult = this.Multimodal(multimodal);
log.info("调用多模态响应结果:"+multimodalResult);
log.info("调用多模态响应结果:" + multimodalResult);
ChatCompletionResponse parsedResponse = new Gson().fromJson(multimodalResult, ChatCompletionResponse.class);
String content = (String) parsedResponse.getChoices().get(0).getMessage().getContent();
// 移除转义字符还原为标准JSON格式
String normalizedJson = content.replace("\\\"", "\"").replace("\\n", "");
String lineId = patrolResultMapper.selectPatrolResultByTaskPatrolledId(analyseRequest.getTaskPatrolId());
String lineId = patrolResultMapper.selectPatrolResultByTaskPatrolledId(analyseRequest.getTaskPatrolId(), analyseRequest.getObjectList().get(0).getObjectId());
String[] typeList = analyseRequest.getObjectList().get(0).getTypeList();
List<ContentJson> contentJsonList =new ArrayList<>();
for (int i = 0; i < typeList.length; i++) {
List<ContentJson> contentJsonList = new ArrayList<>();
for (int i = 0; i < typeList.length; i++) {
// 使用Jackson反序列化
ContentJson contentJson = new ContentJson(false, "无描述内容", "无缺陷类型","");
ContentJson contentJson = new ContentJson(false, "无描述内容", "无缺陷类型", "");
try {
contentJson = objectMapper.readValue(normalizedJson, ContentJson.class);
} catch (JsonProcessingException e) {
@ -305,7 +310,7 @@ public class ModelServiceImpl implements ModelService {
}
if (contentJson.getIsDefect()) {//true-缺陷
contentJson.setIsDefectValue("0");
}else {
} else {
contentJson.setIsDefectValue("1");
}
@ -314,7 +319,6 @@ public class ModelServiceImpl implements ModelService {
contentJson.setObjectId(objectId);
contentJson.setFilter("2");
contentJson.setTaskPatrolId(analyseRequest.getTaskPatrolId());
contentJson.setBusinessId(lineId);
contentJson.setUseType(typeList[i]);
contentJsonList.add(contentJson);
@ -330,7 +334,7 @@ public class ModelServiceImpl implements ModelService {
int maxRetries = 2;
int attempt = 0;
String moRen="{\"id\":\"chat-bdae1b2b74264dd88c262ab7bc717864\",\"object\":\"chat.completion\",\"created\":1751855431,\"choices\":[{\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"{\\n \\\"isDefect\\\": true,\\n \\\"info\\\": \\\"油位计的指针指在4-5之间,接近油位计的刻度上限,表明油位偏高,可能存在油位异常的情况。油位过高可能会导致设备运行时油温升高,影响设备的正常散热和绝缘性能,甚至可能引发设备故障。建议及时检查油位计的准确性,并根据实际情况进行适当的油位调整,以确保设备的安全运行。同时,应定期监测油位变化,避免因油位过高或过低导致的设备问题。此外,图中还可以看到油位计周围有一些污渍和杂物,可能会影响油位计的正常工作,建议进行清洁和维护。油位计下方的标签和标识也应该清晰可见,以便于日常的检查和维护工作。整体来看,设备的运行环境和状态需要进一步的关注和维护,以确保电力系统的安全和稳定运行。\\\",\\n \\\"defectType\\\": \\\"油位异常\\\"\\n}\"},\"finish_reason\":\"stop\"}],\"usage\":{\"prompt_tokens\":1331,\"completion_tokens\":210,\"total_tokens\":1541},\"model\":\"Qwen2-VL\"}\n";
String moRen = "{\"id\":\"chat-bdae1b2b74264dd88c262ab7bc717864\",\"object\":\"chat.completion\",\"created\":1751855431,\"choices\":[{\"index\":0,\"message\":{\"role\":\"assistant\",\"content\":\"{\\n \\\"isDefect\\\": true,\\n \\\"info\\\": \\\"油位计的指针指在4-5之间,接近油位计的刻度上限,表明油位偏高,可能存在油位异常的情况。油位过高可能会导致设备运行时油温升高,影响设备的正常散热和绝缘性能,甚至可能引发设备故障。建议及时检查油位计的准确性,并根据实际情况进行适当的油位调整,以确保设备的安全运行。同时,应定期监测油位变化,避免因油位过高或过低导致的设备问题。此外,图中还可以看到油位计周围有一些污渍和杂物,可能会影响油位计的正常工作,建议进行清洁和维护。油位计下方的标签和标识也应该清晰可见,以便于日常的检查和维护工作。整体来看,设备的运行环境和状态需要进一步的关注和维护,以确保电力系统的安全和稳定运行。\\\",\\n \\\"defectType\\\": \\\"油位异常\\\"\\n}\"},\"finish_reason\":\"stop\"}],\"usage\":{\"prompt_tokens\":1331,\"completion_tokens\":210,\"total_tokens\":1541},\"model\":\"Qwen2-VL\"}\n";
while (attempt < maxRetries) {
try {
attempt++;
@ -360,7 +364,7 @@ public class ModelServiceImpl implements ModelService {
/**
* 构建符合规范的请求体
*/
private ChatCompletionRequest buildCorrectRequest(Multimodal multimodal) {
private ChatCompletionRequest buildCorrectRequest(Multimodal multimodal) throws IOException {
ChatCompletionRequest request = new ChatCompletionRequest();
// 设置模型名称默认"rsv-0zygizvz"
request.setModel(multimodal.getModel() != null ? multimodal.getModel() : "SGGM-VL-74B-V1.2");
@ -398,11 +402,14 @@ public class ModelServiceImpl implements ModelService {
}
// log.info("图片请求"+multimodal.getImageData());
// 转换图片为base64
String base64String = downloadFtp(multimodal.getImageData());
if (base64String!=null) {
InputStream inputStream = downloadFtp(multimodal.getImageData());
byte[] fileBytes = IOUtils.toByteArray(inputStream);
String base64String = Base64.getEncoder().encodeToString(fileBytes);
if (base64String != null) {
imageContent.setImage("data:image/" + fileExtension + ";base64," + base64String);
}else{
log.info(multimodal.getImageData()+"图片转base64未成功!");
} else {
log.info(multimodal.getImageData() + "图片转base64未成功!");
}
// imageUrl.setUrl("data:image/" + fileExtension + ";base64," + base64String);
// imageContent.setImageUrl(imageUrl);
@ -420,30 +427,31 @@ public class ModelServiceImpl implements ModelService {
return request;
}
public String downloadFtp(String downloadPath) {
InputStream inputStream=null;
FTPSClient ftps;
try {
ftps = new FTPSClient(true);
ftps.connect(ftpUrlAddress, ftpUrlPort);
boolean loginRes = ftps.login(ftpUrlAccount, ftpUrlPwd);
System.out.println(loginRes);
ftps.setFileType(2);
ftps.enterLocalPassiveMode();
ftps.setControlEncoding("UTF-8");
ftps.setFileTransferMode(10);
ftps.execPROT("P");
inputStream = ftps.retrieveFileStream(downloadPath);
if (inputStream == null) {
System.out.println("[FTP] DOWNLOAD FAIL, EMPTY STREAM:" + downloadPath);
}
byte[] fileBytes = IOUtils.toByteArray(inputStream);
return Base64.getEncoder().encodeToString(fileBytes);
} catch (Exception e) {
log.error("error" + e);
}
return null;
}
// public String downloadFtp(String downloadPath) {
// InputStream inputStream=null;
// FTPSClient ftps;
// try {
// ftps = new FTPSClient(true);
// ftps.connect(ftpUrlAddress, ftpUrlPort);
// boolean loginRes = ftps.login(ftpUrlAccount, ftpUrlPwd);
// System.out.println(loginRes);
// ftps.setFileType(2);
// ftps.enterLocalPassiveMode();
// ftps.setControlEncoding("UTF-8");
// ftps.setFileTransferMode(10);
// ftps.execPROT("P");
// inputStream = ftps.retrieveFileStream(downloadPath);
// if (inputStream == null) {
// System.out.println("[FTP] DOWNLOAD FAIL, EMPTY STREAM:" + downloadPath);
// }
// byte[] fileBytes = IOUtils.toByteArray(inputStream);
// return Base64.getEncoder().encodeToString(fileBytes);
// } catch (Exception e) {
// log.error("error" + e);
// }
// return null;
// }
//图片路径转base64
public String convertToBase64(String imagePath) {
@ -457,7 +465,7 @@ public class ModelServiceImpl implements ModelService {
}
private ChatCompletionResponse sendRequest(ChatCompletionRequest request) throws IOException {
log.info("多模态搭模型请求路径信息:路径"+dmtModelUrl+",请求头key: "+dmtModelHeader);
log.info("多模态搭模型请求路径信息:路径" + dmtModelUrl + ",请求头key: " + dmtModelHeader);
String requestBody;
try {
@ -488,8 +496,260 @@ public class ModelServiceImpl implements ModelService {
}
//设置规范调用视觉大模型
public int protractImgVisualization(String analyseRequestStr) {
int j=-1;
String visualization = null;
ApiVisualResponse apiVisualResponse = new ApiVisualResponse();
log.info(Color.MAGENTA + "[ Visualization] bigModelPicAnalyse: analyseRequestStr={}", analyseRequestStr);
AnalyseRequest analyseRequest = new Gson().fromJson(analyseRequestStr, AnalyseRequest.class);
String imgUrl = analyseRequest.getObjectList().get(0).getImageUrlList()[0];
String lineId = patrolResultMapper.selectPatrolResultByTaskPatrolledId(analyseRequest.getTaskPatrolId(), analyseRequest.getObjectList().get(0).getObjectId());
String[] typeList = analyseRequest.getObjectList().get(0).getTypeList();
List<VisualJson> visualJsonList = new ArrayList<>();
String imageName = imgUrl.substring(imgUrl.lastIndexOf("/") + 1);//图片名称
Path path = Paths.get(imgUrl);
String directoryPath = path.getParent().toString().replace("\\", "/") + "/"; // 获取图片所在目录并统一使用正斜杠
// 新文件路径
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
String markPicName = sf.format(date);
String pureName = imageName.substring(0, imageName.lastIndexOf('.'));
String outputPath = directoryPath + pureName + "_" + markPicName + ".jpg";
ImageData imageData = new ImageData();
imageData.setImage_name(imageName);
imageData.setImage_data(analyseRequest.getObjectList().get(0).getImageUrlList()[0]);
//下载图片
InputStream inputStream = downloadFtp(imgUrl);
//调用视觉大模型
visualization = this.Visualization(imageData);
if (StringUtils.isNotEmpty(visualization)) {
try {
apiVisualResponse = objectMapper.readValue(visualization, ApiVisualResponse.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
} else {
log.info(imageName + "图片,视觉大模型无返回,使用默认数据");
visualization = "{\"traceId\":\"88e754a8-1d07-4bbd-9d43-98ac40bdb7ad\",\"success\":true,\"data\":[{\"error_code\":0,\"image_name\":\"1613_20250711173000_2081817_02160558348850500131.jpg\",\"image_height\":720,\"image_width\":1280,\"infer_results\":[{\"bbox\":[533.7729,583.49506,773.02124,718.8728],\"category\":\"箱门闭合异常-箱门闭合正常\",\"score\":0.96470034},{\"bbox\":[795.3903,536.1146,1043.0077,718.15497],\"category\":\"箱门闭合异常-箱门闭合正常\",\"score\":0.9343145},{\"bbox\":[1057.7261,638.2431,1223.5446,719.07074],\"category\":\"箱门闭合异常-箱门闭合正常\",\"score\":0.8148986},{\"bbox\":[318.5776,0.34692764,566.56915,592.8563],\"category\":\"设备积污-表面污秽\",\"score\":0.064688765}]}],\"timeUsed\":411}\n";
try {
apiVisualResponse = objectMapper.readValue(visualization, ApiVisualResponse.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
InputStream outputImageStream = null;
try {
outputImageStream = drawBoundingBoxesAndSave(apiVisualResponse, inputStream);
} catch (IOException e) {
e.printStackTrace();
}
if (outputImageStream != null) {
log.info("视觉大模型复筛图片" + imageName + "已上传到:" + outputPath);
this.picFtp(outputPath, outputImageStream, ftpUrlAddress, ftpUrlPort, ftpUrlAccount, ftpUrlPwd);
for (int i = 0; i < typeList.length; i++) {
VisualJson visualJson =new VisualJson();
//存入数据库
String objectId = analyseRequest.getObjectList().get(0).getObjectId();
visualJson.setDefectType(apiVisualResponse.getData().get(0).getInfer_results().get(0).getCategory());
visualJson.setObjectId(objectId);
visualJson.setFilter("2");
visualJson.setTaskPatrolId(analyseRequest.getTaskPatrolId());
visualJson.setBusinessId(lineId);
visualJson.setImgUrl(outputPath);
visualJson.setUseType(typeList[i]);
visualJsonList.add(visualJson);
}
j = resultAnalysisMapper.addVisualModelInfo(visualJsonList);
}
return j;
}
// 绘图方法实现
public InputStream drawBoundingBoxesAndSave(ApiVisualResponse apiVisualResponse,
InputStream inputStream) throws IOException {
// 1. 读取图片
BufferedImage originalImage = ImageIO.read(inputStream);
// 2. 创建可绘制的图片副本
BufferedImage imageWithBoxes = new BufferedImage(
originalImage.getWidth(),
originalImage.getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = imageWithBoxes.createGraphics();
graphics.drawImage(originalImage, 0, 0, null);
// 3. 设置绘制参数
graphics.setColor(Color.RED); // 框线颜色
graphics.setStroke(new BasicStroke(3)); // 线宽
graphics.setFont(new Font("Arial", Font.BOLD, 20)); // 标签字体
// 4. 遍历所有检测结果
for (ResponseData dataItem : apiVisualResponse.getData()) {
for (InferResult inferResult : dataItem.getInfer_results()) {
//可信值大于等于0.9进行画框
if (inferResult.getScore() >= 0.7) {
List<Float> bbox = inferResult.getBbox();
// 4.1 校验bbox数据有效性
if (bbox == null || bbox.size() < 4) {
System.err.println("Invalid bbox data: " + bbox);
continue;
}
// 4.2 提取坐标并转换
int x1 = bbox.get(0).intValue();
int y1 = bbox.get(1).intValue();
int x2 = bbox.get(2).intValue();
int y2 = bbox.get(3).intValue();
int width = x2 - x1;
int height = y2 - y1;
// 4.3 绘制矩形框
graphics.drawRect(x1, y1, width, height);
// 4.4 添加标签类别 + 置信度
String label = String.format("%s (%.2f)",
inferResult.getCategory(),
inferResult.getScore());
graphics.drawString(label, x1, y1 - 5);
}
}
}
// 5. 释放资源并保存图片
graphics.dispose();
// ImageIO.write(imageWithBoxes, "jpg", new File(outputImagePath));
// 6. 将BufferedImage转换为InputStream
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(imageWithBoxes, "jpg", os);
return new ByteArrayInputStream(os.toByteArray());
}
//上传图片到ftp
public void picFtp(String newPath, InputStream originalPath, String ftpUrlAddress, Integer ftpUrlPort, String
ftpUrlAccount, String ftpUrlPwd) {
//不存在输出文件路径进行创建
if (!Files.exists(Paths.get(newPath))) {
try {
Files.createDirectories(Paths.get(newPath));
} catch (IOException e) {
e.printStackTrace();
}
}
FTPSClient ftps = null;
try {
ftps = new FTPSClient(true);
ftps.connect(ftpUrlAddress, ftpUrlPort);
boolean loginRes = ftps.login(ftpUrlAccount, ftpUrlPwd);
System.out.println(loginRes);
ftps.setFileType(2);
ftps.enterLocalPassiveMode();
ftps.setControlEncoding("UTF-8");
ftps.setFileTransferMode(10);
ftps.execPROT("P");
boolean success = ftps.storeFile(newPath, originalPath);
if (!success) {
System.err.println("上传失败!FTP 返回: " + ftps.getReplyString());
}
} catch (Exception e) {
log.error("error" + e);
} finally {
// 5. 关闭资源
try {
if (originalPath != null) originalPath.close();
if (ftps != null && ftps.isConnected()) {
ftps.logout();
ftps.disconnect();
}
} catch (IOException e) {
log.error("error" + e);
}
}
}
//ftp图片获取
public InputStream downloadFtp(String downloadPath) {
InputStream inputStream = null;
FTPSClient ftps;
try {
ftps = new FTPSClient(true);
ftps.connect(ftpUrlAddress, ftpUrlPort);
boolean loginRes = ftps.login(ftpUrlAccount, ftpUrlPwd);
System.out.println(loginRes);
ftps.setFileType(2);
ftps.enterLocalPassiveMode();
ftps.setControlEncoding("UTF-8");
ftps.setFileTransferMode(10);
ftps.execPROT("P");
inputStream = ftps.retrieveFileStream(downloadPath);
if (inputStream == null) {
System.out.println("[FTP] DOWNLOAD FAIL, EMPTY STREAM:" + downloadPath);
}
} catch (Exception e) {
log.error("error" + e);
}
return inputStream;
}
//视觉大模型
@Override
public String Visualization(ImageData imageData) {
String requestBody = null;
String responseJson = null;
String urlPrefix = "http://10.216.82.91:12913/lingzhou/videoMonitor/app/htjc6/htjcImage/";
//构建请求体
// ApiVisualRequest request = new ApiVisualRequest();
List<ImageData> imageList = new ArrayList<>();
ImageData newImageData = new ImageData();
Path path = Paths.get(imageData.getImage_data());
String imgName = path.getFileName().toString();// 直接获取带后缀的文件名
newImageData.setImage_type(ImageData.imageType.url);
newImageData.setImage_name(imgName);
newImageData.setImage_data(urlPrefix + imageData.getImage_data());
log.info("打印允许访问的请求图片路径:" + urlPrefix + imageData.getImage_data());
imageList.add(newImageData);
// request.setData(imageData);
// request.setModel("");
try {
requestBody = objectMapper.writeValueAsString(imageList);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
//接口请求
Request httpRequest = new Request.Builder()
.url(visualizationUrl)
.post(RequestBody.create(MediaType.parse("application/json"), requestBody))
.addHeader("Authorization", "Bearer aWwZeA73i2KtnkGql10iYqC31xTHswvT")
.addHeader("Content-Type", "application/json")
.build();
try (Response response = httpClient.newCall(httpRequest).execute()) {
if (!response.isSuccessful()) {
String errorBody = response.body() != null ? response.body().string() : "无响应体";
throw new IOException(String.format("请求失败,状态码: %d,错误信息: %s", response.code(), errorBody));
}
String responseBody = response.body().string();
ApiVisualResponse apiVisualResponse = objectMapper.readValue(responseBody, ApiVisualResponse.class);
responseJson = new Gson().toJson(apiVisualResponse);
log.info("视觉大模型url返回Json打印:" + responseJson);
} catch (Exception e) {
e.printStackTrace();
}
return responseJson;
}
}

+ 4
- 4
src/main/resources/mapper/PatrolResultMapper.xml View File

@ -837,10 +837,10 @@
</select>
<select id="selectPatrolResultByTaskPatrolledId" parameterType="string" resultType="string">
<select id="selectPatrolResultByTaskPatrolledId" resultType="string">
select r.line_id
from patrol_task_result_main as p
LEFT JOIN patrol_result as r on p.line_id = r.main_id
where p.task_patrolled_id=#{taskPatrolledId}
from patrol_result as r
where r.task_patrolled_id=#{taskPatrolledId} and device_id = #{objectId}
</select>
</mapper>

+ 17
- 0
src/main/resources/mapper/ResultAnalysisMapper.xml View File

@ -49,4 +49,21 @@
</foreach>
</insert>
<insert id="addVisualModelInfo" parameterType="java.util.List">
INSERT INTO result_analysis
( res_status, filter, objectId, task_patrol_id, business_id,alg_type,res_img_url)
VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.defectType},
#{item.filter},
#{item.objectId},
#{item.taskPatrolId},
#{item.businessId},
#{item.useType},
#{item.imgUrl}
)
</foreach>
</insert>
</mapper>

Loading…
Cancel
Save