由于项目需要,需要对灰度图进行孔洞填补,在网上查找了一圈发现基本都是将灰度图二值化在通过漫水填充的方法来实现的(imfill)。但是由于我的灰度图中包含有重要信息,二值化会导致关键信息的丢失。没办法只有自己想了个笨办法解决。(一个数学、逻辑、编程都菜的扣jio的菜狗能想到办法并将之实现是件很不容易的事所以特此记录,代码里面n的初始值为1)
- 根据所得到的灰度图像特点,检测图像中每个像素点的灰度值,如果检测结果为“当前像素灰度值为0,而下一个像素值不为0”则将该点坐标存入DeleteHeadMinuend;
- 如果检测结果为“当前像素灰度值不为0,而下一个像素值为0”则将该点放入DeleteEndSubtraction;
- 去除DeleteHeadMinuend中的首个元素;
- 去除DeleteEndSubtraction中最后一个元素;
- 然后以DeleteEndSubtraction和DeleteHeadMinuend数组中对应位置的元素区间填补其中的点;
- 填补的点的像素值与其前一个点的像素值相同;
/*************************************************************************************/
for (int x = 0; x < Dst.rows; x++)
{
for (int y = 0; y < Dst.cols; y++)
{
if (Dst.ptr<uchar>(x)[y]!=0 && Dst.ptr<uchar>(x)[y+1] ==0)
{
DeleteEndSubtraction.push_back(Point2d(x, y));
}
if (Dst.ptr<uchar>(x)[y] == 0 && Dst.ptr<uchar>(x)[y+1] != 0)
{
DeleteHeadMinuend.push_back(Point2d(x, y));
}
}
}
if (DeleteEndSubtraction.size()>1 && DeleteHeadMinuend.size()>1)
{
//将包含在对应区域内的像素点进行填充
for (int m = 0; m < DeleteEndSubtraction.size()-1; m++)
{
if (DeleteHeadMinuend[n].y-DeleteEndSubtraction[m].y<=8)
{
for (int Y = DeleteEndSubtraction[m].y; Y <= DeleteHeadMinuend[n].y; Y++)
{
Dst.ptr<uchar>(DeleteEndSubtraction[m].x)[Y] = Dst.ptr<uchar>(DeleteEndSubtraction[m].x)[Y - 1];
}
}
n++;
}
}
实验效果: