正如您所看到的,很难过滤点状图案。它明显与文本重叠。我至少看到两个选择: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 );
这是你得到的面具:
现在,只需将此掩码减去原始(二进制)图像即可得到:
正如您所看到的,部分列标题妨碍了操作。如果你想要白色背景和黑色斑点,只需反转图像: