计算面积来计算个数

泸州-视觉+扫码-昆船
LAPTOP-S9HJSOEB\昊天 10 months ago
parent 7608cc675f
commit 05ecb74903

@ -159,6 +159,9 @@ public class IndustrialCameraController {
break;
}
}
if(pa.equals("")){
pa = listResult.getData().get(0);
}
//3d pcd保存
LocalDate currentDate = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

@ -0,0 +1,80 @@
package com.zhehekeji.web.service.algorithm;
import java.util.*;
import java.util.*;
public class IntervalPolygonArea {
public static double calculateArea(List<double[]> points,double xMin, double interval) {
if (points == null || points.isEmpty() || interval <= 0) return 0;
// 分组统计每个区间的 minY 和 maxY
Map<Integer, MinMax> stats = new HashMap<>();
for (double[] point : points) {
double x = point[0];
int group = (int) Math.floor((x - xMin) / interval);
stats.computeIfAbsent(group, k -> new MinMax()).add(point[1]);
}
if (stats.isEmpty()) return 0;
// 构造上、下轮廓点
List<double[]> upperContour = new ArrayList<>();
List<double[]> lowerContour = new ArrayList<>();
for (Map.Entry<Integer, MinMax> entry : stats.entrySet()) {
int group = entry.getKey();
double xCenter = xMin + group * interval + interval / 2;
double minY = entry.getValue().min;
double maxY = entry.getValue().max;
upperContour.add(new double[]{xCenter, maxY});
lowerContour.add(new double[]{xCenter, minY});
}
// 将下轮廓反转后合并到上轮廓,形成闭合多边形
Collections.sort(upperContour, Comparator.comparingDouble(p -> p[0]));
Collections.sort(lowerContour, Comparator.comparingDouble(p -> p[0]));
Collections.reverse(lowerContour);
List<double[]> polygon = new ArrayList<>(upperContour);
polygon.addAll(lowerContour);
// 如果只有一两个点,无法构成多边形
if (polygon.size() < 3) return 0;
// 计算面积
return polygonArea(polygon);
}
private static class MinMax {
double min = Double.POSITIVE_INFINITY;
double max = Double.NEGATIVE_INFINITY;
void add(double value) {
min = Math.min(min, value);
max = Math.max(max, value);
}
}
// 多边形面积公式Shoelace
private static double polygonArea(List<double[]> polygon) {
double area = 0;
int n = polygon.size();
for (int i = 0; i < n; i++) {
double[] p1 = polygon.get(i);
double[] p2 = polygon.get((i + 1) % n);
area += (p1[0] * p2[1] - p2[0] * p1[1]);
}
return Math.abs(area) / 2.0;
}
// 示例主函数
public static void main(String[] args) {
}
}

@ -31,11 +31,13 @@ public class PcdPojo {
private Integer count;
private int width;
private int[] height;
private int high;
private int length;
private String arrangeType;
PcdPojo setPCDInfo(PcdPojo pojo) {
this.setMinBounds(pojo.getMin_pt());
this.setMaxBounds(pojo.getMax_pt());
this.floorHeight = pojo.getFloorHeight();
double[] x = {pojo.getRotation()[0], pojo.getRotation()[1], pojo.getRotation()[2]};
double[] y = {pojo.getRotation()[3], pojo.getRotation()[4], pojo.getRotation()[5]};
double[] z = {pojo.getRotation()[6], pojo.getRotation()[7], pojo.getRotation()[8]};

@ -391,32 +391,32 @@ public class PointCloudProcessor {
int horizontalCount;//横向个数
int longitudinalCount;
}
public static void main(String[] args) {
// List<double[]> points = readPCD("E:\\泸州\\c88165e7-9ea6-493e-9130-e74342e5b639--192.168.40.11.pcd");
// PcdPojo pojo = new PcdPojo();
// pojo.setConfigPath("E:\\26.json");
// ObjectMapper mapper = new ObjectMapper();
// PcdPojo pcdPojo
// try {
// // 读取 JSON 文件并转换为 配置信息
// pcdPojo = mapper.readValue(new File("E:\\1.txt"), mapper.getTypeFactory().constructType(PcdPojo.class));
// // 打印转换后的实体类列表
// pojo = pojo.setPCDInfo(pojoIn);
// //报错则认为没有配置文件,返回盘点失败
// } catch (JsonMappingException e) {
// e.printStackTrace();
//
// } catch (JsonProcessingException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// public static void main(String[] args) {
//// List<double[]> points = readPCD("E:\\泸州\\c88165e7-9ea6-493e-9130-e74342e5b639--192.168.40.11.pcd");
//// PcdPojo pojo = new PcdPojo();
//// pojo.setConfigPath("E:\\26.json");
//// ObjectMapper mapper = new ObjectMapper();
//// PcdPojo pcdPojo
//// try {
//// // 读取 JSON 文件并转换为 配置信息
//// pcdPojo = mapper.readValue(new File("E:\\1.txt"), mapper.getTypeFactory().constructType(PcdPojo.class));
//// // 打印转换后的实体类列表
//// pojo = pojo.setPCDInfo(pojoIn);
//// //报错则认为没有配置文件,返回盘点失败
//// } catch (JsonMappingException e) {
//// e.printStackTrace();
////
//// } catch (JsonProcessingException e) {
//// e.printStackTrace();
//// } catch (IOException e) {
//// e.printStackTrace();
//// }
// getBaijiuBox("E:\\泸州\\5a11d221-268a-4ed6-ad50-446fa481a56e--192.168.40.11.pcd" ,"E:\\26.json","E:\\1.txt");
// {//getLongitudinalType(points, pojo, pcdPojo.getWidth(), pcdPojo.getLength(), pcdPojo.getHeight(),pcdPojo.getArrangeType());
// //getLongitudinalType(points, pojo, 350, 297, new int[]{2443,2142,1750, 1420},"3w 4h 4h");
// }
// }
getBaijiuBox("E:\\泸州\\5a11d221-268a-4ed6-ad50-446fa481a56e--192.168.40.11.pcd" ,"E:\\26.json","E:\\1.txt");
{//getLongitudinalType(points, pojo, pcdPojo.getWidth(), pcdPojo.getLength(), pcdPojo.getHeight(),pcdPojo.getArrangeType());
//getLongitudinalType(points, pojo, 350, 297, new int[]{2443,2142,1750, 1420},"3w 4h 4h");
}
}
static int getBaijiuBox(String path,String configPath,String typeConfPath){
List<double[]> points = readPCD(path);
PcdPojo pojo = new PcdPojo();
@ -442,7 +442,7 @@ public class PointCloudProcessor {
e.printStackTrace();
}
return getLongitudinalType(points, pojo, pcdPojo.getWidth(), pcdPojo.getLength(), pcdPojo.getHeight(),pcdPojo.getArrangeType());
return getLongitudinalType(points, pojo, pcdPojo.getWidth(), pcdPojo.getLength(), pcdPojo.getHigh(),pcdPojo.getArrangeType());
}
@ -605,6 +605,118 @@ public class PointCloudProcessor {
//计算相似度
return (int) count;
}
//采用计算面积方式来计算个数
/**
*
* @param points
* @param pojo
* @param l
* @param w
* @param height
* @param type
* @return
*/
private static int getLongitudinalType(List<double[]> points, PcdPojo pojo, int l, int w, int height,String type){
//pojo里面的floorHeight为地板的值以后所有的height都将根据地板值进行计算地板值减去当前点的z轴值为高度且当为height的倍数的时候认为是有效的点其中1倍的冗余在50mm每高一层冗余增加20mm
// 计算
double baseTolerance = 50; // 初始冗余 50mm
double additionalTolerancePerLevel = 20; // 每层增加 20mm 冗余
Map<Integer, List<double[]>> map = new HashMap<>();
points = points.stream()
.filter(point -> clipPoints(point, pojo.getMinBounds(), pojo.getMaxBounds()))
.filter(point -> {
// 计算当前点的高度(地板值减去 z 轴值)
double currentHeight = pojo.getFloorHeight() - point[2];
// 确保高度为正值
if (currentHeight < 0) {
return false;
}
// 计算当前高度是 height 的几倍
int level = (int) Math.round(currentHeight / height);
// 计算允许的冗余范围
double tolerance = baseTolerance + level * additionalTolerancePerLevel;
// 判断当前高度是否在允许的范围内
if (Math.abs(currentHeight - level * height) <= tolerance) {
if (!map.containsKey(level)) {
map.put(level, new ArrayList<>());
}
map.get(level).add(point);
return true;
}else return false;
})
.peek(point -> point[2] = pojo.getFloorHeight() - point[2])
.collect(Collectors.toList());
String[] types = type.split(" ");
int layersCount = 0;
//计算最大值
for (String s : types){
if (s.endsWith("w")){
int maxW= Integer.parseInt(s.substring(0,1));
layersCount +=maxW;
}else if (s.endsWith("h")){
int maxL= Integer.parseInt(s.substring(0,1));
layersCount +=maxL;
}
}
for (int h =5; h>0; h--){
if (map.containsKey(h) && map.get(h).size()>500){
double area =IntervalPolygonArea.calculateArea(map.get(h),pojo.minBounds[0],10);
if (area>0){
int i =(layersCount*(h-1))+(int) Math.round(area/(double) (l*w));
return i;
}
break;
}
}
return 0;
}
public static void main(String[] args) {
String path ="E:\\工作\\泸州测试\\2025-05-12\\7d5a619e-190d-4e7d-95a9-1e47aa49eef8--192.168.48.11.pcd";
String configPath = "E:\\工作\\泸州测试\\27.json";
String typeConfPath = "E:\\工作\\泸州测试\\temlent\\40014847.json";
List<double[]> points = readPCD(path);
PcdPojo pojo = new PcdPojo();
PcdPojo pcdPojo = new PcdPojo();
pojo.setConfigPath(configPath);
ObjectMapper mapper = new ObjectMapper();
try {
// 读取 JSON 文件并转换为 配置信息
PcdPojo pojoIn = mapper.readValue(new File(pojo.getConfigPath()), mapper.getTypeFactory().constructType(PcdPojo.class));
// 打印转换后的实体类列表
pojo = pojo.setPCDInfo(pojoIn);
// 读取 JSON 文件并转换为 配置信息
pcdPojo = mapper.readValue(new File(typeConfPath), mapper.getTypeFactory().constructType(PcdPojo.class));
//报错则认为没有配置文件,返回盘点失败
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int i = getLongitudinalType(points,pojo, pcdPojo.getWidth(), pcdPojo.getLength(), pcdPojo.getHigh(),pcdPojo.getArrangeType());
System.out.println(i);
}
static int getTopCount(List<double[]> points, PcdPojo pojo, int l, int w,Map<Integer, In> map ,int minIndex,int maxIndex,int maxW,int maxL,int h){
int count = 0;
//列相等

Loading…
Cancel
Save