增加3d拍照

淮阴-烟草
LAPTOP-S9HJSOEB\昊天 1 year ago
parent efd40fa08c
commit 5ddc663563

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -5,6 +5,10 @@ import com.zhehekeji.core.pojo.Result;
import com.zhehekeji.web.entity.Category;
import com.zhehekeji.web.pojo.category.PageSearch;
import com.zhehekeji.web.service.CategoryService;
import com.zhehekeji.web.service.IndustrialCamera.LxPointCloudSaveImage;
import com.zhehekeji.web.service.IndustrialCamera.algorithm.BoxPositionConf;
import com.zhehekeji.web.service.IndustrialCamera.algorithm.PcdPojo;
import com.zhehekeji.web.service.IndustrialCamera.algorithm.PointCloudProcessor;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.core.io.ClassPathResource;
@ -89,4 +93,25 @@ public class CategoryController {
response.flushBuffer();
}
@GetMapping("/getBoxCount")
@ApiOperation(value = "个数获取")
public void getBoxCount(HttpServletResponse response) throws IOException {
LxPointCloudSaveImage.saveImage("192.168.1.82","E:\\1.pcd",1);
PcdPojo pojo = new PcdPojo();
pojo.setPcd1("E:/1.pcd");
pojo.setConfigPath("E:\\pe.json");
try {
pojo.setPCDInfo(pojo);
} catch (IOException e) {
throw new RuntimeException(e);
}
PointCloudProcessor pointCloudProcessor = new PointCloudProcessor();
List<BoxPositionConf> confs = pointCloudProcessor.getBoxPositionConf("E:\\peconf.json");
int i = pointCloudProcessor.slicing(pojo,confs);
System.out.println(pojo.toString());
System.out.println(i);
}
}

@ -0,0 +1,12 @@
package com.zhehekeji.web.service.IndustrialCamera;
public interface CameraSaveUtil {
/**
*
* @param sn sn
* @param path
* @param type sn ip
* @return
*/
boolean saveImage(String sn,String path,String type);
}

@ -0,0 +1,50 @@
package com.zhehekeji.web.service.IndustrialCamera;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.PointerByReference;
import java.util.Arrays;
import java.util.List;
public interface DcLibrary extends Library {
DcLibrary INSTANCE = (DcLibrary) Native.load((System.getProperty("user.dir"))+"\\libs\\plc\\LxCameraApiR.dll", DcLibrary.class);
// 创建一个新的实例
// 设备详细信息结构体
class LxDeviceInfo extends Structure {
public long handle; // 使用 long 类型表示 DcHandle
public short dev_type;
public byte[] id = new byte[32];
public byte[] ip = new byte[32];
public byte[] sn = new byte[32];
public byte[] mac = new byte[32];
public byte[] firmware_ver = new byte[32];
public byte[] algor_ver = new byte[32];
public byte[] name = new byte[32];
public byte[] reserve = new byte[32];
public byte[] reserve2 = new byte[32];
public byte[] reserve3 = new byte[64];
public byte[] reserve4 = new byte[128];
@Override
protected List<String> getFieldOrder() {
return Arrays.asList("handle", "dev_type", "id", "ip", "sn", "mac", "firmware_ver", "algor_ver", "name", "reserve", "reserve2", "reserve3", "reserve4");
}
}
// 设备打开函数
int DcOpenDevice(int open_mode, String param, PointerByReference handle, LxDeviceInfo info);
String DcGetDeviceList(PointerByReference devlist, int devnum);
int DcCloseDevice(Pointer handle);
int DcStartStream(Pointer handle);
int DcStopStream(Pointer handle);
int DcSaveXYZ(Pointer handle, String filename);
int DcSetCmd(Pointer handle, int cmd);
}
// Define LX_OPEN_MODE as an enum or int based on your C definition

@ -0,0 +1,111 @@
package com.zhehekeji.web.service.IndustrialCamera;
import com.sun.jna.Native;
import com.sun.jna.ptr.PointerByReference;
import lombok.extern.slf4j.Slf4j;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
public class LxPointCloudSaveImage {
static DcLibrary INSTANCER = (DcLibrary) Native.loadLibrary((System.getProperty("user.dir"))+"\\libs\\plc\\LxCameraApiR.dll", DcLibrary.class);
static DcLibrary INSTANCEL = (DcLibrary) Native.loadLibrary((System.getProperty("user.dir"))+"\\libs\\plc\\LxCameraApiL.dll", DcLibrary.class);
static Map<String, PointerByReference> handleMap = new ConcurrentHashMap<>();
public static PointerByReference getHandle(String sn,int type ,DcLibrary INSTANCE){
if(handleMap.get(sn)!=null){
return handleMap.get(sn);
}else {
// 创建 Pointer 的引用
PointerByReference handleRef = new PointerByReference();
// 创建 PointerByReference 的实例用于接收设备列表
// PointerByReference devlistRef = new PointerByReference();
// 创建 LxDeviceInfo 实例
DcLibrary.LxDeviceInfo info = new DcLibrary.LxDeviceInfo();
//library.DcGetDeviceList( devlistRef,0);
// 调用 DcOpenDevice 函数
System.out.println(sn+" "+handleRef+" "+info);
int result = INSTANCE.DcOpenDevice(1, sn, handleRef, info);
int i = 0;
if(result ==0) {
handleMap.put(sn, handleRef);
}else {
for (int ii=0;i<50;i++ ) {
result = INSTANCE.DcOpenDevice(1, sn, handleRef, info);
System.out.println(i + "次尝试");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
// 输出结果
System.out.println("Result: " + result);
System.out.println("Handle: " + handleRef.getValue()); // 获取 DcHandle 的值
System.out.println("Device Type: " + info.dev_type);
System.out.println("ID: " + new String(info.id).trim());
System.out.println("IP: " + new String(info.ip).trim());
System.out.println("SN: " + new String(info.sn).trim());
System.out.println("MAC: " + new String(info.mac).trim());
System.out.println("Firmware Version: " + new String(info.firmware_ver).trim());
System.out.println("Algorithm Version: " + new String(info.algor_ver).trim());
System.out.println("Name: " + new String(info.name).trim());
System.out.println("Reserve: " + new String(info.reserve).trim());
System.out.println("Reserve2: " + new String(info.reserve2).trim());
System.out.println("Reserve3: " + new String(info.reserve3).trim());
System.out.println("Reserve4: " + new String(info.reserve4).trim());//lxPointCloudApi.DcCloseDevice(handle);
return handleRef;
}
}
public static boolean saveImage(String sn, String path,int type) {
DcLibrary INSTANCE;
if (type==1){
INSTANCE = INSTANCER;
}else {
INSTANCE = INSTANCEL;
}
int result = 0;
PointerByReference handleRef = getHandle(sn,type,INSTANCE);
result = INSTANCE.DcStartStream(handleRef.getValue());
System.out.println("Result: " + result);
result = INSTANCE.DcSetCmd(handleRef.getValue(),5001);
System.out.println("Result: " + result);
Path path1 = Paths.get(path);
try {
// 如果路径不存在,则创建目录
Files.createDirectories(path1.getParent());
}catch (Exception e){
log.info("路径失败");
}
int i = INSTANCE.DcSaveXYZ(handleRef.getValue(), path);
log.info(sn+" 3dCamera get pcd :"+path +";rest:"+i);
System.out.println(sn+" 3dCamera get pcd :"+path +";rest:"+i);
result = INSTANCE.DcStopStream(handleRef.getValue());
System.out.println("stop Stream Result: " + result);
return true;
}
public static void main(String[] args) {
saveImage("1","E:\\1-8-2-R.pcd",1);
saveImage("2","E:\\12-R.pcd",2);
}
}

@ -0,0 +1,11 @@
package com.zhehekeji.web.service.IndustrialCamera.algorithm;
import lombok.Data;
import java.util.List;
@Data
public class BoxPositionConf {
Double height;
List<Double[]> position;
}

@ -0,0 +1,77 @@
package com.zhehekeji.web.service.IndustrialCamera.algorithm;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class PCDReader {
public static void main(String[] args) {
String filePath = "path/to/your/file.pcd";
try {
if (isBinaryFormat(filePath)) {
readBinaryPCD(filePath);
} else {
readAsciiPCD(filePath);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static boolean isBinaryFormat(String filePath) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("DATA")) {
return line.contains("binary");
}
}
}
return false;
}
private static void readAsciiPCD(String filePath) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
if (!line.startsWith("#") && !line.startsWith("FIELDS") && !line.startsWith("SIZE") &&
!line.startsWith("TYPE") && !line.startsWith("COUNT") && !line.startsWith("WIDTH") &&
!line.startsWith("HEIGHT") && !line.startsWith("VIEWPOINT") && !line.startsWith("POINTS") &&
!line.startsWith("DATA")) {
String[] values = line.split(" ");
for (String value : values) {
System.out.println(value);
}
}
}
}
}
private static void readBinaryPCD(String filePath) throws IOException {
try (FileInputStream fis = new FileInputStream(filePath)) {
ByteBuffer buffer = ByteBuffer.wrap(fis.readAllBytes());
buffer.order(ByteOrder.LITTLE_ENDIAN);
// Skip header (assuming 11 lines of header; adjust if needed)
for (int i = 0; i < 11; i++) {
while (buffer.get() != '\n') {
// Skip header lines
}
}
// Read binary data (assuming float x, y, z and int rgb)
while (buffer.hasRemaining()) {
float x = buffer.getFloat();
float y = buffer.getFloat();
float z = buffer.getFloat();
int rgb = buffer.getInt(); // Read 4 bytes for RGB
System.out.printf("x: %f, y: %f, z: %f, rgb: %d%n", x, y, z, rgb);
}
}
}
}

@ -0,0 +1,53 @@
package com.zhehekeji.web.service.IndustrialCamera.algorithm;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import java.io.File;
import java.io.IOException;
@Data
public class PcdPojo {
double[][] rotationMatrix = {
{0.9982215762138367, 0.057795289903879166, 0.014606773853302002},
{-0.0510917492210865, 0.7032182216644287, 0.7091360092163086},
{0.030712969601154327, -0.7086211442947388, 0.7049204111099243}
}; // 这里使用给定的旋转矩阵
double[] minBounds = {-905.5771484375, 174.71572875976562, 69.14165496826172}; // 裁剪最小值
double[] maxBounds = {321.80609130859375, 1170.4776611328125, 1199.3507080078125}; // 裁剪最大值
private double floorHeight;
private double[] max_pt;
private double[] min_pt;
private double[] rotation;
//路径D://config//3DConfig/"+相机sn+".json"
private String configPath;
//盘点路径 configProperties.getSavePath().getMediaPath() + street.getLeft3D()+ currentDate.format(formatter)+"/"+transmissionPojo.getCheckId()+".pcd";
//随行路径 configProperties.getSavePath().getMediaPath() + street.getLeft3D()+"000/"+ currentDate.format(formatter)+"/"+transmissionPojo.getRow()+".pcd";
private String pcd1;
private String pcd2;
private String cameraSn1;
private String cameraSn2;
private Integer count;
public PcdPojo setPCDInfo(PcdPojo pojo) throws IOException {
ObjectMapper mapper = new ObjectMapper();
// 读取 JSON 文件并转换为 配置信息
PcdPojo pojoIn = mapper.readValue(new File(pojo.getConfigPath()), mapper.getTypeFactory().constructType(PcdPojo.class));
this.setMinBounds(pojoIn.getMin_pt());
this.setMaxBounds(pojoIn.getMax_pt());
double[] x = {pojoIn.getRotation()[0], pojoIn.getRotation()[1], pojoIn.getRotation()[2]};
double[] y = {pojoIn.getRotation()[3], pojoIn.getRotation()[4], pojoIn.getRotation()[5]};
double[] z = {pojoIn.getRotation()[6], pojoIn.getRotation()[7], pojoIn.getRotation()[8]};
this.setRotationMatrix(new double[][]{x, y, z});
return this;
}
}

@ -0,0 +1,501 @@
package com.zhehekeji.web.service.IndustrialCamera.algorithm;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhehekeji.web.service.IndustrialCamera.LxPointCloudSaveImage;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
public class PointCloudProcessor {
//
// public static void main(String[] args) {
// PcdPojo pojo = new PcdPojo();
// pojo.setPcd1("D:\\WeChet\\WeChat Files\\wxid_ttkf0xgmyihv22\\FileStorage\\File\\2024-09\\8-6-2-L.pcd");
// pojo.setPcd2("D:\\WeChet\\WeChat Files\\wxid_ttkf0xgmyihv22\\FileStorage\\File\\2024-09\\369.pcd");
// pojo.setConfigPath("E:\\D91FCF1FAB3568DB.json");
// double i = similarity(pojo,10);
// System.out.println("111 "+i);
// }
/**
* pcd
*
* @param pojo pcd
* @return
*/
//计算两个pcd的相似性
// public static double similarity(PcdPojo pojo) {
//
// ObjectMapper mapper = new ObjectMapper();
//
// try {
// // 读取 JSON 文件并转换为 配置信息
// PcdPojo pojoIn = mapper.readValue(new File(pojo.getConfigPath()), mapper.getTypeFactory().constructType(PcdPojo.class));
//
//
// // 打印转换后的实体类列表
// pojo = pojo.setPCDInfo(pojoIn);
//
// //报错则认为没有配置文件,返回盘点失败
// } catch (JsonMappingException e) {
// e.printStackTrace();
// return 0;
// } catch (JsonProcessingException e) {
// e.printStackTrace();
// return 0;
// } catch (IOException e) {
// e.printStackTrace();
// return 0;
// }
// System.out.println(pojo.toString());
// // 计算pcd1
// List<double[]> points = readPCD(pojo.getPcd1());
// if (points == null || points.isEmpty()) {
// return 0;
// }
//
// // 创建一个DecimalFormat对象指定格式
// DecimalFormat df = new DecimalFormat("#.#");
// //map xyz
// PcdPojo finalPojo = pojo;
// Map<Double, Map<Double, Double>> clippedPoint = points.stream()
// .map(point -> {
// //旋转
// return rotatePoints(point, finalPojo.getRotationMatrix());
//
// })
// .filter(point ->
// //截取
// clipPoints(point, finalPojo.getMinBounds(), finalPojo.getMaxBounds())
// )//z轴截取
// .collect(Collectors.groupingBy(point -> point[0], Collectors.toMap(point -> point[1], point -> point[2], (a, b) -> {
// return a > b ? a : b;
// })));
// //计算xy轴平均值
// Double xAge = clippedPoint.keySet().stream().collect(Collectors.averagingDouble(v -> v));
// Double yAge = clippedPoint.values().stream().flatMap(map -> map.values().stream()).collect(Collectors.averagingDouble(v -> v));
//
// //计算pcd2
// List<double[]> points2 = readPCD(pojo.getPcd2());
// if (points2 == null || points2.isEmpty()) {
// return 0;
// }
//
// //map xyz
// Map<Double, Map<Double, Double>> clippedPoint2 = points2.stream()
// .map(point -> {
// //旋转
// return rotatePoints(point, finalPojo.getRotationMatrix());
//
// })
// .filter(point ->
// //截取
// clipPoints(point, finalPojo.getMinBounds(), finalPojo.getMaxBounds())
// )//z轴截取
// .collect(Collectors.groupingBy(point -> point[0], Collectors.toMap(point -> point[1], point -> point[2], (a, b) -> {
// return a > b ? a : b;
// })));
//
// //计算xy轴平均值
// Double xAge2 = clippedPoint2.keySet().stream().collect(Collectors.averagingDouble(v -> v));
// Double yAge2 = clippedPoint2.values().stream().flatMap(map -> map.values().stream()).collect(Collectors.averagingDouble(v -> v));
// //计算相似度
// return (Math.abs(yAge) < Math.abs(yAge2) ? Math.abs(yAge) / Math.abs(yAge2) : Math.abs(yAge2) / Math.abs(yAge));
// }
public static double similarity(PcdPojo pojo,int i) {
ObjectMapper mapper = new ObjectMapper();
try {
// 读取 JSON 文件并转换为 配置信息
// PcdPojo pojoIn = mapper.readValue(new File(pojo.getConfigPath()), mapper.getTypeFactory().constructType(PcdPojo.class));
// 打印转换后的实体类列表
pojo = pojo.setPCDInfo(pojo);
//报错则认为没有配置文件,返回盘点失败
} catch (JsonMappingException e) {
e.printStackTrace();
return 0;
} catch (JsonProcessingException e) {
e.printStackTrace();
return 0;
} catch (IOException e) {
e.printStackTrace();
return 0;
}
System.out.println(pojo.toString());
// 计算pcd1
List<double[]> points = readPCD(pojo.getPcd1());
if (points == null || points.isEmpty()) {
return 0;
}
//计算pcd2
List<double[]> points2 = readPCD(pojo.getPcd2());
if (points2 == null || points2.isEmpty()) {
return 0;
}
//计算相似度
return calculateTruncatedMeans(points,points2,pojo,i,new ArrayList<>());
}
/**
* y
*
* @param pointCloud
* @param divisions
* @return 3 y
*/
public static double calculateTruncatedMeans(List<double[]> pointCloud, List<double[]> pointCloud2,PcdPojo pojo, int divisions,List<double[]> results) {
double width = (pojo.getMaxBounds()[0] - pojo.getMinBounds()[0]) / divisions; // 每个小方块的宽度
double depth = (pojo.getMaxBounds()[2] - pojo.getMinBounds()[2]) / divisions; // 每个小方块的深度
int count = 0;
int countSum = 0;
for (int i = 0; i < divisions; i++) {
for (int j = 0; j < divisions; j++) {
double leftBottomX = pojo.getMinBounds()[0] + i * width; // 左下角 x 坐标
double leftBottomZ = pojo.getMinBounds()[2] + j * depth; // 左下角 z 坐标
double rightTopX = pojo.getMinBounds()[0] + (i + 1) * width; // 右上角 x 坐标
double rightTopZ = pojo.getMinBounds()[2] + (j + 1) * depth; // 右上角 z 坐标
List<Double> yValues = new ArrayList<>();
for (double[] point : pointCloud) {
point = rotatePoints(point, pojo.getRotationMatrix());
if(clipPoints(point, pojo.getMinBounds(), pojo.getMaxBounds())) {
if (point[0] >= leftBottomX && point[0] < rightTopX &&
point[2] >= leftBottomZ && point[2] < rightTopZ) {
yValues.add(point[1]);
}
}
}
List<Double> yValues2 = new ArrayList<>();
for (double[] point : pointCloud2) {
point = rotatePoints(point, pojo.getRotationMatrix());
if(clipPoints(point, pojo.getMinBounds(), pojo.getMaxBounds())) {
if (point[0] >= leftBottomX && point[0] < rightTopX &&
point[2] >= leftBottomZ && point[2] < rightTopZ) {
yValues2.add(point[1]);
}
}
}
double truncatedMean = calculateTruncatedMean(yValues, 0.1); // 截断比例为10%
double truncatedMean2 = calculateTruncatedMean(yValues2, 0.1); // 截断比例为10%
double similarity = (truncatedMean - pojo.getMinBounds()[1])/(pojo.getMaxBounds()[1] - pojo.getMinBounds()[1]);
double similarity2 = (truncatedMean2 - pojo.getMinBounds()[1])/(pojo.getMaxBounds()[1] - pojo.getMinBounds()[1]);
countSum++;
if(Double.isNaN(similarity) && Double.isNaN(similarity2)){
break;
}
System.out.println("similarity:"+similarity+"similarity2:"+similarity2);
double max = Math.max(similarity, similarity2); // 获取较大数
double min = Math.min(similarity, similarity2); // 获取较小数
if(max-min<0.01){
count++;
}
results.add(new double[]{leftBottomX, leftBottomZ, truncatedMean, truncatedMean2});
}
}
System.out.println(count);
pojo.setCount(count);
return (double) count /countSum;
}
/**
*
*
* @param values
* @param trimRatio
* @return
*/
private static double calculateTruncatedMean(List<Double> values, double trimRatio) {
int trimCount = (int) Math.ceil(values.size() * trimRatio);
values.sort(Comparator.naturalOrder());
double sum = 0;
for (int i = trimCount; i < values.size() - trimCount; i++) {
sum += values.get(i);
}
return sum / (values.size() - 2 * trimCount);
}
public static List<double[]> readPCD(String filePath) {
try {
if (isBinaryFormat(filePath)) {
return readBinaryPCD(filePath);
} else {
return readAsciiPCD(filePath);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static boolean isBinaryFormat(String filePath) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("DATA")) {
return line.contains("binary");
}
}
}
return false;
}
private static List<double[]> readAsciiPCD(String filePath) throws IOException {
List<double[]> points = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("DATA")) {
break;
}
}
while ((line = reader.readLine()) != null) {
double[] point = new double[3];
String[] values = line.split(" ");
point[0] = Double.parseDouble(values[0]);
point[1] = Double.parseDouble(values[1]);
point[2] = Double.parseDouble(values[2]);
points.add(point);
}
}
return points;
}
private static List<double[]> readBinaryPCD(String filePath) throws IOException {
List<double[]> points = new ArrayList<>();
try (FileInputStream fis = new FileInputStream(filePath)) {
ByteBuffer buffer = ByteBuffer.wrap(fis.readAllBytes());
buffer.order(ByteOrder.LITTLE_ENDIAN);
// Skip header (assuming header size is known, or read until DATA section)
// This example assumes 11 lines of header, which may vary
for (int i = 0; i < 11; i++) {
while (buffer.get() != '\n') {
// Skip header lines
}
}
// Read binary data
while (buffer.hasRemaining()) {
double x = buffer.getFloat();
double y = buffer.getFloat();
double z = buffer.getFloat();
int rgb = buffer.getInt(); // Read 4 bytes for RGB
double[] point = {x, y, z};
points.add(point);
}
} catch (Exception e) {
return null;
}
return points;
}
static void getPCDArray(String filePath) {
}
static void getPCDArray(Map<Double, Map<Double, Double>> clippedPoint, String filePath) {
// 创建一个DecimalFormat对象指定格式
DecimalFormat df = new DecimalFormat("#.####");
File file = new File(filePath + ".txt");
file.delete();
try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath + ".txt"))) {
bw.write("[");
for (Double x : clippedPoint.keySet()) {
for (Double y : clippedPoint.get(x).keySet()) {
double z = clippedPoint.get(x).get(y);
bw.write("[" + df.format(x) + ", " + df.format(y) + ", " + df.format(z) + "],\n");
}
}
bw.write("]");
} catch (IOException e) {
e.printStackTrace();
}
// 读取点云数据
}
public static double[] rotatePoints(double[] point, double[][] rotationMatrix) {
double x = point[0];
double y = point[1];
double z = point[2];
double[] rotatedPoint = new double[3];
rotatedPoint[0] = rotationMatrix[0][0] * x + rotationMatrix[0][1] * y + rotationMatrix[0][2] * z;
rotatedPoint[1] = rotationMatrix[1][0] * x + rotationMatrix[1][1] * y + rotationMatrix[1][2] * z;
rotatedPoint[2] = rotationMatrix[2][0] * x + rotationMatrix[2][1] * y + rotationMatrix[2][2] * z;
return rotatedPoint;
}
//
// public static List<double[]> clipPoints(List<double[]> points, double[] minBounds, double[] maxBounds) {
// List<double[]> clippedPoints = new ArrayList<>();
// for (double[] point : points) {
// if (point[0] >= minBounds[0] && point[0] <= maxBounds[0] &&
// point[1] >= minBounds[1] && point[1] <= maxBounds[1] &&
// point[2] >= minBounds[2] && point[2] <= maxBounds[2]) {
// clippedPoints.add(point);
// }
// }
// return clippedPoints;
// }
public static boolean clipPoints(double[] point, double[] minBounds, double[] maxBounds) {
return point[0] >= minBounds[0] && point[0] <= maxBounds[0] && //x轴截取
point[1] >= minBounds[1] && point[1] <= maxBounds[1] && //y轴截取
point[2] >= minBounds[2] && point[2] <= maxBounds[2];
}
public static void writePCD(List<double[]> points, String filePath) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) {
bw.write("# .PCD v0.7 - Point Cloud Data file format\n");
bw.write("VERSION 0.7\n");
bw.write("FIELDS x y z\n");
bw.write("SIZE 4 4 4\n");
bw.write("TYPE F F F\n");
bw.write("COUNT 1 1 1\n");
bw.write("WIDTH " + points.size() + "\n");
bw.write("HEIGHT 1\n");
bw.write("VIEWPOINT 0 0 0 1 0 0 0\n");
bw.write("PIXEL_FORMAT ascii\n");
bw.write("DATA ascii\n");
for (double[] point : points) {
bw.write(point[0] + " " + point[1] + " " + point[2] + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
*
* @param pojo
*/
List<double[]> slicing(PcdPojo pojo){
// 计算pcd1
List<double[]> points = readPCD(pojo.getPcd1());
if (points == null || points.isEmpty()) {
return points;
}
//map xyz
List<double[]> clippedPoint = points.stream()
.map(point -> {
//旋转
return rotatePoints(point, pojo.getRotationMatrix());
})
.filter(point ->
//截取
clipPoints(point, pojo.getMinBounds(), pojo.getMaxBounds())
)
//z轴截取
.collect(Collectors.toList());
return clippedPoint;
}
public static void main(String[] args) {
LxPointCloudSaveImage.saveImage("192.168.1.82","E:\\1.pcd",1);
PcdPojo pojo = new PcdPojo();
pojo.setPcd1("E:/1.pcd");
pojo.setConfigPath("E:\\pe.json");
try {
pojo.setPCDInfo(pojo);
} catch (IOException e) {
throw new RuntimeException(e);
}
PointCloudProcessor pointCloudProcessor = new PointCloudProcessor();
List<BoxPositionConf> confs = pointCloudProcessor.getBoxPositionConf("E:\\peconf.json");
int i = pointCloudProcessor.slicing(pojo,confs);
System.out.println(pojo.toString());
System.out.println(i);
}
/**
*
* @param pojo
*/
public int slicing(PcdPojo pojo, List<BoxPositionConf> boxPositionConfs){
// 计算pcd1
List<double[]> points = readPCD(pojo.getPcd1());
if (points == null || points.isEmpty()) {
}
Map<Integer,Integer> map = new HashMap<>();
//map xyz
List<double[]> clippedPoint = points.stream()
.map(point -> {
//旋转
return rotatePoints(point, pojo.getRotationMatrix());
})
.filter(point ->
//截取
clipPoints(point, pojo.getMinBounds(), pojo.getMaxBounds())
)
.peek(v->{
for (int i = 0; i < boxPositionConfs.size(); i++){
if (boxPositionConfs.get(i).getHeight()>v[2]-50&&boxPositionConfs.get(i).getHeight()<v[2]+50){
for (int j = 0; j < boxPositionConfs.get(i).getPosition().size(); j++){
if (boxPositionConfs.get(i).getPosition().get(j)[0]<v[0]
&&boxPositionConfs.get(i).getPosition().get(j)[1]>v[0]
&&boxPositionConfs.get(i).getPosition().get(j)[2]>v[1]
&&boxPositionConfs.get(i).getPosition().get(j)[3]<v[1]){
int position = j+1+i*boxPositionConfs.get(i).getPosition().size();
map.put(position,map.getOrDefault(position,0)+1);
}
}
}
}
})
//z轴截取
.collect(Collectors.toList());
int count = 0;
for (Integer integer : map.values()){
if (integer>200){
count +=1;
}
}
return count;
}
public List<BoxPositionConf> getBoxPositionConf(String path){
//读取点云位置
ObjectMapper mapper = new ObjectMapper();
List<BoxPositionConf> boxPositionConfs =null;
try {
// 读取 JSON 文件并转换为 配置信息
boxPositionConfs = mapper.readValue(new File(path), mapper.getTypeFactory().constructCollectionType(List.class,BoxPositionConf.class));
// 打印转换后的实体类列表
//报错则认为没有配置文件,返回盘点失败
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return boxPositionConfs;
}
}

@ -23,9 +23,11 @@ import com.zhehekeji.web.service.ksec.KsecInfo;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.nio.CharBuffer;
@ -385,10 +387,6 @@ public class PlcService {
}
}
public static void main(String[] args) {
System.out.println("330101".length() != 6);
}
/**
*
@ -755,20 +753,21 @@ public class PlcService {
public void visualCalculationResults(TransmissionPojo transmissionPojo) {
//获取个数
int count = sendHttp(transmissionPojo.getStreetNumber());
CheckLog checkLog = checkLogMapper.selectById(transmissionPojo.getCheckId());
Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("check_Num", checkLog.getId()));
Street street = streetService.getStreetByPlcId(transmissionPojo.getStreetNumber());
if( stock.getCategory() != null && "20".equals(stock.getCategory())) {
checkLog.setStatus(StockStatus.OTHER.getStatus());
stock.setStatus(StockStatus.OTHER.getStatus());
}else if (transmissionPojo.getResult() != null && transmissionPojo.getResult() == 1) {
}else if (!"0".equals(transmissionPojo.getCategory()) && stock.getCount() == count){
checkLog.setStatus(StockStatus.SUCCESS.getStatus());
stock.setStatus(StockStatus.SUCCESS.getStatus());
} else {
checkLog.setStatus(StockStatus.ERROR.getStatus());
stock.setStatus(StockStatus.ERROR.getStatus());
stock.setCount(transmissionPojo.getCount());
stock.setCategory(transmissionPojo.getCategory());
stock.setCount(count);
}
if (transmissionPojo.getPcd() != null && !"".equals(transmissionPojo.getPcd())) {
@ -786,6 +785,43 @@ public class PlcService {
stockMapper.updateById(stock);
}
public int sendHttp(String streetNumber){
Street street = streetService.getStreetByPlcId(streetNumber);
// 创建 RestTemplate 实例
RestTemplate restTemplate = new RestTemplate();
// 定义 URL
String url = "http://"+street.getPlcIp()+":8097/category/getBoxCount";
// 发起 GET 请求
ResponseEntity<Integer> response = restTemplate.getForEntity(url, Integer.class);
// 输出响应状态码和响应体
System.out.println("Status Code: " + response.getStatusCode());
return response.getBody();
}
public int sendHttp(){
// 创建 RestTemplate 实例
RestTemplate restTemplate = new RestTemplate();
// 定义 URL
String url = "http://"+"127.0.0.1"+":8097/category/getBoxCount";
// 发起 GET 请求
ResponseEntity<Integer> response = restTemplate.getForEntity(url, Integer.class);
// 输出响应状态码和响应体
System.out.println("Status Code: " + response.getStatusCode());
return response.getBody();
}
public static void main(String[] args) {
PlcService plcService = new PlcService();
System.out.println(plcService.sendHttp());
}
public static String join(String[] array, String separator) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length; i++) {

@ -17,6 +17,8 @@ import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.util.List;
@ -125,12 +127,14 @@ public class Decoder extends DelimiterBasedFrameDecoder {
}
//照片和结果保存,并发送给上位机
else if(RETURN_CHECK.equals(transmissionPojo.getHeader())){
//保存数据
//保存数据
plcService.visualCalculationResults(transmissionPojo);
//发送给上位机
KsecInfo ksecInfo = plcService.getKsecDataInfo(transmissionPojo,"E");
ksecInfo.getData().setTypeNum(transmissionPojo.getCategory());
ksecInfo.getData().setQuantity(transmissionPojo.getCount());
//ksecInfo.getData().setQuantity(transmissionPojo.getCount());
ksecInfo.getData().setCheckRlt(transmissionPojo.getResult());
KsecNettyClient.write(ksecInfo);
GetPhotoDelayExecutor.removeTask(transmissionPojo.getStreetNumber(), transmissionPojo);

Loading…
Cancel
Save