Nhận diện tàu thuyền dựa trên hình ảnh vệ tinh với mô hình CNN
Trong bài viết này, mình sẽ trình bày về việc nhận diện các tàu thuyền dựa trên hình ảnh vệ tinh.
Thứ nhất là dataset. Đây là yếu tố quan trọng nhất trong bài toán nhận diện hình ảnh dựa trên CNN. Hình ảnh vệ tinh thì quan trọng nhất chính là độ phân giải của hình ảnh. Có rất nhiều hình ảnh vệ tinh được cung cấp miễn phí và cập nhật hằng ngày, tuy nhiên độ phân giải hình ảnh rất thấp (ví dụ là Landsat 8 - với độ phân giải 30m/pixel), thì không thể sử dụng để nhận diện các tàu thuyền được. Planet thì có độ phân giải cao, sử dụng tốt cho việc nhận diện tàu thuyền nhưng mức phí để sử dụng cũng cao theo. Mình sẽ trình bày cụ thể về các loại hình ảnh vệ tinh trong một bài viết riêng. Trong bài viết này, mình sử dụng bộ dataset "Ships in Satellite Imagery", bộ dataset này được tổng hợp từ nhiều vệ tinh thương mại có độ phân giải cao, nên có thể dễ dàng sử dụng cho mục đích trong bài viết này.
Các bạn có thể download từ Kaggle theo đường link https://www.kaggle.com/rhammell/ships-in-satellite-imagery hoặc download trực tiếp từ website của mình http://vipnas.buitrongan.com:5000/sharing/y0psROlPG
Dataset đã sẵn sàng, giờ chúng ta bắt đầu cho quá trình train bộ dữ liệu này trước.
Môi trường mình sử dụng để thực hiện (cập nhật 12 tháng 6 2019):
- Ubuntu Server 20.04
- Cuda 10.2
- Tensorflow 2.2.0
Vì hiện tại, bản Tensorflow mới nhất chưa hỗ trợ tốt trên Ubuntu 20.04 nên bạn cần phải cấu hình thủ công một số phần. Các bạn có thể tham khảo hướng dẫn cài đặt của mình trên Ubuntu 20.04 tại https://medium.com/@trongan93/tensorflow-2-2-0-on-ubuntu-server-20-04-3aa431c851bc
Sau khi import các thư viện cần thiết, chúng ta tiến hành import và test bộ dữ liệu training cũng như dữ liệu mẫu.
Hình đầu tiên trong bộ dataset được thể hiện theo hình bên dưới trên 3 channels khác nhau là R,G,B.
Bước tiếp theo, chúng ta cần chuẩn hóa bộ dữ liệu.
Sau khi chuẩn hóa bộ dữ liệu, chúng ta tiến hành training cho bộ dữ liệu trên. Vì hiện tại, mình sử dụng Tensorflow 2.2.0, cho đến thời điểm hiện tại, mình cần phẩn config GPUs memory trên các server training multi-gpus.
Mình tiến hành xây dựng Model CNN, trong bài này, mình sử dụng một mô hình CNN đơn giản với 3 Convolution Layer. Các bạn có thể sử dụng ResNet, GoogleNet, MobileNet... để training.
Sau khi định nghĩa xong model, chúng ta tiến hành training.
Trong lúc quá trình training thực hiện, chúng ta chọn một hình ảnh ví dụ để thực hiện quá trình classification.
Sau khi đợi để hoàn thành quá trình training, chúng ta chuyển qua quá trình sử dụng model đã training để nhận diện hình ảnh. Trước tiên chúng ta chia nhỏ hình lớn thành các hình nhỏ có kích thước 80*80 pixel. Chúng ta sẽ tiến hành nhận dện các đối tượng dựa trên các hình nhỏ này.
Cuối cùng chúng ta sẽ sử dụng model đã được training để tìm ra chính xác các vị trí hình nào có chứa các tàu thuyền.
Hình bên dưới là 3 ví dụ về việc nhận diện các thuyền sau khi scan với các hình ảnh đã cắt với kích thước 80x80.
Từ các vị trí của các hình ảnh đã được cắt, chúng ta tiến hành xác định vị trí của các block trong hình test. Sau đó tiến hành khoanh vùng các vị trí này lại.
Kết quả ghi nhận được sẽ hiển thị như sau:
Bài viết ngắn, hy vọng giúp cho các bạn giải trí và cũng là một homework nhỏ cho các bạn tìm tòi trong 2 ngày cuối tuần sắp tới.
Full code, các bạn clone tại git của mình nhé: https://github.com/trongan93/ncnu-ai-course/blob/master/W15-ShipDetection/ship-classification.ipynb
Trong-An Bui
buitrongan.com
References:
https://www.kaggle.com/rhammell/ships-in-satellite-imagery
https://www.kaggle.com/byrachonok/keras-for-search-ships-in-satellite-image/notebook