STDIO Bài viết ứng dụng OpenCV để nhận dạng và đếm số lượng vật thể giúp giảm bớt thời gian làm việc thủ công cho con người. Bạn có thể ứng dụng ngoài đếm đậu để đếm nhiều loại vật thể khác nhau với số lượng lớn.
Nội dung bài viết

Giới thiệu

Hiện nay máy móc giúp đỡ cho con người trong rất nhiều công việc như cơ khí, vũ trang, nhưng hầu hết các công việc đó máy móc giúp đỡ về phần sức khỏe, về thể chất của con người. Con người suy nghĩ và đưa ra quyết định cho máy móc làm việc, vậy phần cốt lõi nếu muốn máy móc làm hết công việc đó là máy móc phải nhận dạng được thế giới xung quanh.

Bài viết này ứng dụng OpenCV vào việc đếm số lượng các vật thể, tôi dùng Python để tiện cho việc viết demo, bạn có thể sử dụng OpenCV C++ hoặc C# với EmguCV cũng cho kết quả tương tự.

Môi trường thử nghiệm

  • Python phiên bản 3.6.5.
  • OpenCV phiên bản 3.4.1.

Sử dụng OpenCV trong bài toán đếm đậu

Tôi phân ra thành hai bước chính đó là: Nhận dạng và đếm.

Cài đặt thư viện OpenCV và Numpy qua dòng lệnh

pip install opencv-python
pip install numpy

Tôi phải khai báo trong đoạn script cho biết những thư viện mà tôi sắp sử dụng 

from cv2 import cv2
import numpy as np
from skimage.morphology import opening

Nhận dạng

Đầu tiên tôi đọc tấm ảnh lên và đặt tên là image

beans

image = cv2.imread("images/dem-dau-voi-opencv.jpg")  

Tạo một bức ảnh màu xám từ ảnh gốc và đặt tên là GrayImage

grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

Tôi sử dụng thuật toán Gaussian để làm mờ bức ảnh từ bức ảnh xám

blur = cv2.GaussianBlur(grayImage, (9,9), 1)

Tiếp theo tôi sử dụng phương thức threshold nhưng tôi nhận thấy rằng bức ảnh của tôi có độ sáng phân bổ không đều nên thay vào đó tôi sử dụng phương thức adaptiveThreshold

threshold = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, -5)

Lọc nhiễu với Opening

opening = cv2.morphologyEx(threshold, cv2.MORPH_OPEN, kernel)

Phác họa ảnh

cv2.imshow('opening', opening)

Đếm

_, contours, _ = cv2.findContours(opening, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) 
print("Cout: " + str(len(contours))) 

Kết thúc chương trình với:

cv2.waitKey(0) 
cv2.destroAllWindows()

Kết quả khi chạy chương trình trên: 

Opening

count

Source code đầy đủ

beans

from cv2 import cv2
import numpy as np
from skimage.morphology import opening

img = cv2.imread("beans.jpg") 
kernel = np.ones((5,5),np.uint8)

# Bước 1: Chuyển về ảnh xám
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Bước 2: Làm mờ ảnh
blur = cv2.GaussianBlur(gray, (9, 9), 1)
cv2.imshow('new', blur)

# Bước 3: Lọc nhiễu
new = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, -5)

# Bước 4: Opening
opening = cv2.morphologyEx(new, cv2.MORPH_OPEN, kernel)

# Bước 5: Đếm
_, contours, _ = cv2.findContours(opening, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Kiểm tra kết quả
cv2.drawContours(img, contours, -1, (255, 0, 0), 3)
cv2.imshow('opening', opening)
print("Count: " + str(len(contours)))
cv2.waitKey(0)
cv2.destroyAllWindows()

Tham khảo

THẢO LUẬN
Người ta nghĩ rằng khoa học máy tính là ngành toàn những thiên tài, thực tế thì ngược lại, họ chỉ làm việc dựa trên kết quả công việc của những người tiền nhiệm, giống như những viên gạch xếp chồng lên nhau tạo nên bức tường. Donald Knuth
ĐÓNG