使用 C# 在图像中查找表

问题描述 投票:0回答:2

我正在尝试编写一个函数,该函数将使用 EMGU.CV 或 Magick.Net 或 AForge.Net 拍摄图像并返回给我仅包含表格的图像列表 例如,对于下图,该函数应返回 2 张图像,其中包含图像中的两个表格。

private static List<Image> FindTables(Image img)
{
    var masterImage = (Bitmap)img;
    var image = new Image<Gray, byte>(masterImage);
    var copyImg = new Image<Bgr, byte>(masterImage);
    List<Image> tables = new List<Images>
    //Find all tables and add to tables variable
    return tables;
}

c# imagemagick emgucv aforge magick.net
2个回答
3
投票

您可以使用 Imagemagick 中的连接组件来做到这一点。过滤掉所有小区域,即文本字符,只留下较大的表格轮廓。然后获取表格的边界框并使用它们来裁剪原始图像。设置 area-threshold 使得表格的行中的像素数大于阈值,而其他所有内容都小于阈值。 (Unix 语法)

输入:

IFS=" "
OLDIFS=$IFS
IFS=$'\n'
bboxArr=(`convert image.png -alpha off -type bilevel \
-define connected-components:verbose=true \
-define connected-components:area-threshold=500 \
-connected-components 4 \
null: | grep "gray(0)" | awk '{print $2}'`)
num=${#bboxArr[*]}
IFS=$OLDIFS
for ((i=0; i<num; i++)); do
convert image.png -crop ${bboxArr[$i]} +repage image$i.png
done

[![在此处输入图片描述][2]][2]

抱歉,我不知道 Magick.NET。但您可以通过 https://imagemagick.org/discourse-server/viewforum.php?f=27https://github.com/dlemstra/Magick 与 Magick.NET 开发人员讨论。网


0
投票

你可以使用 Emgu CV 来做到这一点。按照以下步骤分别识别表格中的每个单元格。

  1. 将输入图像加载到 Emgu CV 结构中
var image = new Image<Bgr, byte>("myimage.png");
  1. 将图像转换为灰度
var gray = image.Convert<Gray, byte>();
  1. 对灰度图像应用二值阈值
var binary = gray.ThresholdBinary(new Gray(100), new Gray(155));
  1. 定义一个列表来保存在图像上找到的所有表格单元格
var cells = new List<Rectangle>();
  1. 读取图像中的所有轮廓
 var contours = new VectorOfVectorOfPoint();
 CvInvoke.FindContours(binary, contours, null, RetrType.List,ChainApproxMethod.ChainApproxSimple);
  1. 通过过滤掉那些太小的(即文本)并使用纵横比检查轮廓的形状来迭代轮廓以找到表格的单元格
//filter out text contours by checking the size
for (int i = 0; i < contours.Size; i++)
{
    //get the area of the contour
    var area = CvInvoke.ContourArea(contours[i]);
    //filter out text contours using the area
    if (area > 2000 && area < 200000)
     {
       //check if the shape of the contour is a square or a rectangle
       var rect = CvInvoke.BoundingRectangle(contours[i]);
       var aspectRatio = (double)rect.Width / rect.Height;
       if (aspectRatio > 0.5 && aspectRatio <= 5)
          {
              //add the cell to the list
              cells.Add(rect);
           }
      }
 }
  1. 使用您选择的颜色在图像上绘制单元格,我使用棕色来突出显示单元格
 if (cells.Count > 0)
    {
       foreach (var rect in cells)
        {
          image.Draw(rect, new Bgr(System.Drawing.Color.Brown),3);
        }
     }
  1. 显示突出显示单元格的图像。
CvInvoke.Imshow("Table Cells", image);

然后您可以使用相关的 OCR 库扫描单个单元格中的文本,并根据需要在程序中使用它们。

© www.soinside.com 2019 - 2024. All rights reserved.