Cả hai hình ảnh của bạn đều chứa nhiều dòng không liên quan gì đến dấu hiệu bạn đang tìm kiếm. Và một số dòng đó dài hơn / có độ tương phản cao hơn các dòng bạn thực sự muốn, vì vậy tôi nghĩ rằng việc phát hiện các đường biên (ví dụ: sử dụng biến đổi hough hoặc bằng cách tóm tắt độ tương phản theo chiều ngang / chiều dọc) sẽ không hiệu quả.
Nhưng: Dấu hiệu bạn đang tìm kiếm có các đặc điểm khác nên dễ phát hiện hơn:
- Có nền dấu hiệu có (gần như) độ sáng không đổi
- Nó chiếm một diện tích tương đối lớn của hình ảnh
- Nó ở gần trung tâm của hình ảnh
Vì vậy, bạn đang tìm kiếm một khu vực kết nối lớn với độ tương phản thấp. Tôi đã hack một thuật toán bằng chứng trong Mathicala. (Tôi không phải là chuyên gia về OpenCV, nhưng tôi sẽ đề cập đến chức năng OpenCV tương ứng khi tôi biết họ.)
Đầu tiên, tôi sử dụng các bộ lọc đạo hàm gaussian để phát hiện cường độ gradient ở mỗi pixel. Bộ lọc phái sinh gaussian có khẩu độ rộng (11x11 pixel trong trường hợp này), vì vậy nó rất nhạy cảm với nhiễu. Sau đó tôi bình thường hóa hình ảnh gradient thành mean = 1, vì vậy tôi có thể sử dụng cùng một ngưỡng cho cả hai mẫu.
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]];
Triển khai OpenCV: Bạn có thể sử dụng sepFilter2D
để lọc thực tế, nhưng rõ ràng, bạn sẽ phải tự tính toán các giá trị nhân của bộ lọc .
Kết quả trông như thế này:
Trong hình ảnh này, nền dấu hiệu tối và đường viền dấu hiệu sáng. Vì vậy, tôi có thể binarize hình ảnh này và tìm kiếm các thành phần kết nối tối.
binaryBorders = Binarize[Image[gradient], 0.2];
sign = DeleteBorderComponents@ColorNegate[binaryBorders];
largestComponent = SortBy[ComponentMeasurements[sign, {"Area", "ConvexVertices"}][[All, 2]], First][[-1, 2]];
Triển khai OpenCV: Ngưỡng phải đơn giản, nhưng tôi nghĩ OpenCV không chứa phân tích thành phần được kết nối - bạn có thể sử dụng fill fill hoặc cvBlobsLib cho điều đó.
Bây giờ, chỉ cần tìm đốm màu lớn nhất ở gần trung tâm của hình ảnh và tìm vỏ lồi (Tôi chỉ đơn giản là sử dụng đốm màu lớn nhất không được kết nối với nền, nhưng điều đó có thể không đủ cho mọi hình ảnh).
Các kết quả: