找回密码
 立即注册
首页 业界区 业界 OpenCvSharp基于颜色反差规避FBA面单贴标

OpenCvSharp基于颜色反差规避FBA面单贴标

谯梨夏 2025-9-19 00:00:50
01
规避原理
1.抠图,根据色差或者根据固定包裹位置以及包裹尺寸抠出纸箱图片
2.色差,获取纸箱上所有背景色的灰度值
3.采图,采集大量视野相同,光源相同面单的色差灰度值,整理区间
4.取反,所有非面单灰度值区间的,都认为是纸箱背景色
02

  • 根据DPI计算1mm对应像素点。
  • 获取吸取的颜色,计算灰度值
 
  1. // 300 DPI 计算:每毫米像素数 = 300 / 25.4 ≈ 11.81
  2. private const double PixelsPerMm = 300.0 / 25.4 ;
  3. private static int LabelSizePixels = Convert.ToInt32(Math.Ceiling((int)(95 * PixelsPerMm) / 1.7)); // 100mm × 100mm

  4. // 面单颜色列表(十六进制格式)
  5. private static readonly List<string> LabelColors = new List<string>
  6. {
  7.         "#E2E2E0", "#DEDEDC", "#E0E0DE", "#CCCCCA", "#B2B2B0", "#C2C2C0","#FFFFFF","#FEFEFE","#FCFCFC" ,"#ADADAD"
  8. };

  9. // 计算出的面单灰度范围
  10. private static int MinLabelGray;
  11. private static int MaxLabelGray;
复制代码
  1. // 加载图像
  2. var originalImage = Cv2.ImRead(@"D:\Users\steph\Pictures\1分4\Image_20250913210539498.jpg", OpenCvSharp.ImreadModes.Grayscale);

  3. // 计算面单灰度范围
  4. CalculateLabelGrayRange();
  5. Console.WriteLine($"计算出的面单灰度范围: {MinLabelGray}-{MaxLabelGray}");


  6. if (originalImage.Empty())
  7. {
  8.         Console.WriteLine("无法加载图像");
  9.         return;
  10. }
复制代码
此处用第二种最简单方式演示,视野固定包裹位置,根据计算包裹的尺寸,扣除原箱外观
  1. // 从右下角裁剪图像
  2. private static OpenCvSharp.Mat CropImageFromBottomRight(OpenCvSharp.Mat image, double widthMm, double heightMm)
  3. {
  4.         // 将毫米转换为像素
  5.         int widthPixels = (int)(widthMm * PixelsPerMm/1.7);
  6.         int heightPixels = (int)(heightMm * PixelsPerMm/1.7);

  7.         // 获取图像尺寸
  8.         int imgWidth = image.Cols;
  9.         int imgHeight = image.Rows;

  10.         // 计算裁剪区域的左上角坐标
  11.         int x = Math.Max(0, imgWidth - widthPixels);
  12.         int y = Math.Max(0, imgHeight - heightPixels);

  13.         // 确保裁剪区域不超出图像边界
  14.         widthPixels = Math.Min(widthPixels, imgWidth - x);
  15.         heightPixels = Math.Min(heightPixels, imgHeight - y);

  16.         // 检查裁剪区域是否有效
  17.         if (widthPixels <= 0 || heightPixels <= 0)
  18.         {
  19.                 Console.WriteLine($"无效的裁剪区域: x={x}, y={y}, width={widthPixels}, height={heightPixels}");
  20.                 return image.Clone(); // 返回原始图像的副本
  21.         }

  22.         Console.WriteLine($"裁剪区域: x={x}, y={y}, width={widthPixels}, height={heightPixels}");

  23.         // 裁剪图像
  24.         return new OpenCvSharp.Mat(image, new Rect(x, y, widthPixels, heightPixels));
  25. }
复制代码
检查可贴标签位置是否与原厂标签有交集,检查可贴区域是否超过原箱尺寸,此处我们以新帖面单大小100mm*100mm为例。没有可贴标签位置默认选择1-1位置贴标
  1. // 检测所有原厂面单位置
  2. public static List<LabelPosition> DetectOriginalLabelPositions(OpenCvSharp.Mat image)
  3. {
  4.         var labelPositions = new List<LabelPosition>();

  5.         // 二值化图像以分离面单区域
  6.         var binary = new OpenCvSharp.Mat();
  7.         Cv2.Threshold(image, binary, MinLabelGray, 255, ThresholdTypes.Binary);

  8.         // 形态学操作去除噪声
  9.         var kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
  10.         Cv2.MorphologyEx(binary, binary, MorphTypes.Open, kernel);

  11.         // 查找轮廓
  12.         Cv2.FindContours(binary, out var contours, out _, RetrievalModes.External, ContourApproximationModes.ApproxSimple);

  13.         // 过滤轮廓(按面积)
  14.         var filteredContours = contours.Where(c => Cv2.ContourArea(c) > 1000).ToList();

  15.         // 处理每个轮廓
  16.         foreach (var contour in filteredContours)
  17.         {
  18.                 // 获取轮廓的边界矩形
  19.                 var rect = Cv2.BoundingRect(contour);

  20.                 // 转换为网格坐标
  21.                 string gridCoordinate = ConvertToGridCoordinate(rect, image.Rows, image.Cols);

  22.                 // 计算实际尺寸(毫米)
  23.                 double widthMm = rect.Width / PixelsPerMm;
  24.                 double heightMm = rect.Height / PixelsPerMm;

  25.                 // 添加到结果列表
  26.                 labelPositions.Add(new LabelPosition
  27.                 {
  28.                         Rect = rect,
  29.                         GridCoordinate = gridCoordinate,
  30.                         WidthMm = widthMm,
  31.                         HeightMm = heightMm
  32.                 });
  33.         }

  34.         return labelPositions;
  35. }
复制代码
可视化结果,以绿色网格铺满原箱,以红色区域标定原厂标签位置,以蓝色网格标定可贴标签位置,返回可视化结果
  1. // 检测所有原厂面单位置
  2. public static List<LabelPosition> DetectOriginalLabelPositions(OpenCvSharp.Mat image)
  3. {
  4.         var labelPositions = new List<LabelPosition>();

  5.         // 二值化图像以分离面单区域
  6.         var binary = new OpenCvSharp.Mat();
  7.         Cv2.Threshold(image, binary, MinLabelGray, 255, ThresholdTypes.Binary);

  8.         // 形态学操作去除噪声
  9.         var kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
  10.         Cv2.MorphologyEx(binary, binary, MorphTypes.Open, kernel);

  11.         // 查找轮廓
  12.         Cv2.FindContours(binary, out var contours, out _, RetrievalModes.External, ContourApproximationModes.ApproxSimple);

  13.         // 过滤轮廓(按面积)
  14.         var filteredContours = contours.Where(c => Cv2.ContourArea(c) > 1000).ToList();

  15.         // 处理每个轮廓
  16.         foreach (var contour in filteredContours)
  17.         {
  18.                 // 获取轮廓的边界矩形
  19.                 var rect = Cv2.BoundingRect(contour);

  20.                 // 转换为网格坐标
  21.                 string gridCoordinate = ConvertToGridCoordinate(rect, image.Rows, image.Cols);

  22.                 // 计算实际尺寸(毫米)
  23.                 double widthMm = rect.Width / PixelsPerMm;
  24.                 double heightMm = rect.Height / PixelsPerMm;

  25.                 // 添加到结果列表
  26.                 labelPositions.Add(new LabelPosition
  27.                 {
  28.                         Rect = rect,
  29.                         GridCoordinate = gridCoordinate,
  30.                         WidthMm = widthMm,
  31.                         HeightMm = heightMm
  32.                 });
  33.         }

  34.         return labelPositions;
  35. }
复制代码
看看效果1,运行看看效果.(如下图纸箱长400,高190)白色原厂面单占据了前面6个网格,最后两个网格超过原箱尺寸无效,默认返回第一个网格(视情况自定义)
1.png

保持期待 奔赴山海KEEP LOOKING FORWARD TO GOING效果2.原厂标签占据第一个和中间4个网格,可贴标签区域蓝色网格标识,并返回可贴坐标
2.png

 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册