【发布时间】:2020-11-02 01:53:02
【问题描述】:
我有一个应用程序将用于从扫描的文档中裁剪空格,例如this image。我想要做的是只提取卡片并删除所有白色/空白区域。我正在使用 Emgucv FindContours 来执行此操作,目前我能够在图像中找到卡片轮廓和扫描仪捕获的一些噪点,如下所示。
我的问题是如何裁剪找到的最大轮廓或如何通过删除其他轮廓和空白/空白来提取它?或者也许可以使用轮廓索引?
编辑:也许另一种可能的解决方案是将轮廓绘制到另一个图片框。
这是我正在使用的代码:
Image<Bgr, byte> imgInput;
Image<Bgr, byte> imgCrop;
private void abrirToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() ==DialogResult.OK)
{
imgInput = new Image<Bgr, byte>(dialog.FileName);
pictureBox1.Image = imgInput.Bitmap;
imgCrop = imgInput;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void shapeToolStripMenuItem_Click(object sender, EventArgs e)
{
if (imgCrop == null)
{
return;
}
try
{
var temp = imgCrop.SmoothGaussian(5).Convert<Gray, byte>().ThresholdBinaryInv(new Gray(230), new Gray(255));
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
Mat m = new Mat();
CvInvoke.FindContours(temp, contours, m, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
for (int i = 0; i < contours.Size; i++)
{
double perimeter = CvInvoke.ArcLength(contours[i], true);
VectorOfPoint approx = new VectorOfPoint();
CvInvoke.ApproxPolyDP(contours[i], approx, 0.04 * perimeter, true);
CvInvoke.DrawContours(imgCrop, contours, i, new MCvScalar(0, 0, 255), 2);
pictureBox2.Image = imgCrop.Bitmap;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
【问题讨论】:
-
如果您还计算轮廓
area(即通过boundingRect获取边界框,然后调用area())并过滤低于某个area threshold的任何内容怎么办? -
@eldesgraciado 说实话我对 emgucv 了解不多,我今天刚开始阅读文档并尝试使用代码,我该怎么做你说的?
-
我的回答正是这样做的:stackoverflow.com/questions/62550517/…
标签: c# winforms opencv emgucv opencv-drawcontour