Waxman, Wu và Bergholm [41] áp dụng các bộ lọc không-thời gian với các ánh xạ cạnh nhị phân để theo vết các cạnh trong thời gian thực. Các ánh xạ cạnh E(x, t) dựa trên một điểm về không DOG [29], được làm trơn bởi bộ lọc Gaussian để tạo mộtkích hoạt quy ước A(x, t):
𝐴𝐴(𝐱𝐱,𝑡𝑡) = 𝐺𝐺�𝑥𝑥,𝑡𝑡;𝜎𝜎𝑥𝑥,𝜎𝜎𝜕𝜕,𝜎𝜎𝑡𝑡� ∗ 𝐸𝐸(𝐱𝐱,𝑡𝑡). (2.34)
Các chu tuyến của A(x, t) sau đó được theo vết sử dụng các phương pháp vi phân. Tuy nhiên, do gradient không gian của A(x, t) bằng không ở các vị trí biên, nên một tiếp cận bậc hai được sử dụng, áp dụng các ràng buộc trong (2.4) với A(x, t). Các vận tốc ước lượng ở vị trí biên được tính bởi:
𝐯𝐯=(𝐴𝐴𝑥𝑥𝑡𝑡𝐴𝐴𝜕𝜕𝜕𝜕 − 𝐴𝐴𝐴𝐴𝜕𝜕𝑡𝑡𝐴𝐴𝑥𝑥𝜕𝜕, 𝐴𝐴𝜕𝜕𝑡𝑡𝐴𝐴𝑥𝑥𝑥𝑥 − 𝐴𝐴𝑥𝑥𝑡𝑡𝐴𝐴𝑥𝑥𝑦𝑦)
𝑥𝑥𝑥𝑥𝐴𝐴𝜕𝜕𝜕𝜕− 𝐴𝐴𝑥𝑥𝜕𝜕2 (2.35)
Để sử dụng cho thực nghiệm, trọng tâm Gaussian của DOG có độ lệnh chuẩn là 1.5 pixels-frames và tỷ lệ tới trọng tâm là 1.6. Với A(x, t) ta sử dụng:
𝜎𝜎𝑥𝑥 = 𝜎𝜎𝜕𝜕 = 2.0 và 𝜎𝜎𝑡𝑡 = 1.0.
Waxman và cả nhóm cũng đề xuất một phương pháp đa 𝜎𝜎 trong đó nó cố gắng lựa chọn vận tốc tốt nhất trên một vị trí biên.
Cho các giá trị 𝜎𝜎𝑥𝑥 = 𝜎𝜎𝜕𝜕khác nhau (1.0, 1.5 và 2.0)ta lựa chọn vận tốc để cực đại hàmsau:
𝑚𝑚𝑑𝑑𝑥𝑥 �𝜎𝜎 2𝜎𝜎𝑡𝑡
𝑥𝑥+𝜎𝜎𝜕𝜕‖𝐯𝐯‖2� (2.36)
Cuối cùng, Waxman đề xuất một giá trị Hessian của A để cung cấp độđo mức tin cậy của các vận tốc. Nếu Hessian là lớn hơn hoặc bằng một ngưỡng 𝜏𝜏 (thường sử
37
dụng 𝜏𝜏 = 0.5), thì vận tốc toàn phần được tính ở vị trí biên. Nếu nó nhỏ hơn ngưỡng 𝜏𝜏 ta có thể sử dụng tính toán vận tốc chính tắc:
(𝑢𝑢𝑛𝑛,𝑣𝑣𝑛𝑛) = − 1
∇2𝐴𝐴�𝐴𝐴𝑥𝑥𝑡𝑡,𝐴𝐴𝜕𝜕𝑡𝑡�(2.37)
2.4.2. Thuật toán Fleet - Jepson
Phương pháp phát triển bởi Fleet và Jepson [11] định nghĩa thành phần vận tốc dưới dạng chuyển động tức thời chuyển hóa sang các chu tuyến ở mức pha trong các bộ lọc thông dải điều chỉnh vận tốc. Các bộ lọc thông dải được sử dụng để tách tín hiệu đầu vào dựa trên tỷ lệ, vận tốc và hướng. Mỗi đầu ra bộ lọc là các giá trị phức tạp và có thểđược viết bởi công thức sau:
𝑅𝑅(𝐱𝐱,𝑡𝑡) =𝜌𝜌(𝐱𝐱,𝑡𝑡) exp[𝑖𝑖∅(𝒙𝒙,𝑡𝑡)] (2.38)
trong đó 𝜌𝜌(𝐱𝐱,𝑡𝑡) và ∅(𝒙𝒙,𝑡𝑡) là các phần biên độ và pha của R. Thành phần của vận tốc 2-d từ dạng chiều tới chu tuyến pha được cho bởi công thức vn = sn, trong đó vận tốc chính tắc và chiều được cho bởi:
𝑠𝑠 = ‖∇∅−∅𝑡𝑡((𝐱𝐱𝐱𝐱,,𝑡𝑡𝑡𝑡))‖, 𝑠𝑠=
∇∅(𝐱𝐱,𝑡𝑡)
‖∇∅(𝐱𝐱,𝑡𝑡)‖ (2.39)
trong đó ∇∅(𝐱𝐱,𝑡𝑡) =�∅𝑥𝑥(𝐱𝐱,𝑡𝑡),∅𝜕𝜕(𝐱𝐱,𝑡𝑡)�𝑇𝑇. Để hiệu quả, kỹ thuật vi phân nên được áp dụng cho pha hơn là cho cường độ. Các đạo hàm pha được tính theo công thức sau:
∅𝑡𝑡(𝐱𝐱,𝑡𝑡) =Im[𝑅𝑅∗|𝑅𝑅(𝐱𝐱(,𝐱𝐱𝑡𝑡,)𝑡𝑡𝑅𝑅)|𝑥𝑥2(𝐱𝐱,𝑡𝑡)](2.40)
trong đó 𝑅𝑅∗ là liên hợp phức của R.
Việc sử dụng pha được thúc đẩy do thành phần pha trong các đầu ra của bộ lọc thông dải là ổn định hơn so với thành phần biên độ khi các độ lệch nhỏ trong các ảnh chuyển dịch. Tuy nhiên, các pha cũng có thể không ổn định với các bất ổn xảy ra ở các vùng lân cận của các suy biến pha. Sự bất ổn này có thể tìm được với một ràng buộc trực tiếp trên tần số tức thời của đầu ra bộ lọc và biến thiên biên độ của nó trong không - thời gian:
38
trong đó (k, 𝜔𝜔) là tần số không- thời gian của bộ lọc đã hiệu chỉnh, 𝜎𝜎𝑘𝑘 là độ lệch chuẩn của biên độ sử dụng và 𝜏𝜏 là một ngưỡng được sử dụng để loại bỏ các thành phần không đáng tin cậy của các độ đo vận tốc. Khi 𝜏𝜏 giảm thì đầu ra bộ lọc được ràng buộc chặt hơn và bởi thế các vùng lân cận suy biến lớn hơn sẽ được phát hiện. Trong thực nghiệm, ta thiết lập 𝜏𝜏 = 1.25. Ràng buộc thứ hai trên biên độ của phản hồi cũng được sử dụng để bảo đảm một tỷ lệ tín hiệu trên nhiễu hợp lý.
Cuối cùng, cho trước các ước lượng thành phần vận tốc từ các kênh lọc sai khác, một mô hình vận tốc tuyến tính được tính phù hợp cho mỗi vùng cục bộ. Các ước lượng này thỏa mãn tính ổn định và các ràng buộc tỷ lệ tín hiệu trên nhiễu (SNR) thu thập được từ các vùng lân cận 5x5, tới mô hình vận tốc tuyến tính tốt nhất được xác định. Để bảo đảm có thông tin đầy đủ để ước lượng vận tốc tin cậy, các tác giả đưa ra các ràng buộc trên hệ thống tuyến tính và lỗi dư thừa tuyến tính. Để chứng minh các kết quả, Fleet và Jepson chỉ xét các độđo vận tốc hai chiều với sốđiều kiện nhỏhơn 10.0 và lỗi dư thừa nhỏhơn 0.5.
2.5. Thành lập công thức tính vận tốc thật của phương tiện
Sơ đồ quy chiếu từ video sang thực tế sẽ giúp ta có cái nhìn trực quan hơn về công thức tính toán vận tốc thực tế của phương tiện giao thông (hình 2.4)
Hình 2.4: Sơ đồ quy chiếu từ video sang thực tế
Xây dựng công thức liên hệ giữa vận tốc thực tế của một điểm chuyển động trên đường với sốlượng điểm ảnh chuyển động qua 2 frame liên tiếp được thực hiện như sau:
• Để có thểtính được vận tốc thật của xe, một yêu cầu cần thiết là phải xác định được kích thước của đường mà camera có thể quan sát được, ta gọi là
39
(D1xD2) như trong hình 2.4.
• Tại mỗi thời điểm, khi áp dụng các thuật toán luồng quang học ở trên, ta có các mảng chứa thông tin về toạ độ của các vật thể ở frame trước và frame hiện tại, được lưu trữ trong các mảng.
• Không mất tính tổng quát, ta xét 1 điểm của 1 vật thểở hai frame liên tiếp. Ở frame thứ nhất điểm có toạ độ (x1,y1), ở frame thứ hai là (x2,y2). Độ dịch chuyển của điểm theo chiều x và y lần lượt là:
∆x = x1 – x2 (pixel) (2.42) ∆y = y1 − y2 (pixel) (2.43)
• Ta có thể xác định được độ dịch chuyển thật của điểm trên mặt đất như sau (đối với trường hợp kích thước khung hình video thu được là 320x240, trên thực tế có thể khác và ta thay bằng các giá trị phù hợp):
∆ X = (x1-x2)* D1/320 (m) (2.44) ∆Y = (y1 − y2) ∗ D2/240 (m) (2.45)
• Độ di chuyển của xe trên thực tế:
∆𝐷𝐷 = √∆𝑋𝑋2+ ∆𝑌𝑌2 (m) (2.46)
• Đây là độ dịch chuyển của xe qua 2 frame liên tiếp, do đó, để tính vận tốc di chuyển của xe, ta nhân độ di chuyển với tốc độ frame R (fps):
V = ∆D ∗ R (m/s) = 3.6 ∗ ∆D ∗ R (km/h) (2.47)
2.6. Kết luận chương
Chương này của luận văn đã trình bày tương đối chi tiết 9 kỹ thuật dựa trên luồng quang học bao gồm các phương pháp vi phân, so khớp vùng, dựa trên năng lượng và pha, đó là các thuật toán: Horn and Schunck, Lucas and Kanade, Uras, Nagel, Anandan, Singh, Heeger, Waxman và Fleet and Jepson.
Ở cuối chương cũng trình bày phương pháp xác định vận tốc thật của phương tiện khi đã có kết quả các véc tơ vận tốc thu nhận được ở dạng điểm ảnh bằng các thuật toán ởtrên. Phương pháp này sẽ làm cơ sởđểtiến hành cài đặt và thực nghiệm chương trình xác định vận tốc chuyển động của các phương tiện xuất hiện trong các video thu nhận được từ hệ thống camera giao thông.
40
Chương 3: CÀI ĐẶT THUẬT TOÁN, THỰC NGHIỆM VÀ ĐÁNH GIÁ
Trong chương này tác giả tiến hành cài đặt một số thuật toán tiêu biểu ở chương 2 (Lucas-Kanade, Farneback, Region-based Matching, Horn-Schunck) với bộ thư viện OpenCv để xác định vận tốc của các phương tiện trong các video thu được từ camera giao thông, thực hiện trên các video và đánh giá và so sánh các thuật toán về tốc độ xửlý, độ chính xác của các kết quảthu được.
3.1. Phát hiện chuyển động3.1.1. Trừ nền 3.1.1. Trừ nền
Trước khi theo vết các chuyển động, hệ thống cần phải trích xuất ra đối tượng. Kỹ thuật phổ biển để nhận được đối tượng từảnh 2D là trừ nền. Lý do để sử dụng việc trừ nền đó là chúng hoạt động tốt trong trường hợp ảnh nền là tĩnh trong một thời gian dài. Mà trong thực tế, khi ta lắp camera tại vị trí cố định để giám sát giao thông thì ảnh nền thu nhận được là tĩnh trong một thời gian dài.
OpenCV cung cấp nhiều kỹ thuật khác nhau để loại bỏ nền tĩnh từ khung ảnh thu nhận được. Một trong các kỹ thuật đó là mô hình nền MoG. Hàm MoG cung cấp trong thư viện OpenCV đã được cập nhật và sửa đổi một vài lần. Trong phiên bản trước của OpenCV (phiên bản 2.1, cập nhật tháng 4/2010), hàm MoG được viết lại để tăng độc chính xác và hiệu năng. Hàm MoG của thư viện OpenCV được dựa trên một phiên bản cải tiến của thuật toán MoG (KaewTraKulPong and Bowden, 2001). Mặc dù từ các phiên bản 2.2 trở đi của OpenCV, việc phát hiện bóng được đề xuất trong bài báo này không được thực thi nữa, nhưng nó không ảnh hưởng đến kết quả nhiều vì bóng cũng có thể được xem xét như là một phần của đối tượng.
Để thực hiện hàm này, trong thư viện OpenCV ta gọi hàm
cvCreateGaussianBGModel. Hàm cvCreateGaussianBGModel yêu cầu tối thiểu một tham số, đó là frame thu nhận được tại thời điểm hiện tại từ camera hoặc từ chuỗi hình ảnh (video).
cvCreateGaussianBGModel ( IplImage* frame,
41
);
(a) (b)
Hình 3.1: Ảnh tách nền riêng (a) và đối tượng chuyển động riêng (b)
3.1.2. Tạo chu tuyến và đánh dấu đối tượng
Sau khi đã trừ nền thành công để trích ra ảnh nền, ta sẽ vẽ chúng dưới dạng ảnh nhị phân. Việc tiếp theo cần làm là đánh dấu các đối tượng. Tạo chu tuyến là việc xửlý đểđánh dấu đường viền các cạnh của đối tượng, làm cho chúng dễ được nhận biết hơn. Trong lĩnh vực thị giác máy tính, biên của các đối tượng thường được định nghĩa là vùng các điểm ảnh mà tương phản với vùng lân cận hoặc vùng chuyển động của nó.
Hàm để tìm và tạo chu tuyến trong OpenCV rất hữu dụng, nó cung cấp các thông tin bổ sung của đối tượng như kích thước, điểm trọng tâm, các điểm có thể được sử dụng để vẽ một hình hộp bao quanh đối tượng. Điểm trọng tâm của đối tượng rất hữu ích cho bước xử lý tiếp theo đó là theo vết đối tượng, nó hoạt động như một điểm đặc trưng tốt (good feature point) cho đối tượng.
Hàm tạo chu tuyến trong OpenCV sử dụng cấu trúc dữ liệu tương tự như các danh sách liên kết lưu trữ các nút chu tuyến, trong đó các nút chu tuyến này thường là góc hoặc chỗ lượn của đối tượng. Trước khi các chu tuyến được vẽ, hàm cvFindContours cần được thực hiện để lấy được danh sách các nút chu tuyến:
int cvFindContours( IplImage* img,
CvMemStorage* storage, CvSeq** firstContour,
42
int headerSize = sizeof(CvContour),
CvContourRetrievalMode mode, = CV_RETR_LIST,
CvChainApproxMethod method = CV_CHAIN_APPROX_SIMPLE );
Sau khi lấy được danh sách các nút chu tuyến, ta tiến hành vẽ chu tuyến với việc sử dụng hàm: void cvDrawContours ( CvArr *img, CvSeq* contour, CvScalar external_color, CvScalar hole_color, int max_level,
int thickness CV_DEFAULT(1), int line_type CV_DEFAULT(8),
CvPoint offset CV_DEFAULT(cvPoint(0,0)) );
Xác định một hình hộp bao quanh đối tượng sử dụng hàm: CvRect cvBoundingRect(
CvArr* points,
int update CV_DEFAULT(0) );
Sau đó, ta vẽ một hình chữ nhật bao quanh đểđánh dấu đối tượng với hàm: void cvRectangle(
CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
int thickness CV_DEFAULT(1), int line_type CV_DEFAULT(8),
43
int shift CV_DEFAULT(0) );
Kết quả khi chạy chương trình:
Hình 3.2: Kết quả tạo chu tuyến và đánh dấu đối tượng
3.2. Theo vết chuyển động
3.2.1. Sử dụng thuật toán Lucas - Kanade (LK)
Việc trừ nền bản thân nó không thực hiện bất cứ phép toán theo vết nào trên đối tượng được trích ra. Các thuật toán luồng quang học được sử dụng để theo vết đối tượng như đã trình bày ởcác chương trước.
LK là phương pháp luồng quang học thưa, yêu cầu một tập các đặc trưng đầu vào trước khi thực hiện bất kỳ phép toán nào. Thuật toán này không thực hiện bất kỳ việc phát hiện đặc trưng nào. OpenCV cung cấp hàm bổ sung
cvGoodFeaturesToTrack để giúp người dùng tựđộng phát hiện đặc trưng thay bằng việc họ phải xây dựng chúng bằng tay. Tuy nhiên, các đặc trưng được tính toán từ cvGoodFeaturesToTrack có thể không biểu diễn đối tượng mà nó chỉ lấy các điểm ảnh có đặc điểm tốt cho việc xác định và theo vết đối tượng.
void cvGoodFeaturesToTrack( const CvArr* image, CvArr* eig_image, CvArr* temp_image, CvPoint2D32f* corners,
44
double min_distance,
const CvArr* mask CV_DEFAULT(NULL), int block_size CV_DEFAULT(3),
int use_harris CV_DEFAULT(0), double k CV_DEFAULT(0.04) );
Kết quảkhi tìm các đặc trưng sử dụng cvGoodFeaturesToTrack:
Hình 3.3: Các đặc trưng tìm được sử dụng hàm cvGoodFeaturesToTrack
OpenCV cung cấp hai hàm LK optical flow đó là cvCalcOpticalFlowLK và cvCalcOpticalFlowPyrLK. Sự khác nhau giữa chúng đó là hàm sau sử dụng thêm tháp hình ảnh để cải thiện chất lượng kết quả(đây cũng là hàm được sử dụng để cài đặt chương trình mô phỏng trong luận văn). Tháp hình ảnh là tập hợp các hình ảnh mà các ảnh bên trong tháp được tạo ra từ một ảnh gốc đơn:
45
void cvCalcOpticalFlowPyrLK( const CvArr* imgA, const CvArr* imgB, CvArr* pyrA, CvArr* pyrA,
const CvPoint2D32f* featuresA, CvPoint2D32f* featuresA, int count, CvSize win_size, int level, char* status, float* track_error, CvTermCriteria criteria, int flags ); trong đó:
- imgA và imgB là khung hình ở thời điển hiện tại (framen) và khung hình trước đó (framen-1).
- pyrA và pyrB là tháp hình ảnh tương ứng của imgA và imgB. Chúng có thể nhận giá trị NULL và hệ thống sẽ tựđộng xác định chúng, tuy nhiên điều này có thể gây rủi ro và hiệu năng không cao.
- featuresA là một mảng dữ liệu kiểu CvPoint2D32f, là cấu trúc sử dụng để lưu trữ điểm ảnh trong OpenCV. featuresA là một mảng điểm được tìm thấy trong imgA và sẽ cố gắng để tìm và theo vết chúng trong imgB, tương ứng với featuresB.
- count là sốcác đặc trưng được lưu trữ trong featuresA.
- winSize là kích thước cửa sổ cục bộ có thể thay đổi nếu người dùng muốn. Nếu winSize lớn hơn thì chuyển động lớn hơn có thểđược theo vết.
- Level: Số mức pyramid lớn nhất. Nếu bằng 0 , các pyramid không được dùng (single level), nếu bằng 1 , có 2 mức được sử dụng...
- Status: có cấu trúc mảng chứa tất cả các phần tử của mảng được đặt là 1 nếu như việc thực hiện optical flow cho các điểm là được tìm thấy, 0 với trường hợp còn lại.
46
- Criteria: Chỉ định khi quá trình xử lý lặp đi lặp lại của việc tìm kiếm flow cho mỗi điểm trong mỗi mức pyramid được dừng lại.
Kết quả đạt được khi vẽcác véc tơ chuyển động tìm kiếm được từ thuật toán trên:
Hình 3.5: Kết quả tìm véc tơ chuyển động theocvCalcOpticalFlowPyrLK
3.2.2. Sử dụng thuật toán Horn và Schunck
OpenCV cũng cung cấp một hàm cvCalcOpticalFlowHS để thực hiện tính các trường chuyển động theo thuật toán Horn and Schunck như sau:
void cvCalcOpticalFlowHS( const CvArr* prev, const CvArr* curr,
int use_previous, CvArr* velx, CvArr* vely, doublelambda, CvTermCriteriacriteria );
trong đó:
- prev lưu khung ảnh trước, curr lưu khung ảnh hiện tại, dưới định dạng 8-bit và single channel.
- use_previous: cờ để xác định xem có sử dụng vận tốc đầu vào như là khởi tạo xấp xỉ hay không.
- velx: thành phần luồng quang optical flow theo phương nằm ngang với kích thước bằng kích thước các ảnh đầu vào, kiểu 32 bit floating-point và single channel.
47
- vely: thành phần luồng quang optical flow theo phương thẳng đứng với kích thước bằng kích thước các ảnh đầu vào, kiểu 32 bit floating-point và single channel.
- lambda: trọng số làm trơn. Giá trị này lớn thể hiện luồng quang nhận được trơn hơn.
- criteria: tiêu chí kết thúc việc tính vận tốc.
Ta thấy rằng không giống như hàm cvCalcOpticalFlowPyrLK có tham số số lượng đặc trưng cần tính, hàm cvCalcOpticalFlowHS sẽ tính luồng cho mọi điểm của ảnh đầu vào, do đó thuật toán sẽ xửlý lâu hơn và hiện tại không còn được sử dụng trong thực tế. Để theo vết tất cả các điểm ảnh, người ta sử dụng thuật toán Gunna Farneback với hàm OpenCV tương ứng dưới đây.
3.2.3. Sử dụng thuật toán Gunna Farneback
OpenCV cung cấp hàm cvCalcOpticalFlowFarneback để tính luồng quang cho tất cảcác điểm ảnh trong ảnh theo thuật toán Gunnar Farneback với độ hiệu quả cao hơn hẳn so với cvCalcOpticalFlowHS ở trên.
voidcvCalcOpticalFlowFarneback( const CvArr* prev, const CvArr* next,
CvArr* flow, double pyr_scale, int levels,
int winsize, int iterations, int poly_n,