我正在使用EmguCV进行简单的图像处理。我想从阈值图像中删除小轮廓,所以我使用了 connectedcomponentswithstats 。以下是我的代码,其中将小于最小大小的任何像素转换为黑色-本质上将其删除。我要这样做的原因是因为它与其他类型不兼容,因此可以在后一部分中使用它。
public Mat Filtered(Mat in_img, string currentDir)
{
Mat gray_res = new Mat();
Mat labels = new Mat();
Mat stats = new Mat();
Mat centroids = new Mat();
CvInvoke.CvtColor(in_img, gray_res, ColorConversion.Bgr2Gray);
var nlabels = CvInvoke.ConnectedComponentsWithStats(gray_res, labels, stats, centroids, LineType.EightConnected);
int min_size = 250;
int[] sizes = new int[nlabels];
for (int s = 1; s < nlabels; s++)
{
sizes[s] = BitConverter.ToInt32(stats.GetData(s, (int)ConnectedComponentsTypes.Area), 0);
}
Matrix<double> fltr_img = new Matrix<double>(labels.Rows, labels.Cols);
fltr_img.SetValue(0);
for (int i = 1; i < nlabels; i++)
{
int j = BitConverter.ToInt32(stats.GetData(i, (int)ConnectedComponentsTypes.Left), 0); //left most
int w = BitConverter.ToInt32(stats.GetData(i, (int)ConnectedComponentsTypes.Width), 0); //run width
int k = BitConverter.ToInt32(stats.GetData(i, (int)ConnectedComponentsTypes.Top), 0); //top most
int h = BitConverter.ToInt32(stats.GetData(i, (int)ConnectedComponentsTypes.Height), 0); //run height
if (sizes[i] < min_size)
{
for (int a = k; a < k + h; a++)
{
for (int b = j; b < j + w; b++)
{
fltr_img.Data[a, b] = 255;
}
}
}
}
//Covnert 2D Matrix to Image
CvInvoke.Imwrite(currentDir + "filter.jpg", fltr_img);
Mat subtrahend = CvInvoke.Imread(currentDir + "filter.jpg");
Mat fnl_img = new Mat();
CvInvoke.Subtract(in_img, subtrahend, fnl_img);
return fnl_img;
}
最后,我所做的是一个肮脏的技巧,将蒙版转换为兼容类型的 Mat ,这是原始图像。有了这段代码,我得到了结果,但是我仍然对它感到不安。
答案 0 :(得分:1)
您可以通过使用其Mat属性转换矩阵类型。我不知道您需要哪种类型,所以在示例中使用了DepthType.Cv8U。
Mat converted = new Mat();
fltr_img.Mat.ConvertTo(converted, DepthType.Cv8U);
Mat fnl_img = new Mat();
CvInvoke.Subtract(in_img, converted, fnl_img);
或者,您也可以将Mat和/或Matrix与减法一起使用。两者都实现了IInpurArray接口。
CvInvoke.Subtract(in_img, fltr_img, fnl_img); //Tested with EmguCv 3.4.1