Kedua gambar Anda mengandung banyak garis yang tidak ada hubungannya dengan tanda yang Anda cari. Dan beberapa garis itu lebih panjang / memiliki kontras lebih tinggi daripada garis yang sebenarnya Anda inginkan, jadi saya pikir mendeteksi garis tepi (misalnya menggunakan transformasi hough atau dengan menjumlahkan kontras secara horizontal / vertikal) tidak akan berfungsi.
Tetapi: Tanda yang Anda cari memiliki karakteristik lain yang seharusnya lebih mudah dideteksi:
- Latar belakang tanda ada memiliki (hampir) kecerahan konstan
- Ini membutuhkan area gambar yang relatif besar
- Itu dekat pusat gambar
Jadi, Anda mencari area terhubung yang besar dengan kontras rendah. Saya telah meretas algoritma pembuktian konsep di Mathematica. (Saya bukan ahli OpenCV, tapi saya akan menyebutkan fungsi OpenCV masing-masing ketika saya mengenal mereka.)
Pertama, saya menggunakan filter turunan gaussian untuk mendeteksi besarnya gradien pada setiap piksel. Filter turunan gaussian memiliki bukaan lebar (11x11 piksel dalam kasus ini), sehingga sangat tidak sensitif terhadap noise. Saya kemudian menormalkan gambar gradien berarti = 1, jadi saya bisa menggunakan ambang yang sama untuk kedua sampel.
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]];
Implementasi OpenCV: Anda dapat menggunakan sepFilter2D
untuk pemfilteran yang sebenarnya, tetapi tampaknya, Anda harus menghitung sendiri nilai-nilai kernel filter .
Hasilnya terlihat seperti ini:
Pada gambar ini, latar belakang tanda gelap dan batas tanda cerah. Jadi saya bisa melakukan binarize pada gambar ini dan mencari komponen yang terhubung secara gelap.
binaryBorders = Binarize[Image[gradient], 0.2];
sign = DeleteBorderComponents@ColorNegate[binaryBorders];
largestComponent = SortBy[ComponentMeasurements[sign, {"Area", "ConvexVertices"}][[All, 2]], First][[-1, 2]];
Implementasi OpenCV: Ambang batas harus langsung, tetapi saya pikir OpenCV tidak mengandung analisis komponen yang terhubung - Anda dapat menggunakan mengisi banjir atau cvBlobsLib untuk itu.
Sekarang, temukan gumpalan terbesar di dekat bagian tengah gambar dan temukan cembung cembung (Saya hanya menggunakan gumpalan terbesar yang tidak terhubung ke latar belakang, tetapi itu mungkin tidak cukup untuk setiap gambar).
Hasil: