如您所见,虚线图案很难过滤。它显然与文本重叠。我看到至少有两种选择:1)利用模式的周期性特性并执行频率过滤。 2) 尝试一种更简单的方法,对目标像素使用形态命中或未命中操作,旨在隔离它们。
让我们看看选项 2。噪声具有非常独特的模式。如果您使用所有斑点都以白色着色的二进制图像,您正在寻找的图案是一个白色像素 (1) 被 8 个黑色像素 (0) 包围>:
[ 0, 0, 0 ]
[ 0, 1, 0 ]
[ 0, 0, 0 ]
命中和未命中操作可用于定位和隔离像素模式。 Here's 如果您想了解更多信息,这是一篇好文章。现在,让我们处理代码:
//Read the input image, as normal:
std::string imagePath = "C://opencvImages//tableTest.png";
cv::Mat testImage = cv::readImage( imagePath );
//Convert the image to grayscale:
cv::Mat grayImage;
cv::cvtColor( testImage, grayImage, cv::COLOR_BGR2GRAY );
//Get the binary image via otsu:
cv::Mat binaryImage;
cv::threshold( grayImage, binaryImage, 0, 255,cv::THRESH_OTSU );
//Invert the image, as we will be working on white blobs:
binaryImage = 255 - binaryImage;
//Prepare the target kernel. This is where you define the pattern of
//pixels you are looking for
//Keep in mind that -1 -> black and 1 -> white
cv::Mat kernel = ( cv::Mat_<int>(3, 3) <<
-1, -1, -1,
-1, 1, -1,
-1, -1, -1
);
//perform the hit or miss operation:
cv::Mat hitMissMask;
cv::morphologyEx( binaryImage, hitMissMask, cv::MORPH_HITMISS, kernel );
这是你得到的面具:
现在,只需将此蒙版减去原始(二进制)图像即可得到:
如您所见,部分列标题妨碍了操作。如果您想要白色背景和黑色斑点,只需反转图像: