Beide Bilder enthalten viele Linien, die nichts mit dem gesuchten Zeichen zu tun haben. Und einige dieser Linien sind länger / kontrastreicher als die von Ihnen gewünschten, sodass ich denke, dass das Erkennen der Kantenlinien (z. B. mithilfe einer Hough-Transformation oder durch horizontales / vertikales Aufsummieren von Kontrasten) nicht funktioniert.
Aber: Das Zeichen, nach dem Sie suchen, hat andere Eigenschaften, die leichter zu erkennen sein sollten:
- Dort hat Zeichenhintergrund (fast) konstante Helligkeit
- Es nimmt einen relativ großen Bereich des Bildes ein
- Es ist in der Nähe der Bildmitte
Sie suchen also einen großen zusammenhängenden Bereich mit geringem Kontrast. Ich habe in Mathematica einen Proof-of-Concept-Algorithmus gehackt. (Ich bin kein OpenCV-Experte, aber ich werde die jeweilige OpenCV-Funktion erwähnen, wenn ich sie kenne.)
Zuerst benutze ich Gauß'sche Ableitungsfilter, um die Gradientengröße bei jedem Pixel zu erfassen. Das Filter mit Gauß-Ableitung hat eine große Apertur (in diesem Fall 11 x 11 Pixel) und ist daher sehr rauschunempfindlich. Ich normalisiere dann das Gradientenbild auf mean = 1, damit ich für beide Samples die gleichen Schwellenwerte verwenden kann.
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-Implementierung: Sie können sepFilter2D
für die eigentliche Filterung verwenden, aber anscheinend müssen Sie die Filterkernwerte selbst berechnen .
Das Ergebnis sieht so aus:
In diesem Bild ist der Zeichenhintergrund dunkel und die Zeichenränder sind hell. So kann ich dieses Bild digitalisieren und nach dunkel verbundenen Komponenten suchen.
binaryBorders = Binarize[Image[gradient], 0.2];
sign = DeleteBorderComponents@ColorNegate[binaryBorders];
largestComponent = SortBy[ComponentMeasurements[sign, {"Area", "ConvexVertices"}][[All, 2]], First][[-1, 2]];
OpenCV-Implementierung: Thresholding sollte unkompliziert sein, aber ich denke, OpenCV enthält keine Analyse verbundener Komponenten - Sie können entweder Flood Fill oder verwenden cvBlobsLib verwenden .
Suchen Sie nun einfach den größten Fleck in der Nähe der Bildmitte und die konvexe Hülle (ich habe einfach den größten Fleck verwendet, der nicht mit dem Hintergrund verbunden ist, der jedoch möglicherweise nicht für jedes Bild ausreicht).
Ergebnisse: