Một trong những dự án thú vị nhất mà tôi đã thực hiện trong vài năm qua là một dự án về xử lý hình ảnh . Mục tiêu là phát triển một hệ thống để có thể nhận ra 'lon' của Coca-Cola (lưu ý rằng tôi đang nhấn mạnh từ 'lon', bạn sẽ thấy tại sao trong một phút). Bạn có thể thấy một mẫu bên dưới, với hình có thể được nhận ra trong hình chữ nhật màu xanh lá cây với tỷ lệ và xoay.
Một số hạn chế về dự án:
- Bối cảnh có thể rất ồn ào.
- Có thể có bất kỳ tỷ lệ hoặc xoay hoặc thậm chí định hướng (trong giới hạn hợp lý).
- Hình ảnh có thể có một số độ mờ (đường viền có thể không hoàn toàn thẳng).
- Có thể có chai Coca-Cola trong hình ảnh, và các thuật toán chỉ nên phát hiện sự can !
- Độ sáng của hình ảnh có thể thay đổi rất nhiều (vì vậy bạn không thể dựa vào "quá nhiều" để phát hiện màu).
- Cái này có thể được giấu một phần ở hai bên hoặc giữa và có thể một phần ẩn đằng sau một cái chai.
- Không thể có thể có tất cả trong hình ảnh, trong trường hợp đó bạn không tìm thấy gì và viết một tin nhắn nói như vậy.
Vì vậy, bạn có thể kết thúc với những thứ khó khăn như thế này (trong trường hợp này là thuật toán của tôi hoàn toàn thất bại):
Tôi đã thực hiện dự án này một thời gian trước đây, và đã có rất nhiều niềm vui khi thực hiện nó, và tôi đã có một triển khai tốt. Dưới đây là một số chi tiết về việc thực hiện của tôi:
Ngôn ngữ : Thực hiện trong C ++ bằng thư viện OpenCV .
Xử lý trước : Để xử lý trước hình ảnh, tức là chuyển đổi hình ảnh thành dạng thô hơn để cung cấp cho thuật toán, tôi đã sử dụng 2 phương pháp:
- Thay đổi miền màu từ RGB sang HSV và lọc dựa trên màu "đỏ", bão hòa trên một ngưỡng nhất định để tránh các màu giống như màu cam và lọc giá trị thấp để tránh tông màu tối. Kết quả cuối cùng là một hình ảnh đen trắng nhị phân, trong đó tất cả các pixel trắng sẽ đại diện cho các pixel phù hợp với ngưỡng này. Rõ ràng vẫn còn rất nhiều crap trong hình ảnh, nhưng điều này làm giảm số lượng kích thước bạn phải làm việc với.
- Lọc nhiễu bằng cách sử dụng lọc trung vị (lấy giá trị pixel trung bình của tất cả các lân cận và thay thế pixel bằng giá trị này) để giảm nhiễu.
- Sử dụng Bộ lọc phát hiện cạnh Canny để có được các đường viền của tất cả các mục sau 2 bước trước đó.
Thuật toán : Bản thân thuật toán tôi chọn cho tác vụ này được lấy từ cuốn sách tuyệt vời này về trích xuất tính năng và được gọi là Generalized Hough Transform (khá khác với Hough Transform thông thường). Về cơ bản nó nói một vài điều:
- Bạn có thể mô tả một đối tượng trong không gian mà không cần biết phương trình phân tích của nó (đó là trường hợp ở đây).
- Nó có khả năng chống biến dạng hình ảnh như tỷ lệ và xoay, vì về cơ bản nó sẽ kiểm tra hình ảnh của bạn cho mọi sự kết hợp của yếu tố tỷ lệ và yếu tố xoay.
- Nó sử dụng một mô hình cơ sở (một mẫu) mà thuật toán sẽ "học".
- Mỗi pixel còn lại trong hình ảnh đường viền sẽ bỏ phiếu cho một pixel khác được cho là trung tâm (tính theo trọng lực) của đối tượng của bạn, dựa trên những gì nó học được từ mô hình.
Cuối cùng, bạn kết thúc với một bản đồ nhiệt của phiếu bầu, ví dụ ở đây tất cả các pixel của đường viền có thể sẽ bỏ phiếu cho trung tâm hấp dẫn của nó, vì vậy bạn sẽ có rất nhiều phiếu trong cùng một pixel tương ứng với trung tâm, và sẽ thấy một đỉnh trong bản đồ nhiệt như dưới đây:
Khi bạn đã có điều đó, một heuristic dựa trên ngưỡng đơn giản có thể cung cấp cho bạn vị trí của pixel trung tâm, từ đó bạn có thể lấy tỷ lệ và xoay và sau đó vẽ hình chữ nhật nhỏ của bạn xung quanh nó (tỷ lệ cuối cùng và hệ số xoay sẽ rõ ràng tương đối với mẫu gốc). Về lý thuyết ít nhất ...
Kết quả : Bây giờ, trong khi phương pháp này hoạt động trong các trường hợp cơ bản, nó đã bị thiếu trầm trọng ở một số lĩnh vực:
- Nó cực kỳ chậm ! Tôi không nhấn mạnh điều này đủ. Gần như cả ngày là cần thiết để xử lý 30 hình ảnh thử nghiệm, rõ ràng vì tôi có hệ số tỷ lệ rất cao để xoay và dịch, vì một số lon rất nhỏ.
- Nó đã bị mất hoàn toàn khi các chai trong hình ảnh, và vì một số lý do hầu như luôn tìm thấy chai thay vì lon (có lẽ vì chai lớn hơn, do đó có nhiều pixel hơn, do đó nhiều phiếu hơn)
- Hình ảnh mờ cũng không tốt, vì phiếu bầu kết thúc bằng pixel tại các vị trí ngẫu nhiên xung quanh trung tâm, do đó kết thúc bằng một bản đồ nhiệt rất ồn.
- Sự khác biệt trong dịch thuật và xoay đã đạt được, nhưng không theo định hướng, có nghĩa là một hộp không trực tiếp đối diện với mục tiêu máy ảnh không được nhận ra.
Bạn có thể giúp tôi cải thiện thuật toán cụ thể của mình , sử dụng các tính năng OpenCV độc quyền , để giải quyết bốn vấn đề cụ thể được đề cập không?
Tôi hy vọng một số người cũng sẽ học được điều gì đó từ nó, sau tất cả, tôi nghĩ rằng không chỉ những người đặt câu hỏi nên học. :)