どちらの画像にも、探しているサインとは何の関係もない多くの行が含まれています。そして、これらの線のいくつかは実際に必要な線よりも長い/高いコントラストを持っているので、エッジ線の検出(例えば、ハフ変換の使用またはコントラストを水平/垂直に合計すること)は動作しません。
しかし、あなたが探しているサインには、他の特徴があります。
- 背景にサインが(ほぼ)一定の明るさを持っている
- 画像の比較的広い領域を占める
- 画像の中央付近です
したがって、コントラストの低い大きな接続領域を探しています。Mathematicaで概念実証アルゴリズムをハッキングしました。(私はOpenCVの専門家ではありませんが、OpenCVの機能を知っていれば、それぞれについて説明します。)
まず、ガウス微分フィルターを使用して、各ピクセルの勾配の大きさを検出します。ガウス微分フィルターは広い開口部(この場合は11x11ピクセル)を持っているため、ノイズに非常に敏感です。次に、勾配画像をmean = 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
実際のフィルタリングに使用できますが、明らかに、カーネルのフィルター値を自分で計算する必要があります。
結果は次のようになります。
この画像では、標識の背景は暗く、標識の境界線は明るいです。そのため、この画像を2値化して、暗い連結成分を探すことができます。
binaryBorders = Binarize[Image[gradient], 0.2];
sign = DeleteBorderComponents@ColorNegate[binaryBorders];
largestComponent = SortBy[ComponentMeasurements[sign, {"Area", "ConvexVertices"}][[All, 2]], First][[-1, 2]];
OpenCVの実装:しきい値設定は簡単である必要がありますが、OpenCVには接続コンポーネント分析が含まれていないと思います。そのためには、fill fillまたはcvBlobsLibを使用できます。
ここで、画像の中央付近で最大のBLOBを見つけて、凸包を見つけます(背景に接続されていない最大のBLOBを使用しましたが、すべての画像には十分ではないかもしれません)。
結果: