C#实现图像中白色及相近色调矩形检测的技术需求
C# 检测图像白色矩形并生成TableLayout面板方案
一、识别白色及相近色调区域
先定义“白色相近色调”的判断规则,推荐两种方式:
- RGB阈值法:白色RGB为(255,255,255),设定容差(比如20),只要像素的R/G/B分量都在[255-容差, 255]区间内,就判定为目标区域。
- HSV亮度法:将RGB转HSV后,取亮度通道值(范围0-100),只要亮度>90%,就判定为接近白色,这种方式对光照变化适应性更强。
用System.Drawing实现的基础检测代码:
int whiteTolerance = 20; Bitmap targetImage = new Bitmap("你的图片路径"); bool[,] isWhitePixel = new bool[targetImage.Width, targetImage.Height]; for (int x = 0; x < targetImage.Width; x++) { for (int y = 0; y < targetImage.Height; y++) { Color pixel = targetImage.GetPixel(x, y); // RGB阈值判断 bool isWhite = (pixel.R >= 255 - whiteTolerance) && (pixel.G >= 255 - whiteTolerance) && (pixel.B >= 255 - whiteTolerance); isWhitePixel[x, y] = isWhite; } }
二、提取白色矩形区域
得到白色像素矩阵后,需要提取连通的矩形区域,推荐用OpenCVSharp简化开发(也可以自己实现区域生长算法,但效率较低):
- 将布尔矩阵转为灰度图,白色区域设为255,其余为0。
- 调用轮廓检测接口找到所有白色连通区域。
- 对每个轮廓计算最小外接矩形,过滤掉面积过小的噪点区域。
示例代码:
// 转换为OpenCV的Mat格式 Mat grayMat = new Mat(targetImage.Height, targetImage.Width, MatType.CV_8UC1); for (int x = 0; x < targetImage.Width; x++) { for (int y = 0; y < targetImage.Height; y++) { grayMat.Set<byte>(y, x, isWhitePixel[x, y] ? (byte)255 : (byte)0); } } // 查找轮廓 List<Point[]> contours = new List<Point[]>(); Cv2.FindContours(grayMat, contours, null, RetrievalMode.External, ContourApproximationMode.ApproxSimple); // 提取有效矩形 List<Rectangle> whiteRects = new List<Rectangle>(); foreach (var contour in contours) { Rect rect = Cv2.BoundingRect(contour); // 过滤小区域,阈值根据实际图像调整 if (rect.Area() > 500) { whiteRects.Add(new Rectangle(rect.X, rect.Y, rect.Width, rect.Height)); } }
三、映射矩形到TableLayout控件
根据提取的矩形排列规律,动态生成TableLayout的面板:
- 按矩形的Y坐标分组(同一行的Y值相近),每组内按X坐标排序(从左到右排列)。
- 设置TableLayout的行列数,按矩形尺寸设置行列的自适应样式。
- 遍历每个矩形,创建Panel控件并添加到对应单元格。
示例代码:
// 按Y坐标分组,10为分组阈值,可根据实际调整 var rowGroups = whiteRects.GroupBy(r => r.Y / 10) .OrderBy(g => g.Key) .ToList(); tableLayoutPanel1.RowCount = rowGroups.Count; tableLayoutPanel1.ColumnCount = rowGroups.Max(g => g.Count); // 配置行列样式并添加面板 for (int rowIndex = 0; rowIndex < rowGroups.Count; rowIndex++) { tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize)); var sortedRects = rowGroups[rowIndex].OrderBy(r => r.X).ToList(); for (int colIndex = 0; colIndex < sortedRects.Count; colIndex++) { if (colIndex >= tableLayoutPanel1.ColumnStyles.Count) { tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize)); } Panel panel = new Panel(); panel.BackColor = Color.LightGray; // 模拟白色矩形区域 panel.Size = new Size(sortedRects[colIndex].Width, sortedRects[colIndex].Height); tableLayoutPanel1.Controls.Add(panel, colIndex, rowIndex); } }
注意事项
- 容差、面积过滤阈值需要根据实际图像调整,避免误识别。
- 若不用OpenCVSharp,可自行实现区域生长算法,但仅适合小尺寸图像。
- 若矩形排列不规则,需额外处理行列对齐逻辑,比如按最大行宽、最大列高统一尺寸。
内容的提问来源于stack exchange,提问作者Gokhan
相关产品推荐
相关产品推荐

