您的两个图像都包含许多与您正在寻找的标志无关的线条。其中一些线条比您实际想要的线条更长/对比度更高,因此我认为检测边缘线(例如使用霍夫变换或通过水平/垂直总结对比度)将不起作用。
但是:您正在寻找的标志具有其他应该更容易检测到的特征:
- 标志背景具有(几乎)恒定的亮度
- 它占据了图像的相对较大的区域
- 它靠近图像的中心
所以你正在寻找一个低对比度的大连接区域。我在 Mathematica 中破解了一个概念验证算法。(我不是 OpenCV 专家,但是当我了解它们时,我会提到相应的 OpenCV 功能。)
首先,我使用高斯导数滤波器来检测每个像素的梯度幅度。高斯导数滤波器的孔径很宽(在这种情况下为 11x11 像素),因此它对噪声非常不敏感。然后我将梯度图像归一化为均值 = 1,因此我可以对两个样本使用相同的阈值。
src = Import["http://www.freeimagehosting.net/uploads/720da20080.jpg"];
pixels = ImageData[ColorConvert[src, "Grayscale"]];
gradient = Sqrt[GaussianFilter[pixels, 5, {1, 0}]^2 + GaussianFilter[pixels, 5, {0, 1}]^2];
gradient = gradient/Mean[Flatten[gradient]];
OpenCV 实现:您可以sepFilter2D
用于实际过滤,但显然,您必须自己计算过滤器内核值。
结果如下所示:
在此图像中,标志背景较暗,标志边框较亮。所以我可以将此图像二值化并寻找暗连接组件。
binaryBorders = Binarize[Image[gradient], 0.2];
sign = DeleteBorderComponents@ColorNegate[binaryBorders];
largestComponent = SortBy[ComponentMeasurements[sign, {"Area", "ConvexVertices"}][[All, 2]], First][[-1, 2]];
OpenCV 实现:阈值设置应该很简单,但我认为 OpenCV 不包含连接组件分析 - 您可以使用洪水填充或cvBlobsLib。
现在,只需在图像中心附近找到最大的斑点并找到凸包(我只是使用了未连接到背景的最大斑点,但这对于每张图像来说可能还不够)。
结果: