• Nenhum resultado encontrado

Hình tròn biếu diễn các sắc màu (H: 0-360) và độ bão hòa (S: 0-1) Màu đỏ: H=0,

Hệ màu HSV có 3 tham số:

 S (saturation) (0-1): độ bão hòa. Chỉ ra mức độ “thuần” của màu, màu có S càng lớn thì càng “rõ”, ngược lại thì càng “mờ”. Tại S=0 sắc màu không còn giá trị, mọi H đều chỉ cho màu xám hoặc trắng.

 V (value, có nơi ghi B: Brightness) (0-1): độ phát sáng. Đó là cường độ ánh sáng mà tự đối tượng phát ra chứ không phải do phản xạ từ các nguồn sáng khác.

Hệ màu HSV này được biểu diễn bởi một hình nón ngược (Hình 3.1-1).

Trong đó H (màu sắc) được biểu diễn bằng góc quay quanh trục đứng của hình nón, vì vậy H có giá trị 0-360o, với:

 Màu đỏ có H = 0o

 Màu xanh lá có H = 120o

 Màu xanh dương có H = 240o

S là khoảng cách từ trục hình nón tới điểm xét màu. S có giá trị thực nằm trong đoạn 0-1. Tại trục: S = 0, tại vành ngoài cùng: S = 1. Ta có thể quan sát thấy màu của S càng “rõ” khi càng nằm gần vành (S>0). Với S = 0 thì H không còn { nghĩa, như trong hình, tại trục của hình nón chỉ có màu xám và trắng.

Độ phát sáng V (hay B) là khoảng cách từ đỉnh dưới của hình nón (vì hình nón bị lật ngược) tới mặt cắt ngang hình nón chứa điểm xét màu. Tại đỉnh (bên dưới) của hình nón, V có giá trị là 0, tại đó là màu đen (không có ánh sáng). V = 1 tại tâm của mặt đáy phía trên, tại đó là màu trắng (H: không xác định, S=0, V= 1).

Một tính chất quan trọng của hệ màu HSV là các màu được đặc trưng bằng sắc độ (H). Tức là một vật thể có một màu nhất định thì H của nó thay đổi rất ít trong các độ sáng khác nhau của môi trường. Nghĩa là, ví dụ, một vật thể có màu vàng với H = 32. 3 thì khi môi trường thay đổi độ sáng, chỉ có giá trị S và V của nó (màu của vật thể) là thay đổi, còn H chỉ dao động trong khoảng 32.3 ± 6. Đây là tính chất khiến ta chọn HSV để làm hệ màu cho ảnh muốn phân ngưỡng (mục 3.3).

3.1.2 Chuyển từ màu RGB sang HSV

Như mục trên vừa trình bày, trong lý thuyết của hệ màu HSV thì:

 H: Sắc độ màu [0-360] với màu đỏ tại điểm 0

 S: Độ bão hòa [0-1]

 V: Giá trị cường độ sáng [0-1]

Nhưng trong OpenCV, HSV được lưu giống như RGB, tức 1 byte cho một giá trị H, S và V, nên khoảng có giá trị 0-255.

Bởi vì H có giá trị lớn hơn 255 nên nó được lưu là H/2, ví dụ: H = 240 (màu xang dương) thì OpenCV lưu H = 240/2 = 120. Còn S và V thì được giãn thành 0-255 (số nguyên) tương

ứng cho khoảng 0-1 (số thực). Đây là một lưu { quan trọng để biểu diễn màu HSV trong OpenCV.

Thuật toán Chuyển từ màu RGB sang HSV:

(Thuật toán này tính toán trên lý thuyết. Sau khi có được giá trị trên lý thuyết (Hl, Sl, Vl) (với Hl: 0-360, Sl: 0-1, Vl: 0-1) ta chuyển về giá trị được lưu bởi OpenCV: H=Hl/2, S = Sl*255, V = Vl*255) Đặt: M = max (R, G, B) m = min (R, G, B) C = M – m  Giá trị H: H = 60 * 𝑘𝑕ô𝑛𝑔 𝑥á𝑐 đị𝑛𝑕, 𝑛ế𝑢 𝐶 = 0 𝐺−𝐵 𝐶 𝑚𝑜𝑑 6, 𝑛ế𝑢 𝑀 = 𝑅 𝐵−𝑅 𝐶 + 2, 𝑛ế𝑢 𝑀 = 𝐺 𝑅−𝐺 𝐶 + 4, 𝑛ế𝑢 𝑀 = 𝐵  Giá trị S = 0, 𝑛ế𝑢 𝐶 = 0𝐶 𝑀, 𝑛𝑔ượ𝑐 𝑙ạ𝑖  Giá trị V = M/255 Thuật toán hoàn thành.

Chú ý: mod là phép chia lấy dư trên SỐ THỰC (như hàm MOD trong MS Excel hoặc mod trên http://www.wolframalpha.com).

Nói thêm: vậy trong đề tài của chúng ta, để lấy được khoảng ngưỡng tối ưu ta làm như sau:

Chụp một hình chứa vật thể.

Pick một màu ra (dùng MS Paint hoặc phần mềm rgbhsv)

Tính H, S, V theo thuật toán trên (nhớ đổi sang dạng của OpenCV sau khi tính (H: 0-

180)) Chú ý:

Nhất thiết phải tính H theo thuật toán trên, chứ H từ các chương trình hoặc code

khác là không đúng.

H thì thường biến thiên rất ít đối với một màu, ta chỉ cần +, - 3 vào H đã tính là có

Còn S, V thì chương trình rgbhsv đã tính đúng, có thể dùng để tra khoảng biến thiên của 2 đại lượng này cho thuận tiện.

Ví dụ: ta có màu với giá trị RGB = (195, 125, 43) (màu vàng hơi tối nâu).

Ta tính:  M = 195 (R)  m = 43  C = M-m = 152 Giá trị H:  (G-B)/C = 0.5395  0.5395 mod 6 = 0.5395  0.5395*60 = 32.37o (giá trị lý thuyết)

 Giá trị lưu trong OpenCV là: H = 32.37 / 2 = 16 Giá trị S:

 C/M = 0.7795 (giá trị lý thuyết)

 Giá trị lưu trong OpenCV là: S = 0.7795*255 = 198 Giá trị V:

 M/255 = 0.7647

 Giá trị lưu trong OpenCV là: V = 0.7647*255 = 195

3.2 Moment của ảnh (image moment)

Moment 2 chiều của bậc (p+q) của một ảnh f(x, y) có kích thước MxN được định nghĩa là: Mpq = 𝑀−1𝑥 =0 𝑁−1𝑦 =0𝑥𝑝𝑦𝑞𝑓(𝑥, 𝑦)

trong đó p=0, 1, 2,… và q=0, 1, 2,… là số nguyên.

Một số tính chất ảnh đơn giản được đặc trưng bởi moment ảnh là:

Diện tích (cho ảnh nhị phân13) hoặc tổng mức xám (đối với ảnh xám14): M00.

Tâm ảnh: {xc, yc} = {M10/ M00, M01/ M00}

2 tính chất trên của moment sẽ được dùng trong phần phát hiện đối tượng theo màu sắc.

3.3 Thuật toán phát hiện đối tƣợng theo màu sắc

Từ những kiến thức trình bày trong các phần trên, ta có thể xây dựng một thuật toán phát hiện đối tượng theo màu sắc đơn giản như sau:

13 Ảnh nhị phân: là ảnh có màu trắng (f = 255) và đen (f = 0). 14

(1) Chuyển từ ảnh RGB (hoặc các hệ màu khác) về HSV.

(2) Thực hiện phân ngưỡng ảnh: tạo ảnh nhị phân từ ảnh HSV với ngưỡng trên và dưới thích hợp (tham khảo cách lấy ngưỡng trong mục 3.1.2). Các điểm ảnh nằm trong khoảng ngưỡng trên và ngưỡng dưới sẽ có giá trị 1 (trắng), còn các điểm còn lại sẽ có giá trị 0 (đen).

(3) Làm mịn ảnh phân ngưỡng để loại bỏ các điểm nhiễu (có thể dùng lọc trung vị). (4) Tính toán các moment M00, M10 và M01 để lấy tâm của vật thể (xc, yc) = (M10/ M00,

M01/ M00).

Thuật toán hoàn thành.

Có một số điểm cần lưu { trong thuật toán trên:

 Hệ màu được chọn ở bước 1 phải là HSV. Có một hệ màu tương tự được dùng trong nhiều hệ thống là HSL. Mặc dù 2 hệ màu này dựa trên cùng một { tưởng về

Sắc màu, Độ bão hòa và Độ sáng, nhưng chúng có những khác biệt khiến cho hệ

màu HSL không phải là ứng viên tốt nhất cho phân ngưỡng ảnh theo màu (sắc độ).

 Khi lấy các giá trị ngưỡng, nếu tìm được một ngưỡng (một màu) có trong hệ RGB ta phải chuyển nó về hệ HSV theo theo thuật toán trình bày ở mục 3.1.2. Có nhiều chương trình (và cả code) chuyển từ màu RGB sang HSV nhưng chúng không chính xác và điều này dẫn tới thất bại trong việc phân ngưỡng ảnh. Ngoài ra ta cũng phải lưu ý cách biểu diễn màu HSV trong OpenCV là HSV = (0-180, 0-255, 0-255) để đưa giá trị vào chương trình cho đúng.

 Điểm lưu { sau cùng là về bước (3). Trong thực tế cài đặt, nếu ta tiến hành làm mịn ảnh (khử nhiễu) sẽ ảnh hưởng rất nhiều tới hiệu năng của chương trình (chương trình sẽ chậm đi rõ rệt). Bên cạnh đó việc này cũng không cần thiết lắm ở chương trình của chúng ta bởi vì màu của vật thể mà ta chọn khá khác biệt với môi trường, nên nếu ta chọn ngưỡng tốt thì hầu như ảnh sau phân ngưỡng sẽ không có nhiễu15. Cho nên giải pháp ở đây (cho phần cài đặt) là bỏ qua bước 3. Thay vào đó, đơn giản ta chỉ dùng một câu lệnh điều kiện:

nếu (M00 < diện_tích_min) thì quay lại bƣớc (1)

Câu lệnh trên có nghĩa là nếu diện tích của vật thể (M00) nhỏ hơn một giá trị nào đó

(diện_tích_min) thì ta bỏ qua việc tính tọa độ tâm, xem như đó là một nhiễu chứ không phải vật thể (vì vật thể của ta luôn có kích thước lớn hơn diện_tích_min này).

3.4

Cài đặt thuật toán phát hiện vật thể dựa theo màu sắc với

OpenCV

Trong OpenCV có hỗ trợ chúng ta các hàm dùng cho thuật toán phát hiện vật thể theo màu sắc vừa trình bày.

15

Hàm cvCvtColor void cvCvtColor( const CvArr* src, CvArr* dst, int code );

Hàm này dùng để chuyển ảnh từ một hệ màu này sang hệ màu khác. Trong đó src là ảnh nguồn, dst là ảnh đầu ra, và code là mã chuyển. Một số code thường dùng:

 CV_BGR2RGB: chuyển từ BGR sang RGB

 CV_RGB2BGR: chuyển từ RGB sang BGR

 CV_RGB2RGBA: thêm tham số Alpha cho hệ màu RGB

 CV_BGR2BGRA: thêm tham số Alpha cho hệ màu BGR

 CV_BGR2HSV: chuyển từ BGR sang HSV (ta dùng mã này trong chương trình)

Hàm cvInRangeS void cvInRangeS( const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst );

Hàm này tạo ra ảnh phân ngưỡng. Trong đó, src là ảnh nguồn và dst là ảnh đầu ra. lower và upper là 2 ngưỡng của ta, nó có dạng là một 3 giá trị (H, S, V).

Hàm cvMoments

void cvMoments(

const CvArr* image, CvMoments* moments, int isBinary = 0 );

Hàm này thực hiện tính toán các moment của ảnh, trong đó image là ảnh cần tính moment và moments là một biến cấu trúc chứa các moment của ảnh.

typedef struct CvMoments { // spatial moments

double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03; // central moments

double mu20, mu11, mu02, mu30, mu21, mu12, mu03; // m00 != 0 ? 1/sqrt(m00) : 0

double inv_sqrt_m00; } CvMoments;

Bằng việc sử dụng các hàm trên chúng ta có thể dễ dàng cài đặt thuật toán phát hiện vật thể dựa trên màu. Code cụ thể cho phần này sẽ được trình bày trong chương 4.

4 Chương

4

Thiết Kế Và Cài Đặt

Chương Trình Phát Hiện Di Động

Các nội dung chính:  Thiết kế chương trình: Mô hình hệ thống và Bộ đo.

 Cài đặt: Hoạt động của chương trình và Các đoạn mã quan trọng.

4.1 Thiết kế

4.1.1 Mô hình hệ thống

Như đã trình bày trong chương 2, các ước lượng sử dụng bộ lọc Kalman phải gồm 2 phần: Mô hình hệ thống (tính toán giá trị ước lượng cho trạng thái hệ thống) và Cảm biến (lấy giá trị đo thực tế của trạng thái). Trong mục này chúng sẽ trình bày về mô hình của hệ thống. Mục đích của chúng ta là xây dựng một mô hình theo dõi vật thể chuyển động, như vậy chúng ta có thể mô hình hệ thống như sau:

4.1.1.1 Vector trạng thái

Vector trạng thái là một vector cột chứa 4 thành phần:

xk = 𝑥 𝑦 𝑣𝑥 𝑣𝑦

Trong đó x, y là tọa độ của vật thể, vx, vy là vận tốc theo phương x và y. Ở đây chúng ta xem

vật thể có một chuyển động với vận tốc không đổi nên ta có ma trận chuyển trạng thái như sau: Ф = 1 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1

Nếu lấy ma trận chuyển trạng thái nhân với vector trạng thái ta sẽ có trạng thái ở bước sau: xk+1 = Ф xk = 1 0 1 0 0 1 0 1 0 0 1 0 0 0 0 1 𝑥 𝑦 𝑣𝑥 𝑣𝑦 = 𝑥 + 𝑣𝑥 𝑦 + 𝑣𝑦 𝑣𝑥 𝑣𝑦 Tức là ta có xk+1 = xk + vx và yk+1 = yk + vy. 4.1.1.2 Nhiễu hệ thống

Bởi vì vector trạng thái có kích thước 4x1 nên vector nhiễu hệ thống wk cũng phải cùng kích

thước 4x1. Do đó ma trận hiệp phương sai của nhiễu hệ thống Q là một ma trận 4x4:

Q = 10−3 0 0 0 0 10−3 0 0 0 0 10−3 0 0 0 0 10−3 Nó là một ma trận chỉ có các phần tử trên đường chéo chính (chỉ số hàng = chỉ số cột) khác không, bởi vì ta giả thiết rằng nhiễu của các giá trị khác nhau là độc lập thống kê. Ví dụ nhiễu của x và y là độc lập thống kê nên Cov(x, y) = 0. Đối với các giá trị trên đường chéo

chính, đó là phương sai của biến ngẫu nhiên đó, ví dụ: phần tử 0, 016 chính là Var(X). Các giá trị này thể hiện độ lớn của khoảng giá trị của nhiễu (hay nói cách khác chính là độ lớn của nhiễu). Như ta đã biết, bộ lọc Kalman giả định các nhiễu có phân phối chuẩn với kz vọng bằng 0 (hàm mật độ đối xứng qua trục Oy), vì vậy, nếu phương sai (hay độ lệch chuẩn) càng lớn thì các giá trị x lớn sẽ có xác suất cao hơn. Ngược lại, nếu phương sai càng nhỏ thì các giá trị càng tập trung quanh giá trị kz vọng (ở đây là 0), các điểm x có giá trị lớn sẽ có xác suất gần bằng 0.

Như vậy, tóm lại, nếu ta muốn (hay nghĩ rằng) nhiễu có giá trị lớn thì cho phương sai (các giá trị trên đường chéo) lớn và ngược lại.

Biểu đồ 4.1-1 Một số phân phối Gauss,

với phương sai σ2 càng lớn thì các giá trị x có giá trị lớn (xa kỳ vọng) sẽ có xác suất cao hơn 4.1.1.3 Vector đo

Mặc dù vector trạng thái có 4 thành phần, nhưng các giá trị ta ước đoán chỉ có 2, đó là tọa độ x và y. Vì vậy vector đo zk của chúng ta cũng chỉ có 2 thành phần x, y:

zk =

𝑥 𝑦

Bởi vì vector trạng thái có kích thước 4x1, vector đo có kích thước 2x1 nên ma trận đo H (thể hiện quan hệ tuyến tính giữa x và z) sẽ có kích thước 2x4: (2x1) = (2x4)(4x1)

16

H = 1 0 0 0 0 1 0 0

Ma trận H trên thể hiện đúng quan hệ của x và z, bởi vì x và z đều là các tọa độ:

zk = Hxk = 1 0 0 0 0 1 0 0 𝑥 𝑦 𝑣𝑥 𝑣𝑦 = 𝑥𝑦

Nói thêm về ma trận đo: Ma trận đo là ma trận thể hiện quan hệ tuyến tính giữa trạng thái và giá trị đo. Xem lại Ví dụ dẫn nhập mục 2.2.4, chương 2, ta có bộ phận định vị trả về tọa độ nên giá trị đo có quan hệ với trạng thái quan tâm x - tọa độ của vật thể, là:

z = a.x, a là hệ số tuyến tính (mà ở đây là ma trận H)

Trong trường hợp khác, nếu ta không có bộ phận định vị trả về tọa độ mà có đồng hồ vận tốc trả về vận tốc, thì khi đó vector đo z là vận tốc và dĩ nhiên nó không bằng x. Giữa z và x khi đó sẽ có một hệ số tuyến tính a khác. Chằng hạn trong chuyển động đều thì:

z = (1/t) * x, a = (1/t), t là thời gian tính từ lúc x = 0.

Như vậy, ta lại có thêm một lưu { nữa, hệ số a (hay ở đây là ma trận H) có thể thay đổi theo thời gian.Tuy nhiên trong trường hợp của chúng ta thì nó phải là không đổi.

4.1.1.4 Nhiễu đo

Bởi vì vector đo có kích thước 2x1 nên vector nhiễu đo wk cũng có kích thước là 2x1, do đó

ma trận hiệp phương sai của nhiễu đo R sẽ là ma trận có kích thước 2x2. R = 10−4 0

0 10−4

Như trong mục 4.1.2 đã nói, các giá trị không nằm trên trên đường chéo sẽ bằng 0 bởi vì nhiễu của các thành phần khác nhau là độc lập nhau.

Các giá trị trên đường chéo chính càng lớn thì nhiễu có thể càng lớn. Ở đây ta cho nhiễu càng nhỏ chứng tỏ ta càng tin tưởng phép đo (nhiễu ở đây có thể coi là sai số của phép đo).

4.1.2 Bộ đo

Bộ đo cho ra giá trị của vector đo z ở đây chính là hàm phát hiện vật thể dựa trên màu sắc viết theo thuật toán trình bày trong chương 3. Đầu ra của hàm này là tọa đô tâm của vật thể quan tâm.

Ngoài ra còn có 2 giá trị cần khởi tạo đó là:

 Hậu nghiệm của bước 0: ta khởi tạo với giá trị ngẫu nhiên.

4.2 Cài đặt

Chương trình viết cho đồ án này sử dụng thư viện OpenCV 2.1 (xem cách cài đặt và thiết lập trong phần Phụ lục) với ngôn ngữ lập trình C++, CLR Windows Forms Application project, IDE Visual Studio 2008.

4.2.1 Hoạt động của chương trình

Chương trình có 3 form chính: Cửa sổ điều khiển, Camera và Khung nhìn.

 Cửa sổ điều khiển: form này thể hiện các chức năng của chương trình:

 Theo dõi (mặc định): theo dõi vị trí của vật thể có màu quan tâm (vàng và hồng).

 Vẽ: vẽ các đường theo di chuyển của vật thể.

 Điều khiển: di chuyển, zoom một ảnh theo chuyển động và sự xuất hiện của các vật thể.

 Thoát: dừng và thoát chương trình.

 Giới thiệu: hiện cửa sổ thông tin về chương trình.

Documentos relacionados