diff --git a/father.txt b/father.txt index 83a008c..85c146f 100644 --- a/father.txt +++ b/father.txt @@ -1,16 +1,4 @@ [ - "古井贡5年", - "g8", - "g8y", - "g16", - "g20", - "g5(2)", - "gxl", - "g7", - "v6", - "gjyy", - "lcg", - "v6", - "v60", - "D8" + "正常", + "倾斜" ] \ No newline at end of file diff --git a/web/src/main/java/com/zhehekeji/web/config/ConfigProperties.java b/web/src/main/java/com/zhehekeji/web/config/ConfigProperties.java index e3326a1..c69accc 100644 --- a/web/src/main/java/com/zhehekeji/web/config/ConfigProperties.java +++ b/web/src/main/java/com/zhehekeji/web/config/ConfigProperties.java @@ -47,6 +47,15 @@ public class ConfigProperties { private String productDoc; private List smokeBoxType; + private InventoryImage inventoryImage; + + @Data + public static class InventoryImage{ + private Integer cameraId; + private Integer imageSize = 640; + private Integer[] imageSpace = {0, 0}; + } + @Data public static class SmokeBoxType{ private String type= ""; diff --git a/web/src/main/java/com/zhehekeji/web/controller/CameraControlController.java b/web/src/main/java/com/zhehekeji/web/controller/CameraControlController.java index 4299bc2..56c7629 100644 --- a/web/src/main/java/com/zhehekeji/web/controller/CameraControlController.java +++ b/web/src/main/java/com/zhehekeji/web/controller/CameraControlController.java @@ -6,6 +6,7 @@ import com.zhehekeji.core.util.Assert; import com.zhehekeji.web.config.ConfigProperties; import com.zhehekeji.web.entity.Camera; import com.zhehekeji.web.entity.CameraDownload; +import com.zhehekeji.web.entity.yolo.ImageTool; import com.zhehekeji.web.lib.*; import com.zhehekeji.web.lib.hik.HCNetSDK; import com.zhehekeji.web.lib.joyware.NetSDKLib; @@ -19,6 +20,7 @@ import org.springframework.http.HttpEntity; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.io.IOException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -306,6 +308,22 @@ public class CameraControlController { return Result.success(path); } + @PostMapping("/pic") + @ApiOperation(value = "立即拍照") + public Result picCrop(@RequestParam ConfigProperties.InventoryImage image) { + + checkLogin(image.getCameraId()); + String path = "D:\\work\\"+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+".jpeg"; + String pathCrop = "D:\\work\\crop\\"+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))+".jpeg"; + cameraControlModule.pic(image.getCameraId(),0,path); + try { + ImageTool.cropImage(path,pathCrop,image.getImageSize(),image.getImageSpace()); + } catch (IOException e) { + throw new RuntimeException(e); + } +// taskDelayExecutor.addPicDelayTask(image.getCameraId(),path,0L); + return Result.success(pathCrop); + } @Resource private ConfigProperties configProperties; @Resource diff --git a/web/src/main/java/com/zhehekeji/web/entity/AlgorithmPojo.java b/web/src/main/java/com/zhehekeji/web/entity/AlgorithmPojo.java index 23269ff..9c900f4 100644 --- a/web/src/main/java/com/zhehekeji/web/entity/AlgorithmPojo.java +++ b/web/src/main/java/com/zhehekeji/web/entity/AlgorithmPojo.java @@ -19,6 +19,8 @@ public class AlgorithmPojo { private String goodsTypeResult; private int goodsNumberResult; private Calculate calculate; + private String path; + private String model; public static AlgorithmPojo buildAlgorithmPojo(Street street, KsecDataInfo dataInfo) { AlgorithmPojo algorithmPojo = new AlgorithmPojo(); diff --git a/web/src/main/java/com/zhehekeji/web/entity/yolo/ClassifyEntity.java b/web/src/main/java/com/zhehekeji/web/entity/yolo/ClassifyEntity.java new file mode 100644 index 0000000..c5ab293 --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/entity/yolo/ClassifyEntity.java @@ -0,0 +1,10 @@ +package com.zhehekeji.web.entity.yolo; + +import lombok.Data; + +@Data +public class ClassifyEntity { + private Integer index; + private String name; + private double confidence; +} diff --git a/web/src/main/java/com/zhehekeji/web/entity/yolo/ImageTool.java b/web/src/main/java/com/zhehekeji/web/entity/yolo/ImageTool.java new file mode 100644 index 0000000..065b9da --- /dev/null +++ b/web/src/main/java/com/zhehekeji/web/entity/yolo/ImageTool.java @@ -0,0 +1,82 @@ +package com.zhehekeji.web.entity.yolo; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +public class ImageTool { + public static void main(String[] args) { + try { + // 输入图片路径 + String inputImagePath = "D:\\PycharmProjects\\yolo\\pyTest\\train\\1\\192.168.2.64_01_2025090413515066.jpeg"; + // 输出图片路径 + String outputImagePath = "D:\\test.jpg"; + + // 裁剪参数 + int width = 200; + int height = 200; + int x = 100; + int y = 100; + + // 调用裁剪方法 + boolean success = cropImage(inputImagePath, outputImagePath, width, height, x, y); + if (success) { + System.out.println("图片裁剪成功并保存到 " + outputImagePath); + } else { + System.out.println("图片裁剪失败"); + } + } catch (IOException e) { + System.err.println("处理图片时出错: " + e.getMessage()); + } + } + public static boolean cropImage(String inputImagePath, String outputImagePath, + int width, Integer[] space) throws IOException { + + return cropImage(inputImagePath, outputImagePath, width, width, space[0], space[1]); + } + + /** + * 裁剪图片并保存到指定位置 + * + * @param inputImagePath 输入图片地址 + * @param outputImagePath 输出图片地址 + * @param width 裁剪宽度 + * @param height 裁剪高度 + * @param x 裁剪区域左上角x坐标 + * @param y 裁剪区域左上角y坐标 + * @return 是否裁剪成功 + * @throws IOException 当读取或写入图片失败时抛出异常 + */ + public static boolean cropImage(String inputImagePath, String outputImagePath, + int width, int height, int x, int y) throws IOException { + // 读取原图片 + File inputFile = new File(inputImagePath); + BufferedImage originalImage = ImageIO.read(inputFile); + + // 检查边界有效性 + if (x < 0 || y < 0 || x + width > originalImage.getWidth() || y + height > originalImage.getHeight()) { + throw new IllegalArgumentException("裁剪区域超出图片边界"); + } + + // 创建裁剪后的图片 + BufferedImage croppedImage = originalImage.getSubimage(x, y, width, height); + + // 获取输出文件的扩展名 + String format = "jpg"; + int dotIndex = outputImagePath.lastIndexOf('.'); + if (dotIndex > 0) { + format = outputImagePath.substring(dotIndex + 1).toLowerCase(); + } + + // 确保输出目录存在 + File outputFile = new File(outputImagePath); + File parentDir = outputFile.getParentFile(); + if (parentDir != null && !parentDir.exists()) { + parentDir.mkdirs(); + } + + // 保存裁剪后的图片 + return ImageIO.write(croppedImage, format, outputFile); + } +} diff --git a/web/src/main/java/com/zhehekeji/web/pojo/stock/StockExportExcel.java b/web/src/main/java/com/zhehekeji/web/pojo/stock/StockExportExcel.java index 64c7272..20f2ff6 100644 --- a/web/src/main/java/com/zhehekeji/web/pojo/stock/StockExportExcel.java +++ b/web/src/main/java/com/zhehekeji/web/pojo/stock/StockExportExcel.java @@ -36,30 +36,30 @@ public class StockExportExcel { // private String column; - - @ExcelProperty(index = 3, value = "上位品规") - private String wmsCategory; - - - @ExcelProperty(index = 4, value = "核对品规结果") - private String category; - - - @ExcelProperty(index = 5, value = "上位个数") - private Integer wmsCount; - - - - @ExcelProperty(index = 6, value = "核对个数") - private Integer count; - +// +// @ExcelProperty(index = 3, value = "上位品规") +// private String wmsCategory; +// +// +// @ExcelProperty(index = 4, value = "核对品规结果") +// private String category; +// +// +// @ExcelProperty(index = 5, value = "上位个数") +// private Integer wmsCount; +// +// +// +// @ExcelProperty(index = 6, value = "核对个数") +// private Integer count; +// - @ExcelProperty(index = 7, value = "盘点结果") + @ExcelProperty(index = 3, value = "盘点结果") private String status; - @ExcelProperty(index = 8, value = "时间") + @ExcelProperty(index = 4, value = "时间") private String exportTime; } diff --git a/web/src/main/java/com/zhehekeji/web/service/PlcService.java b/web/src/main/java/com/zhehekeji/web/service/PlcService.java index 23eefc4..06a9009 100644 --- a/web/src/main/java/com/zhehekeji/web/service/PlcService.java +++ b/web/src/main/java/com/zhehekeji/web/service/PlcService.java @@ -56,6 +56,8 @@ import java.util.*; import java.util.concurrent.*; import java.util.stream.Collectors; +import static com.zhehekeji.web.service.algorithm.AlgorithmService.fatherList; + /** * @Description plc信号指令处理类 * 对plcId做同步处理,防止内存中保存的正在运行的订单信息错乱 @@ -770,8 +772,8 @@ public class PlcService { OrderInfo orderInfo = new OrderInfo(street, plcCmdInfo, 1, cmdCode); Stock stock = stockMapper.getByStreetAndDirectionAndSideAndRowColumn(orderInfo.getStreetId(), plcCmdInfo.getFromDirection(), orderInfo.getSeparation(), orderInfo.getRow(), orderInfo.getColumn()); - AlgorithmPojo algorithmPojo = algorithmService.getGoodResult(street, dataInfo); - String paths = String.join(";", algorithmPojo.getCalculate().getFisheye()) + ";" + String.join(";", algorithmPojo.getCalculate().getCloseUp()) + ";" + algorithmPojo.getCalculate().getPath(); + AlgorithmPojo algorithmPojo = algorithmService.getGoodResult(street, dataInfo,path); + String paths = path; //货物使用球机扫码 @@ -788,19 +790,23 @@ public class PlcService { // }); // thread.start(); //核对异常 - Integer status = 4; +// Integer status = 4; //托盘和货物都正确 // if (algorithmPojo != null && algorithmPojo.getResult() != null && algorithmPojo.getResult() == 1) { // status = 2; // } + Integer status = 1; + if (algorithmPojo != null && algorithmPojo.getResult() != null && algorithmPojo.getResult() == 0) { + status = 2; + } if (stock == null) { stock = Stock.builder() .checkNum(plcCmdInfo.getOrderNum()) .lotnum(plcCmdInfo.getLotnum()) - .count(algorithmPojo.getGoodsNumberResult()) - .category(algorithmPojo.getGoodsTypeResult()) - .wmsCount(algorithmPojo.getGoodsNumber()) - .wmsCategory(algorithmPojo.getGoodsType()) +// .count(algorithmPojo.getGoodsNumberResult()) + .category(fatherList.get(algorithmPojo.getResult())) +// .wmsCount(algorithmPojo.getGoodsNumber()) +// .wmsCategory(algorithmPojo.getGoodsType()) .streetId(orderInfo.getStreetId()) .wmsTrayCode(dataInfo.getTrayCode()) .direction(plcCmdInfo.getFromDirection()) @@ -817,10 +823,10 @@ public class PlcService { stock.setLotnum(plcCmdInfo.getLotnum()); stock.setExportTime(LocalDateTime.now()); stock.setWmsTrayCode(dataInfo.getTrayCode()); - stock.setCount(algorithmPojo.getGoodsNumberResult()); - stock.setCategory(algorithmPojo.getGoodsTypeResult()); - stock.setWmsCategory(algorithmPojo.getGoodsType()); - stock.setWmsCount(algorithmPojo.getGoodsNumber()); +// stock.setCount(algorithmPojo.getGoodsNumberResult()); + stock.setCategory(fatherList.get(algorithmPojo.getResult())); +// stock.setWmsCategory(algorithmPojo.getGoodsType()); +// stock.setWmsCount(algorithmPojo.getGoodsNumber()); stock.setCheckPic(path); stock.setPreoperationPic(paths); stock.setCheckNum(plcCmdInfo.getOrderNum()); diff --git a/web/src/main/java/com/zhehekeji/web/service/StockService.java b/web/src/main/java/com/zhehekeji/web/service/StockService.java index bec7851..4b7ed9c 100644 --- a/web/src/main/java/com/zhehekeji/web/service/StockService.java +++ b/web/src/main/java/com/zhehekeji/web/service/StockService.java @@ -279,11 +279,11 @@ public class StockService { stockExportExcel.setStreetName(street.getName()); stockExportExcel.setTrayCode(stock.getWmsTrayCode()); stockExportExcel.setDirection((stock.getDirection() == 1 ? "左侧" : "右侧")+"-"+(stock.getSide()==1?"浅货位":"深货位")+"-"+stock.getRow()+"层"+"-"+stock.getColumn()+"列"); - stockExportExcel.setWmsCategory(stock.getWmsCategory()); - stockExportExcel.setCategory((stock.getCategory() == null||stock.getWmsCategory() == null) ? "无" : (stock.getWmsCategory().equals(stock.getCategory())?"一致":"不一致")); - - stockExportExcel.setWmsCount(stock.getWmsCount()); - stockExportExcel.setCount(stock.getCount()+stock.getCountTop()); +// stockExportExcel.setWmsCategory(stock.getWmsCategory()); +// stockExportExcel.setCategory((stock.getCategory() == null||stock.getWmsCategory() == null) ? "无" : (stock.getWmsCategory().equals(stock.getCategory())?"一致":"不一致")); +// +// stockExportExcel.setWmsCount(stock.getWmsCount()); +// stockExportExcel.setCount(stock.getCount()+stock.getCountTop()); stockExportExcel.setStatus(status[stock.getStatus()]); stockExportExcel.setExportTime(stock.getFormattedExportTime()); // stockExportExcel.setCode(stock.getTrayCode()); @@ -319,10 +319,10 @@ public class StockService { stockExportExcel.setStreetName(streetMap.get(stock.getStreetId())); stockExportExcel.setTrayCode(stock.getWmsTrayCode()); stockExportExcel.setDirection((stock.getDirection() == 1 ? "左侧" : "右侧")+"-"+(stock.getSide()==1?"浅货位":"深货位")+"-"+stock.getRow()+"层"+"-"+stock.getColumn()+"列"); - stockExportExcel.setWmsCategory(stock.getWmsCategory()); - stockExportExcel.setCategory((stock.getCategory() == null||stock.getWmsCategory() == null) ? "无" : (stock.getWmsCategory().equals(stock.getCategory())?"一致":"不一致")); - stockExportExcel.setWmsCount(stock.getWmsCount()); - stockExportExcel.setCount(stock.getCount()+stock.getCountTop()); +// stockExportExcel.setWmsCategory(stock.getWmsCategory()); +// stockExportExcel.setCategory((stock.getCategory() == null||stock.getWmsCategory() == null) ? "无" : (stock.getWmsCategory().equals(stock.getCategory())?"一致":"不一致")); +// stockExportExcel.setWmsCount(stock.getWmsCount()); +// stockExportExcel.setCount(stock.getCount()+stock.getCountTop()); stockExportExcel.setStatus(status[stock.getStatus()]); stockExportExcel.setExportTime(stock.getFormattedExportTime()); // stockExportExcel.setCode(stock.getTrayCode()); diff --git a/web/src/main/java/com/zhehekeji/web/service/algorithm/AlgorithmService.java b/web/src/main/java/com/zhehekeji/web/service/algorithm/AlgorithmService.java index 0975ef0..cdbb82f 100644 --- a/web/src/main/java/com/zhehekeji/web/service/algorithm/AlgorithmService.java +++ b/web/src/main/java/com/zhehekeji/web/service/algorithm/AlgorithmService.java @@ -8,12 +8,15 @@ import com.zhehekeji.web.entity.AlgorithmPojo; import com.zhehekeji.web.entity.Category; import com.zhehekeji.web.entity.Street; import com.zhehekeji.web.entity.yolo.Calculate; +import com.zhehekeji.web.entity.yolo.ClassifyEntity; import com.zhehekeji.web.mapper.CategoryMapper; import com.zhehekeji.web.service.CategoryService; import com.zhehekeji.web.service.ksec.KsecDataInfo; import lombok.extern.slf4j.Slf4j; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; +import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.ResourceAccessException; @@ -38,9 +41,6 @@ public class AlgorithmService { ConfigProperties configProperties; - public static void main(String[] args) { - System.out.println(null=="111"); - } public static Map classIdMap = new HashMap<>(); public static List fatherList = new ArrayList<>(); @@ -90,16 +90,16 @@ public class AlgorithmService { throw new RuntimeException(e); } - String url = "http://"+algorithmPojo.getIp()+":8094/industrialCamera/panoramaAlgorithm"; + String url = "http://127.0.0.1:8094/industrialCamera/panoramaAlgorithm"; //String url = "http://127.0.0.1:8083"+"/visionCompute"; - + HttpEntity httpEntity = new HttpEntity<>(algorithmPojo); try { // System.out.println("1111111111111"+algorithmPojo.toString()); // String jsonString = gson.toJson(algorithmPojo); ResponseEntity> response = restTemplate.exchange( url, HttpMethod.POST, - null, // 如果有请求体可以传入 HttpEntity + httpEntity, // 如果有请求体可以传入 HttpEntity new ParameterizedTypeReference>() {} ); Calculate calculate = response.getBody().getData(); @@ -135,6 +135,61 @@ public class AlgorithmService { return algorithmPojo; } + public static void main(String[] args) { + AlgorithmService algorithmService = new AlgorithmService(); + AlgorithmPojo algorithmPojo =new AlgorithmPojo(); + algorithmPojo.setPath("D:\\PycharmProjects\\yolo\\pyTest\\train\\1\\192.168.2.64_01_20250904120927842.jpeg"); + + algorithmPojo =algorithmService.getGoodResultHttpClassifyOne(algorithmPojo); + System.out.println(algorithmPojo); + } + public AlgorithmPojo getGoodResultHttpClassifyOne(AlgorithmPojo algorithmPojo) { + try { + Thread.sleep(1500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + + String url = "http://127.0.0.1:8094/industrialCamera/classifyOne"; + //String url = "http://127.0.0.1:8083"+"/visionCompute"; + HttpEntity httpEntity = new HttpEntity<>(algorithmPojo); + try { +// System.out.println("1111111111111"+algorithmPojo.toString()); + // String jsonString = gson.toJson(algorithmPojo); + ResponseEntity> response = restTemplate.exchange( + url, + HttpMethod.POST, + httpEntity, // 如果有请求体可以传入 HttpEntity + new ParameterizedTypeReference>() {} + ); + ClassifyEntity calculate = response.getBody().getData(); +// System.out.println("2222222222"+calculate.toString()); + log.info("视觉服务返回结果:{}",calculate.toString()); +// 若没有找到,则赋值-2,以防和堆垛机返回的type匹配错误 +// 倾斜1,正常0 + if(calculate.getIndex()!=null && calculate.getIndex()==0){ + algorithmPojo.setResult(1); + algorithmPojo.setGoodsTypeResult(algorithmPojo.getGoodsType()); + }else { + algorithmPojo.setResult(0); + } + +// System.out.println(calculate); + }catch (RestClientException e){ + log.error("未连接上堆垛机"+e); + //Assert.isTrue(false,"请求失败,视觉服务未连接"); + algorithmPojo.setResult(0); + return algorithmPojo; + + }catch (Exception e){ + log.error("堆垛机报错"+e); + e.printStackTrace(); + algorithmPojo.setResult(0); + return algorithmPojo; + } + return algorithmPojo; + } + public AlgorithmPojo getGoodResultTcp(AlgorithmPojo algorithmPojo) { AlgorithmClint clint = new AlgorithmClint(); clint.clint(algorithmPojo.getIp(),9040,algorithmPojo,configProperties.getSmokeBoxType()); @@ -170,10 +225,11 @@ public class AlgorithmService { return algorithmPojo; } - public AlgorithmPojo getGoodResult(Street street, KsecDataInfo dataInfo ) { + public AlgorithmPojo getGoodResult(Street street, KsecDataInfo dataInfo ,String path) { AlgorithmPojo algorithmPojo = AlgorithmPojo.buildAlgorithmPojo(street, dataInfo); + algorithmPojo.setPath(path); if(configProperties.getVisualSense().getAble()) { - algorithmPojo = getGoodResultHttp(algorithmPojo); + algorithmPojo = getGoodResultHttpClassifyOne(algorithmPojo); }else { algorithmPojo.setResult(1); algorithmPojo.setGoodsNumberResult(algorithmPojo.getGoodsNumber()); diff --git a/web/src/main/resources/application-prod.yml b/web/src/main/resources/application-prod.yml index 832545f..42e9e15 100644 --- a/web/src/main/resources/application-prod.yml +++ b/web/src/main/resources/application-prod.yml @@ -99,7 +99,6 @@ rfid: scanTime: 1 - asyncExecutorThread: corePoolSize: 5 maxPoolSize: 70 @@ -120,3 +119,7 @@ smokeBoxType: numOfLayers: 1 #用于计算总数的个数 numLayers: 6 + +inventoryImage: + imageSize: 1000 + imageSpace: [0, 0] \ No newline at end of file