我正在尝试编写一个函数,该函数将使用 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;
}
您可以使用 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
抱歉,我不知道 Magick.NET。但您可以通过 https://imagemagick.org/discourse-server/viewforum.php?f=27 或 https://github.com/dlemstra/Magick 与 Magick.NET 开发人员讨论。网
你可以使用 Emgu CV 来做到这一点。按照以下步骤分别识别表格中的每个单元格。
var image = new Image<Bgr, byte>("myimage.png");
var gray = image.Convert<Gray, byte>();
var binary = gray.ThresholdBinary(new Gray(100), new Gray(155));
var cells = new List<Rectangle>();
var contours = new VectorOfVectorOfPoint();
CvInvoke.FindContours(binary, contours, null, RetrType.List,ChainApproxMethod.ChainApproxSimple);
//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);
}
}
}
if (cells.Count > 0)
{
foreach (var rect in cells)
{
image.Draw(rect, new Bgr(System.Drawing.Color.Brown),3);
}
}
CvInvoke.Imshow("Table Cells", image);
然后您可以使用相关的 OCR 库扫描单个单元格中的文本,并根据需要在程序中使用它们。