Xử lý dữ liệu trên Kinect

Một phần của tài liệu Đồ án phân loại sản phẩm, dùng camera Kinect (Trang 72)

a. Xử lý dữ liệu hình ảnh được truy cập từ camera RGB

Kinect SDK cung cấp dữ liệu hình ảnh dưới dạng mảng lớn gồm các phần tử 8 bit, trong đó mỗi pixel của hình ảnh được ánh xạ thành 4 vị trí (3 kênh màu và 1 kênh trống (Alpha)) của mảng này; ánh xạ được xảy ra theo thứ tự liên tiếp từ kênh xanh dương sang kênh đỏ (B, G, R, rỗng). Công thức tính độ dài mảng: [8]

Length.arr = image.height × image.width × 4 (3.16)

Trong đó:

60

• image.height: chiều cao của ảnh (chiều dọc, đơn vị: pixel)

• image.width: chiều rộng của ảnh (chiều ngang, đơn vị: pixel)

• Hệ số ánh xạ 4: đại diện cho 4 kênh màu (R (Red) – đỏ, G (Green) – xanh lá cây, B (Blue)– xanh dương, A (Alpha) – rỗng).

Hình 3.29. Mảng dữ liệu hình ảnh truy cập từ camera RGB

Mối quan hệ giữa các cấu trúc (mảng và ma trận) có thể được mô tả bởi các phương trình dưới đây, thông qua giá trị tại một vị trí cho trước trong mảng (index), ta tìm được vị trí của một pixel tương ứng: [8]

pixel.y=floor(index/(image.width × 4)) (3.17)

pixel.x=floor(index/4-(pixel.y × image.width)) (3.18)

Và phép toán nghịch đảo (tìm một vị trí trên mảng khi cho một vị trí pixel x, y):

index=(pixel.y*image.width+pixel.x) × 4 (3.19)

Trong đó:

• Index: vị trí phần tử mảng

• Pixel.y: tọa độ y của pixel tương ứng với phần tử index

• Pixel.x: tọa độ x của pixel tương ứng với phần tử index

Vị trí trên mảng luôn trỏ tới kênh B – xanh dương của pixel cho trước, vì vậy giá trị của các kênh khác cần được tính toán qua những phương trình sau: [8]

61

ValueB=Array(index) (3.20)

ValueG=Array(index+1) (3.21)

ValueR=Array(index+2) (3.22)

b. Xử lý dữ liệu độ sâu thông qua cảm biến hồng ngoại

Dữ liệu độ sâu cũng được cung cấp dưới dạng một mảng hàng gồm các phần tử 16 bit với độ dài của mảng này đã cho.

Hình dưới đây minh họa mối quan hệ giữa khoảng cách của một đối tượng K tới cảm biến so với mặt phẳng tham chiếu và sự chênh lệch đo lường d. [9]

Hình 3.30. Mối quan hệ giữa khoảng cách của một đối tượng so với cảm biến

Z trục là trực giao với mặt phẳng ảnh đối với vật thể, X trục vuông góc với trục Z theo phương của đường cơ sở b (đường thẳng nối từ tâm camera hồng ngoại đến máy chiếu laser) và trục Y trực giao với X và Z.

Giả sử rằng một đối tượng O nằm trên mặt phẳng tham chiếu ở khoảng cách Zo và một điểm thể hiện đối tượng được chụp trên mặt phẳng hình ảnh của camera hồng ngoại. Nếu đối tượng được dịch chuyển gần đến (hoặc xa hơn) thì vị trí của điểm trên mặt phẳng ảnh sẽ bị dịch chuyển theo phương X. Điểm này được xác định trong không gian ảnh dưới dạng chênh lệch d tương ứng với một điểm k trong mặt phẳng đối tượng. Từ sự đồng dạng của các tam giác ta có: [9]

O K O Z Z D b Z − = (3.23)

62

K

d D

f = Z (3.24)

Trong đó:

• ZK: độ sâu của đối tương K trong không gian

• b: chiều dài cơ sở

• f: tiêu cự của thấu kính camera hồng ngoại

• D: độ dời điểm K trong mặt phẳng đối tượng

• d: độ chêm lệch quan sát được trong mặt phẳng ảnh

Từ 2 phương trình ở trên ta thu được phương trình biểu diễn độ sâu của vật thể: 1 O K O Z Z Z d fb = + (3.25) 3.3.3. Nhận diện sản phẩm

Các bước tiến hành nhận diện phôi:

Bước 1: Hiển thị một luồng video RGB trực tiếp từ camera.

Thông qua thư viện OpenNI, dữ liệu từ Kinect được truy xuất và sử dụng bởi lệnh ‘openni2.Device.open_any()’. Bước đầu tiên là truy cập vào video RGB và hiển thị trên màn hình laptop sử dụng kết hợp với thư viên OpenCV cho tác vụ nhận diện phôi thông qua màu sắc.

Màu sắc mặc định hiển thị trong OpenCV là BGR nên cần dùng lệnh cv2.cvtColor(img, cv2.COLOR_BGR2RGB) để màu sắc được hiển thị đúng

openni2.initialize()

dev = openni2.Device.open_any()

color_stream = dev.create_color_stream() – truy cập RGB video

color_stream.start() color_frame = color_stream.read_frame() color = numpy.ctypeslib.as_array(color_frame.get_buffer_as_uint8()).r eshape(h,w,3) color = cv2.cvtColor(color,cv2.COLOR_BGR2RGB) Hình ảnh hiển thị:

63

Hình 3.31. Hiển thị luồng video RGB

Bước 2: Hình ảnh thu được được chuyển sang không gian màu HSV.

Hệ màu HSV được sử dụng phổ biến trong công nghệ xử lý ảnh bởi tính chính xác của nó trong kĩ thuật nhận diện màu thông qua 3 thông số H – màu sắc, S – độ bão hòa (lượng màu xám trong màu, S giảm dần – màu nhạt dần), V – giá trị (cường độ của màu với V = 0 màu sắc không được nhìn thấy).

Câu lệnh chuyển đổi hệ màu RGB sang HSV

hsv = cv2.cvtColor(color,cv2.COLOR_BGR2HSV) Hình ảnh hiển thị:

Hình 3.32. Hình ảnh chuyển sang không gian màu HSV

Bước 3: Chuyển sang hình ảnh nhị phân (đen trắng với vùng đen là không nhận diện được), dựa vào các thông số H-Hue, S-Saturation, V-Value để xác định đối tượng nhận diện.

Các thông số được lấy trong khoảng:

• H_min = 0 ÷ 179, H_max = 0 ÷ 179

• S_min = 0 ÷ 255, S_max = 0 ÷ 255

64

Dựa vào màu sắc muốn nhận diện cùng với điều kiện môi trường để chọn ra thông số phù hợp nhất cho hệ thống nhận diện.

Với lệnh cv2.inRange() giá trị màu của phôi sẽ được giới hạn trong khoảng (min, max) của các thông số H, S, V.

Lower_color = np.array([H_min,S_min,V_min]) Upper_color = np.array([H_max,S_max,V_max]) mask = cv2.inRange(hsv,Lower_color,Upper_color)

Hình ảnh hiển thị:

Hình 3.33. Hình ảnh nhị phân

mask = cv2.erode(mask, kernel) mask2 = cv2.erode(mask2, kernel)

Sử dụng hàm cv2.erode() để loại bỏ những vùng có số lượng điểm ảnh ít mang giá trị 1. Kết quả hiển thị ở hình dưới:

3.3.4. Phân loại sản phẩm a. Phân loại theo hình dạng a. Phân loại theo hình dạng

Các bước phân loại phôi theo hình dạng:

• Bước 1: Từ hình ảnh nhị phân tìm đường bao của các vật thể đã được nhận diện thông qua lệnh ‘findContours’.

contours,_ =

65

• Bước 2: Với mỗi đường bao đã được xác định, ta có thể xác định gần đúng hình dạng của các đa giác có trong hình ảnh qua phép tính xấp xỉ với lệnh ‘approxPolyDP’.

approx = cv2.approxPolyDP(contour,0.025 * cv2.arcLength(contour,True),True)

Tỷ số 0.025 có thể thay đổi tuỳ thuộc yêu cầu đề bài, trong đề tài phân loại dựa trên hình dạng, tỷ số này không nên quá nhỏ.

• Bước 3: Sau đó, hình dạng xác định của các đường bao được vẽ trên hình ảnh và hiển thị dưới dạng đầu ra của chương trình.

Sử dụng câu lệnh ‘drawContours’ vẽ đường viền màu đen với mã màu (0, 0, 0) (đây là mã màu RGB, thông số có thể thay đổi tùy màu đường viền mong muốn) và độ dày viền là 2.

cv2.drawContours(color,[approx],0,(0,0,0),2) Hình ảnh hiển thị:

Hình 3.34. Xác định đường bao sản phẩm

• Bước 4: Từ phép tính xấp xỉ, tìm số đỉnh của đường bao sản phẩm, phân loại sản phẩm theo số đỉnh nhận được. Tương ứng với số đỉnh ta có thể xác định chính xác loại hình dạng của phôi: 3 đỉnh – hình tam giác, 4 ÷ 6 đỉnh – hình vuông, 7 ÷ 10 đỉnh – hình chữ nhật. if len(approx) == 3: print("Triangle") elif 4 <= len(approx) <= 6: print("Rectangle") elif 7 < len(approx) < 10: print("Circle") Hình ảnh hiển thị:

66

Hình 3.35. Nhận diện hình dạng tam giác

Hình 3.36. Nhận diện hình dạng chữ nhật

b. Phân loại theo chiều cao

Đặt khoảng cách từ cảm biến hồng ngoại đến mặt băng tải là S1, khoảng cách của sản phẩm đo được thông qua cảm biến là S2, nên ta có chiều cao phôi:

H = S1 – S2 (3.30)

Các bước phân loại phôi theo chiều cao:

• Bước 1: Tạo 1 luồng video hiển thị độ sâu trong khung hình đo được từ cảm biến hồng ngoại.

Lệnh create_depth_stream() được thực hiện cho phép máy tính truy cập và lấy dữ liệu từ cảm biến hồng ngoại trên Kinect.

Dữ liệu độ sâu được cung cấp dưới dạng một mảng gồm các phần tử 16 bit, vậy nên cần chuyển đổi các phần tử này sang 8 bit giống với Kinect khi cung cấp dữ liệu hình ảnh giúp cho việc xử lý dữ liệu dễ dàng hơn thông qua lệnhconvertScaleAbs(). depth_stream = dev.create_depth_stream() depth_stream.start() depth_scale_factor = 255.0 / depth_stream.get_max_pixel_value() depth_frame = depth_stream.read_frame() h,w = depth_frame.height,depth_frame.width

67 depth = numpy.ctypeslib.as_array(depth_frame.get_buffer_as_uint16()). reshape(h,w) depth_uint8 = cv2.convertScaleAbs(depth,alpha=depth_scale_factor)

• Bước 2: Khoảng cách được đo trong giới hạn khung hình

Khung hình được giới hạn trong không gian ảnh nhị phân đủ diện tích và thời gian để có thể xác định được 1 phôi

cv2.rectangle(mask, (0, 0), (280, 480), (0, 0, 0), thickness=-1) cv2.rectangle(mask, (350, 0), (640, 480), (0, 0, 0), thickness=-1) cv2.rectangle(mask, (0, 0), (640, 173), (0, 0, 0), thickness=-1) cv2.rectangle(mask, (0, 307), (640, 480), (0, 0, 0), thickness=-1)

Với x, y là tâm tiết diện đã được nhận diện của phôi, do sự chênh lệch giữa khung hình đo độ sâu và khung hình nhận diện phôi nên tọa độ tâm phôi trong khung đo độ sâu được tính bằng: (x – 25) và (y – 20).

Distance = depth[(y-20), (x-25)] Distance = Distance / 10

• Bước 3: Tính toán chiều cao phôi từ các giá trị khoảng cách đo được. Hình ảnh hiển thị:

Hình 3.37. Đo chiều cao sản phẩm

68

CHƯƠNG 4. THI CÔNG, TÍCH HỢP HỆ THỐNG 4.1. Thi công hệ thống cơ khí

4.1.1. Gối đỡ quả lô

Gối đỡ được làm bằng cách in 3D với vật liệu là nhựa PLA. Gối đỡ có tác dụng là đỡ 2 quả lô chủ động và bị động hạn chế 5 bậc tự do của quả lô (quả lô chỉ xoay quanh trục y).

Gối đỡ được cố định vào nhôm định hình bằng 2 con ốc M5x8 để hạn chế việc quả lô bị xoay theo trục y khi hệ thống hoạt động. Thêm vào đó để chắc chắc việc gối đỡ không bị xoay khi hệ thống làm việc nhóm đã thiết kế thêm một rãnh để ôm chắc vào nhôm định hình khi lắp ráp tránh hiện tượng lắp ráp sai cách.

Hình 4.1. Gối đỡ

4.1.2. Ổ bi

Ngoài ra gối đỡ còn lắp thêm vòng bi để tăng khả năng hiệu quả khi quay theo trục y của quả lô. Vòng bi giúp giảm ma sát giữa trục tang và gối đỡ, làm giảm việc hỏng hóc do ma sát lâu ngày.

Vòng bi nhóm chọn là vòng bi NSK608-RS là sản phẩm của công ty NSK Automation, là công ty sản xuất vòng bi lớn trên toàn cầu và lớn nhất tại Nhật Bản. Với kích thước nhỏ gọn đường kính ngoài 22mm, đường kính trong 8mm và dày 7mm rất phù hợp để sử dụng trong mô hình hệ thống của nhóm.

Vòng ngoài của vòng bi được lắp với mặt trong của trụ tròn được gia công trên quả lô còn vòng trong sẽ được lắp với trục tang, ở mỗi vị trí tiếp xúc sẽ được bôi mỡ thường xuyên để giảm ma sát và tăng tuổi thọ của vật liệu.

69

Kết hợp với việc bảo dưỡng thường xuyên thì sẽ làm tăng tuổi thọ, độ ổn định của hệ thống cũng như tính chính xác của hệ thống khi làm việc.

Hình 4.2. Vòng bi NSK608-RS khi lắp vào gối đỡ

4.1.3. Ru lô băng tải

Ru lô là bộ phận trung gian kết nối chuyển động giữa động cơ và dây băng tải. Băng tải của nhóm có 2 quả ru lô là ru lô chủ động và ru lô bị động. Ru lô chủ động được lắp hai vòng bi hai đầu được lắp cố định vào gối đỡ. Ru lô bị động cũng được lắp vòng bi hai đầu và đươc lắp vào gối đỡ sau đó được cố định vào hai thành khung băng tải bằng bu lông, đai ốc, giúp cho việc tháo lắp thay băng tải, căn chỉnh băng tải dễ dàng và thuận tiện hơn.

Ru lô của nhóm được làm bằng cách in 3D bằng vật liệu nhựa PLA với trục là thanh inox tròn đặc đường kính 8mm. Đối với quả lô chủ động sẽ được truyền chuyển động từ động cơ bằng bộ truyền đai răng.

70

4.1.4. Gá động cơ

Gá động cơ được làm bằng cách in 3D với vật liệu là nhựa PLA. Động cơ được gắn vào gá bằng 4 con bu lông M4x20 và 4 lỗ ren ở trên hộp giảm tốc của động cơ.

Vì là bộ phận phát động truyền động của cả hệ thống nên động cơ cần được cố định một cách chắc chắn, nên nhóm đã quyết định cố định động cơ vào khung của băng tải bằng bu lông và đai ốc M5. Để thêm chắc chắn thì nhóm đã thiết kế thêm một rãnh để bám vào nhôm định hình tăng độ bám của gá và tăng độ cứng vững cho động cơ để hệ thống hoạt động ổn định hơn.

Hình 4.4. Gá động cơ khi lắp vào khung

Hình ảnh sau khi động cơ đã gắn gắn vào gá động cơ

71 Mặt trước của gá động cơ:

Hình 4.6. Gá động cơ

4.1.5. Dây đai băng tải

Dây đai băng tải PVC (phần màu xanh trong hình 4.7) là loại dây chuyên dùng trong công nghiệp được làm từ chất liệu nhựa dẻo tổng hợp Poly Vinyl Clorua, có tính đàn hồi cao. Dây đai băng tải trong quá trình sử dụng sẽ tiếp xúc trực tiếp với sản phẩm tải, chịu trách nhiệm là phương tiện chở sản phẩm đến vị trí cần.

Dây đai băng tải là sản phẩm thích hợp dùng cho truyền tải các vật liệu có tính mật độ tách rời cao, chịu mài mòn nhiều, lực xung kích lớn, đặc biệt thích hợp làm việc trong môi trường làm việc có tính ổn định cao có độ nghiêng thấp hoặc tải thẳng. Phần dưới của dây đai băng tải được thiết kế các lớp bố để tăng ma sát bám vào ru lô nhằm không xảy ra hiện tượng trượt đai khi dây đai băng tải hoạt động lâu.

Dây đai băng tải hoạt động lâu thường xảy ra hiện tượng giãn đai, khi đó thì ta cần căng lại đai cho băng tải hoặc tùy vào điều kiện vận hành và chất lượng của đai băng tải có thể thay mới đai băng tải để hệ thống hoạt động ổn định nhất

72

4.2. Thi công hệ thống điều khiển 4.2.1. Nguồn điện 4.2.1. Nguồn điện

Với các thành phần linh kiện đã chọn, nhóm sử dụng 3 mức điện áp đảm bảo cho hệ thống hoạt động bình thường, bao gồm:

• Nguồn động cơ băng tải có sử dụng module L298: 24V

• Nguồn hỗ trợ Arduino nuôi cảm biến, động cơ servo: 5V

• Nguồn Adapter cho camera Kinect: 12V

(*Chú ý: Nguồn cấp tiêu chuẩn cho L298 là 12V, khi muốn sử dụng động cơ với mức điện áp 24V cần ngắt kết nối nguồn 24V với IC hạ áp trong module L298 (tháo Jump) tránh hỏng linh kiện.)

4.2.2. Cảm biến và động cơ tay gạt

Hệ thống có 4 cảm biến tiệm cận và 3 động cơ servo nên chân GND và VCC sẽ được nối chung sử dụng nguồn ngoài 5V và chân GND cần được nối chung với Arduino. Các dây tín hiệu còn lại được nối tới arduino như mô hình thiết kế chương 3.

Hình 4.8. Cảm biến và động cơ tay gạt

Do thời gian thực hiện giới hạn, nên nhóm chưa có phần thiết kế và thi công bo mạch mà chỉ chỉ sử dụng dây cắm trực tiếp trên các module.

4.2.3. Hiển thị và điều khiển

Màn hình LCD hiển thị số lượng phôi đã được phân loại: tròn cao, vuông cao, tam giác cao, thấp. Nút bấm Start dùng để ngắt động cơ băng tải

73

Bảng 4.1. Đấu nối nút bấm

Nút bấm Cách đấu nối Chức năng

START 1 chân nút bấm nối đến 1 trong 2 cực của động cơ, chân còn lại nối đến cổng OUT2 của module L298

Bật động cơ băng tải, khởi động hệ thống. STOP 1 chân nối đến GND, chân còn lại nối đến

chân 8 trên Arduino

Dừng hệ thống khi đã chạy hết chu trình.

RESET 1 chân nối đến GND, chân còn lại nối đến chân 12 trên Arduino

Đặt lại các giá trị về giá trị ban đầu.

Hình 4.9. Mặt trên hộp điện

4.3. Xây dựng chương trình, kết nối hệ thống

Chương trình phân loại phôi đươc viết trên phần mềm Pycharm sử dụng ngôn ngữ Python trên phiên bản 3.7. Chương trình điều khiển được viết trên phần mềm Arduino IDE sử dụng ngôn ngữ C.

74

Hình 4.10. Hệ thống sau khi đã hoàn thiện

• Cài đặt Pycharm và Arduino IDE:

Hình 4.11. Cài đặt Pycharm và Arduino IDE

Dữ liệu từ camera Kinect được khai thác và sử dụng bằng máy tính cá nhân thông qua phần mềm Pycharm các dữ liệu được xử lý và được gửi vào Arduino thông qua giao tiếp Serial.

Cài đặt các thư viện sử dụng trên Pycharm bao gồm:

• SerialDevice: Truyền thông tin giữa thiết bị xử lý dữ liệu và thiết ngoại vi.

• Opencv-python: xử lý dữ liệu hình ảnh, thị giác máy tính.

• Openni: Thao tác với dữ liệu trên Kinect.

• Numpy: một thư viện toán học cho phép làm việc hiệu quả với ma trận và mảng với tốc độ xử lý nhanh hơn “Core Python” đơn thuần.

Một phần của tài liệu Đồ án phân loại sản phẩm, dùng camera Kinect (Trang 72)

Tải bản đầy đủ (PDF)

(110 trang)