Giới thiệu về hệ thống Computer Vision

Đây là chương mở đầu trong luận văn tốt nghiệp của duy_pham, duy_pham post lên diễn đàn với 2 mục đích. Thứ nhất là nhờ bà con góp ý dùm về nội dung bài viết, thứ hai là cũng muốn share với mọi người về hướng phát triển hệ thống nhúng trên NSLU2 và bài toán thị giác máy Computer Vision. Có gì mọi người tận tình góp ý nhe.

I. Giới Thiệu Về Thị Giác Máy – Computer Vision

Thị giác máy là một lĩnh vực đa và đang rất phát triển. Khái niệm thị giác máy – Computer vision có liên quan tới nhiều ngành học và hướng nghiên cứu khác nhau. Từ những năm 1970 khi mà năng lực tính toán của máy tính ngày càng trở nên mạnh mẽ hơn, các máy tính lúc này có thể xử lý được những tập dữ liệu lớn như các hình ảnh, các đoạn phim thì khái niệm và kỹ thuật về thị giác máy ngày càng được nhắc đến và nghiên cứu nhiều hơn cho tới ngày nay. Hiện tại lĩnh vực được các chuyên gia đánh giá là vẫn còn “non nớt” và có rất nhiều sự thay đổi trong thời gian tới.

A. Thế nào là thị giác máy

Thị giác máy bao gồm lý thuyết và các kỹ thuật liên quan nhằm mục đích tạo ra một hệ thống nhân tạo có thể tiếp nhận thông tin từ các hình ảnh thu được hoặc các tập dữ liệu đa chiều. Đối với mỗi con người chúng ta, quá trình nhận thức thế giới bên ngoài là một điều dễ dàng. Quá trình nhận thức đó được “học” thông qua quá trình sống của mỗi người. Tuy nhiên với các vật vô tri vô giác như như các máy tính, robot v..v thì điều đó quả thực là một bước tiến rất gian nan. Các thiết bị ngày nay không chỉ nhận thông tin ở dạng tín hiệu đơn lẻ mà nay còn có thể có cái “nhìn” thật với thế giới bên ngoài. Cái “nhìn” này qua quá trình phân tích, kết hợp với các mô hình như máy học, mạng nơron v..v sẽ giúp cho thiết bị tiến dần tới một hệ thống nhân tạo có khả năng ra quyết định linh hoạt và đúng đắn hơn rất nhiều.

Lĩnh vực nghiên cứu của thị giác máy rất rộng, và đặc điểm chung là các bài toán về thị giác máy tính đều không có một đề bài chung và cách giải duy nhất. Mỗi giải pháp giải quyết vấn đều được một kết quả nhất định cho những trường hợp cụ thể. Ta có thể thấy sự tương quan giữa Computer vision với các lĩnh

B. Ứng dụng:

Một vài lĩnh vực mà Computer Vision được ứng dụng có thể kể tới như sau:

- Điều khiển tiến trình (ví dụ: trong các robot công nghiệp, hay các thiết bị, xe tự hành)

- Phát hiện sự thay đổi (ví dụ: các thiết bị giám sát)

- Tổ chức thông tin (ví dụ: chỉ số kho dữ liệu các ảnh hoặc chuỗi ảnh liên tục)

- Mô hình hoá đối tượng (ví dụ: quá trình kiểm tra trong môi trường công nghiệp, xử lý ảnh trong y học)

- Tương tác (đóng vai trò làm đầu vào cho thiết bị trong quá trình tương tác giữa người và máy)

1. Các thao tác chính của CV

a. Nhận dạng (recognition):

Nhận dạng ảnh là một trong những vấn đề kinh điển trong lĩnh vực thị giác máy và xử lý ảnh. Mục đích của nhận dạng ảnh tức là xác định xem liệu một bức ảnh có tồn tại những đối tượng, đặc điểm đặc biệt hay không. Chức năng này có thể thực hiện tự động, không cần sự tác động của con người; tuy nhiên nó không đảm bảo trong các trường hợp chung, với những đối tượng tuỳ ý và trong tình huống tuỳ ý.

Các phương pháp hiện nay để giải quyết vấn đề này chỉ được ứng dụng với những đối tượng đặc biệt( những đối tượng hình học cơ bản, nhận dạng mặt người, nhận dạng chữ in và chữ viết tay, ...) và trong những tình huống đặc biệt (trong điều kiện chiếu sáng được xác định trước, ...)
b. Phân tích chuyển động:
Nhận dạng chuyển động được áp dụng để sử lý một chuỗi các ảnh liên tiếp để ước lượng tốc độ chuyển động của từng điểm ảnh.

- Egomotion: Xác định chuyển động trong khung cảnh 3D từ camera. Áp dụng cho các camera theo dõi tự động.
- Tracking: Theo dõi chuyển động của một đối tượng nào đó, ví dụ như người hay xe cộ
c. Xây dựng cảnh (scene reconstruction)
Đây là chức năng cho phép xây dựng và mô phỏng lại một khung cảnh 3D từ những bức ảnh hoặc một đọan phim cho trước.
d. Khôi phục hình ảnh (image restoration)
Lọai bỏ tác động của nhiễu trong ảnh, khôi phục lại hình ảnh ban đầu

2. Hệ thống CV cho bài tóan robot di chuyển:
Việc áp dụng thị giác máy vào bài toán robot di chuyển là một việc phức tạp. Tuy nhiên, trong giới hạn của đề tài, duy_pham giả định ta đã biết trước được điều kiện môi trường robot chuyển động (màu sàn, các vật cản cố định) và hình dạng cũng như màu của mục tiêu biệt lập với môi trường. Sau đây mình xin trình bày từng bước các chức năng có thể ứng dụng vào bài toán này:
Các chức năng chính trong hầu hết các hệ thống CV:
a. Lấy hình ảnh
Chụp ảnh từ webcam. Chất lượng của ảnh thu được từ bước này phụ thuộc nhiều vào chất lượng webcam, tốc độ di chuyển khi chụp, góc nhìn và độ sáng.
b. Tiền xử lí (lấy mẫu, lọc nhiễu, tương phản, ...)
Trước khi áp dụng các chức năng của thị giác ảnh, chúng ta cần xử lý ảnh để đảm bảo rằng ảnh sẽ thoả mãn một vài giả thiết nào đó. Ví dụ như sau:
Lấy mẫu lại để đảm bảo hệ thống toạ độ làü đúng. Nếu 2 ảnh lấy liên tiếp nhau có sự sai khác quá nhiều thì chúng ta có thể loại bỏ ảnh đó vì tư thế của robot lúc chụp không được ổn định.
Loại bỏü nhiễu để giảm thiểu khả năng xuất hiện các thông tin sai
Tăng độ tươngü phản để đảm bảo sẽ xác định được các thông tin cần thiết.
c. Phân tích hình ảnh (xác định đường, góc, cạnh, khối, ...)
Đặc trưng của ảnh ở những mức phức tạp khác nhau sẽ được trích rút từ ảnh, như là các đường, cạnh, góc.

d. Nhận dạng, phân mảnh
Tại một vài điểm ảnh chúng ta chọn ra một tập các điểm ảnh hoặc các vùng ảnh phù hợp với các thao tác xứ lý. Ví dụ:
Chọn các điểm ảnh có màu trùng với màu của mục tiêu.ü
Phân ra các vùng ảnh có khả năng chứa mục tiêu.ü
Phân ngưỡng và địnhü vị các vật cản có thể có

e. Xử lí mức cao
Đến bước này thì dữ liệu đầu vào chỉ là một phần của dữ liệu ban đầu, đó có thể là tập các điểm ảnh hoặc một vùng ảnh có khả năng chứa một đối tượng đặc biệt nào đó. Quá trình xử lý sẽ qua các bước sau:
Thẩm định lại dữü liệu có phù hợp với các yêu cầu cơ bản và đặc biệt
Ước lượng các tham sốü đặc biệt
Phân lớp đối tượng xác định được.ü



II. Single Board Computer(SBC) sử dụng System on Chip (SoC)

SBC (Single board computer) có sử dụng các SoC là buớc tiến lớn trong việc xây dựng thiết bị với khả năng tính toán và xử lý như một máy tính thông thường.Với nhiều ưu điểm hơn hẳn so với các thiết bị khác như :

Kích cỡü
Giá thành.ü
Sửü dụng các SoC làm bộ xử lý trung tâm có khả năng chuyên biệt về xử lý hình ảnh hay xử lý trên môi trường mạng rất hữu hiệu.

Do vậy tuỳ và bài toán đặt ra mà ta có thể chọn các SBC cho các SoC phù hợp với yêu cầu cụ thể. Hiện nay đa có nhiều SoC có khả năng tích hợp các DSP Processor vào trong nhân nhằm tăng khả năng xử lý

Việc sử dụng mạch SBC sẽ có những ưu/ nhược điểm sau:
• Ưu điểm
o Kích thước rất nhỏ
o Giá thành rẻ (~<100$)
o Hỗ trợ SPI, I2C, I2S, MMC, SDCard, UART, USB2.0/1.1 v..v
o Có tốc độ xử lý cao
o Sử dụng hệ điều hành Linux
o Được sự hỗ trợ rất lớn của cộng đồng mã nguồn mở. Từ HĐH, kernel hay rất nhiều các ứng dụng
o Các công cụ biên dịch phổ biến gcc
o Các công cụ hỗ trợ lập trình rất nhiều. Eclipse, Vim, Emacs v..v

• Nhược điểm
o Việc chạy/kiểm thử phải thực hiện giả lập trên máy tính trước khi đưa vào mạch
o Am hiểu kiến thức về các giao tiếp ngoại vi, kiến trúc về SBC

Cách tiếp cận nhanh nhất

Theo quan điểm của mình, cách tiếp cận nhanh chóng nhất với sinh viên đó là tận dụng môi trường mã nguồn mở hiện nay. Với mã nguồn mở chúng ta có thể sử dụng lại những thành quả của cộng đồng mã nguồn mở và phát triển, sáng tạo những cái riêng cho mình một cách dễ dàng và nhanh chóng nhất.

Chúng ta có thể sử dụng HĐH Linux làm môi trường chính cho thiết bị, với mã nguồn mở ta có thể chủ động đuợc cấu hình của hệ thống, tăng hiệu năng hay xử lý thô với các giao tiếp ngoại vi bên ngoài một cách nhanh chóng và thuận tiện nhất. Điều đáng quan tâm nữa là ta có thể có được sự trợ giúp (miễn phí) rất lớn cộng đồng mã nguồn mở. Đây là điều mà môi trường mã nguồn đóng như Window chưa thể có được.

Phần cứng (Hardware)

Ta có thể tận dụng lợi thế của các SBC có sử dụng SoC để làm phần cứng cho các thiết bị trong bài toán thị giác máy. Lợi thế của sự chọn lựa này là các mạch SBC giá rẻ và rất linh hoạt giúp cho nguời thiết kế tập trung hơn vào các module phần mềm.


[align=center]Mạch NSLU2[/align]

Mạch NSLU2 Linksys là một thiết bị lưu trữ mạng (network storage device) giá thành thấp của hãng Linksys. Chức năng chính của NSLU2 là 1 file server. Các ổ cứng hoặc USB kết nối với NSLU2 sẽ được chia sẻ trên mạng nội bộ qua cổng Ethernet.

Tuy nhiên, bằng việc nạp lại Flash của NSLU2 chúng ta có thể biến thiết bị trên thành một trạm làm việc hay một máy vi tính thu nhỏ sử dụng hđh Linux. Cộng đồng Linux phát triển cho NSLU2 rất rộng rãi và các ứng dụng cực kỳ phong phú.


Các thông số kỹ thuật

• Hãng sản xuất Linksys
• Kiến trúc ARM
• Sử dụng bộ VĐK SoC, Intel IXP420. Tốc độ 266Mhz
• 32MB Bộ nhớ SDRAM , 8MB Flash
• Hai cổng USB 2.0 Host
• Hai cổng Ethernet
• I2C, JTAG Port
• Giao tiếp UART với tốc độ 900Kb/s
• 16 cổng lập trình được (GPIO)
• Giá 125$

Ứng dụng mạch NSLU2 vào hệ thống xử lý ảnh cho robot

Mục đích sử dụng thiết bị NSLU2 là tận dụng các thong số kỹ thuật của mạch để làm bộ xử lý trung tâm cho robot. Một webcam được kết nối vào cổng usb để thu nhận ảnh. Kết quả sau khi xử lý sẽ được truyền qua board mạch vi điều khiển thông qua serial port.

Tiếc rằng có một số hình ảnh về hệ thống duy_pham đã chụp lại nhưng ko thể up lên vì nhiều và khá nặng. Có dịp sẽ share với mọi người.



Để giải quyết bài tóan xử lý ảnh bằng NSLU2, ta phải giải quyết theo trình tự các quá trình sau:

1. Cấu hình NSLU2 thành một platform Linux nhúng, có thể truy cập thông qua Ethernet với một PC sử dụng Window hoặc Linux, bằng cách nạp firmware vào Flash của NSLU2.

2. Biên dịch kernel của firmware đang sử dụng, cho phép truy xuất dữ liệu ảnh từ webcam có hỗ trợ video4linux (v4l).

3. Cài đặt môi trường lập trình GNU C trên hđh Linux nhúng đang sử dụng, bao gồm các trình biên dịch (gcc, g++,python…) và các thư viện chuẩn (glibc, libc6, ncurses…), thư viện hỗ trợ xử lý ảnh (libjpeg, libpng, openCV…)

4. Xây dựng các thuật tóan lập trình xử lý ảnh và gửi kết quả xử lý thông qua serial port cho vi điều khiển điều khiển robot.

5. Lập trình vi điều khiển thực thi các thao tác của robot dựa trên kết quả xử lý nhận được.


Rùi, hôm nay là tutorial đầu tiên để xây dựng 1 hệ thống xử lý ảnh bằng NSLU2.

Đầu tiên hãy điểm qua những thiết bị và phần mềm mà chúng ta cần phải có:

Phần cứng và thiết bị:

. Một PC có cài đặt hđh Linux song song với Window.
. NSLU2 (bạn có thể đặt mua tại công ty phân phối của Linksys tại TP HCM hoặc qua mạng)
. 1 ổ cứng USB dung lượng tối thiểu 512Mb (recommended), nhưng nếu chừng 1Gb trở lên sẽ tốt hơn
. 1 webcam có hỗ trợ linux (v4l), tham khảo tại website http://webcam-osx.sourceforge.net/camer ... controller. Chú ý dòng chip điều khiển OV5XX, pwc và SPCAX là đã được thử nghiệm thành công.
. 1 cáp mạng Ethernet nếu bạn dùng switch để kết nối, nếu không bạn có thể kết nối trực tiếp vào cổng Ethernet của PC, với điều kiện dùng cáp chéo (crossover cable)

Software: Cài những soft này trên PC của bạn

- Linksys Network Disk Utility download here
- SercommFirmwareUpdater (for Window user)download here
- or Upslug2 (for Linux user) ie: Ubuntu, đánh dòng lệnh sau vào command line để install upslug2:
sudo apt-get install upslug2
- WinSCP và Putty download here

Rùi, giờ bắt tay vào vọc NSLU2:
[align=center]
Bài 1: Làm thế nào để upgrade phần cứng mới cho NSLU2 và xây dựng giao diện command line cho NSLU2[/align]

B1: Tải phiên bản firmware mà bạn muốn nâng cấp vào PC. Cộng đồng NSLU2-linux đã phát triển rất nhiều phiên bản firmware cho nhiều cấp độ người dùng khác nhau. Duy_pham sẽ tóm tắt 1 chút về các bản phân phối này.

Unslung: Là phiên bản dành cho người mới bắt đầu làm quen với platform NSLU2. Được xây dựng dựa trên nền của phiên bản default nên Unslung khá thân thuộc với người mới sử dụng NSLU2 khi giữ lại giao diện web-interface. Unslung sử dụng kernel 2.4.22 khá cũ kỹ nên khả năng hỗ trợ phần cứng của Unslung là khá hạn chế. Các gói phần mềm cho Unslung bao gồm hơn 1000 soft và thư viện được đóng gói dưới dạng optware (.ipk)

SlugOS: Phiên bản dành cho người dùng cao cấp và cả developer. Sử dụng kernel 2.6.21 và phiên bản cập nhật của glibc, slugos hỗ trợ các công cụ phát triển khá tốt. SlugOS tương thích với khoảng 5000 gói phần mềm (1000 optware như Unslung và 4000 OpenEmbedded packages). SlugOS không có giao diện web nhưng hỗ trợ SSH để giao tiếp với PC qua Putty.SlugOS có thể chạy trên Flash cũng như trên thiết bị lưu trữ ngoài (usb). Nếu hệ thống trục trặc trên usb, flash sẽ là giải pháp backup

Note: Unslung và OpenSlug đều nằm trong dự án OpenEmbedded do đó chúng ta có thể biên dịch kernel cho hai firmware trên bằng hai công cụ của OpenEmbedded là bitbake và monotone. Tham khảo quá trình biên dịch kernel trên website http://www.openembedded.org

Debian/NSLU2: Phiên bản duy nhất được hỗ trợ bởi 1 nhà phân phối Linux uy tín. Debian/NSLU2 hỗ trợ hơn 10000 packages, với kernel Debian Etch và được cấu hình như đối với 1 desktop. Vì lý do đó, Debian/NSLU2 cồng kềnh ko thể chạy trên flash như Unslung và SlugOS, mà yêu cầu phải có thiết bị lưu trữ ngoài. Support sẵn module cho webcam dùng pwc và spcaX nên khá thuận tiện. Tuy nhiên, nếu hệ thống treo, bạn chỉ có 1 cách là ... reflash lại tự đầu.

website download các phiên bản trên: http://www.slug-firmware.net/

riêng Debian/NSLU2, tham khảo hướng dẫn cài đặt tại website http://www.cyrius.com/debian/nslu2/

Hệ thống của Duy_pham dùng Debian/NSLU2, tuy nhiên theo duy_pham thì chúng ta nên bắt đầu từ Unslung để làm quen với NSLU2.

B2: Khởi động NSLU2 vào chế độ upgrade mode:
- Bật NSLU2 lên
- Giữ phím reset cho tới khi thấy đèn ready chuyển sang màu đỏ
- Lập tức thả phím reset (nếu làm đúng thì đèn ready sẽ nhấp nháy giữa xanh và đỏ, nếu nhấp nháy vàng và đỏ tức là bạn thả tay ra chậm wé, tắt nguồn và làm lại đi)
- Chạy Sercomm Updater.
- Open file binary của Unslung mà bạn vừa tải xuống xong và bắt đầu nạp.
Hướng dẫn chi tiết cài đặt Unslung có thể xem tại đây

Chú ý, nếu hướng dẫn nói bạn format ổ đĩa của mình thành dạng EXT3 bằng web-interface của bản default thì khoan làm. Vì bản stock firmware của NSLU2 chỉ format những ổ có dung lượng trên 10Gb. Cứ bỏ qua và tiếp tục đến khi bạn đã boot được Unslung bằng web-interface thì format sau.

B3: Sau khi làm theo các bước trong cái íntallation guide thì có lẽ bạn đã có thể telnet vào được unslung rồi. Để telnet vào NSLU2 bạn cần biết các điều sau:
1. địa chỉ IP của NSLU2 (chạy Disk setupUltility và cấu hình lại IP của NSLU2 tùy theo bạn dùng DHCP hay fix IP)
2. mở IE hay firefox lên, gõ vào địa chỉ: http://192.168.1.x là địa chỉ IP của NSLU2
3. nhấn vào tab telnet, chọn enable
4. ở Window, chọn Start->Run, gõ cmd
5. Trong giao diện cmd, gõ telnet <IP>
---> Chúc mừng, bạn đã telnet đc với platform NSLU2

Hãy dành thời gian làm quen với các lệnh Linux và cài đặt trình biên dịch C bằng cách gõ dòng lệnh sau trong command line của NSLU2:

ipkg update
ipkg install optware-devel

tham khảo chi tiết về cách soạn thảo và lập trình C trên NSLU2 tại đây

vậy là chúng ta đã cấu hình xong NSLU2 trở thành 1 platform Linux. Để cài đặt các phần mềm chúng ta dùng lệnh ipkg, và các gói phần mềm có thể đc download tại website www.nslu2-linux.org hoặc search bằng google với từ khóa NSLU2 optware.

Bài kế tiếp: Rebuild kernel và chạy module videodev cho webcam trên Unslung

Bài 2: Rebuild kernel và chạy module video trên Unslung

1. Nhân Linux (Linux kernel) và việc biên dịch nhân (rebuild kernel)

Như duy_pham đã có lần viết một bài giới thiệu về Linux trong box Hệ điều hành, Linux là 1 hđh có tính module rất cao, cho phép người dùng có thể chỉnh sửa các module, driver cần thiết tương ứng với thiết bị đang sử dụng. Vì tinh thần "biên dịch nhân", một yếu tố chính và quan trọng nhất cần ghi nhận đ*ó là tính phân bộ (modularity) của nhân Linux.

‑Đối với ng dùng bình thường, modularity cho phép chọn lựa cách biên dịch các drivers của nhân theo dạng modules hay theo dạng biên dịch trực tiếp vào nhân.

Có những "driver" không thể biên dịch như một module vì nó phải được load and link trực tiếp ngay khi nhân khởi động . Cũng có những "driver" cho phép chọn như một module và *được tải trong khi và sau khi nhân *được khởi động. Điểm chính yếu cần nắm là khi nào nên chọn M (cho module), Y (cho biên dịch trực tiếp) và N (không dùng) các drivers này.

Biên dịch trực tiếp nghĩa là các driver có dùng hay không cũng đều được load ngày từ khi hđh khởi động, tất nhiên nó sẽ chiếm 1 phần memory. Lợi điểm là "tính trung thực" của nhân và driver. Các hệ thống bảo mật cao thường biên dịch trực tiếp để tránh các module "lạ" bị cài vào nhân trong quá trình hoạt động của máy.

Biên dịch module nghĩa là biên dịch các driver như những module, chỉ khi cần sử dụng mới được tải vào nhân. Lợi điểm của phương pháp này là hiệu quả sử dụng tài nguyên. Bạn có thể tạo ra 1 nhân rất nhỏ gọn và thuận tiện trong việc biên dịch lại 1 số module nào đó (thay vì phải biên dịch lại toàn bộ nhân).

Các bạn nào muốn biết thêm về biên dịch nhân và cách viết driver và biên dịch driver cho Linux (cơ bản là cho máy vi tính nhé) thì tham khảo các tài liệu sau:

Biên dịch nhân linux - Hoàng Ngọc Diệu
Linux device driver - Third Edition - Jonathan Corbet

Hoặc vào website http://kernelnewbies.org/ để làm quen với kernel.

2. NSLU2 và OpenEmbedded:

Dự án Open Embedded (OE) là một dự án phát triển các công cụ hỗ trợ cho việc phát triển những bản phân phối Linux cho các hệ thống nhúng. Căn bản mà nói, OpenEmbedded duy trì và phát triển kho lưu trữ các BitBake recipes. Các BitBake file này chứa đựng địa chỉ mã nguồn của các gói (package), những yếu cầu (dependencies) và thông số biên dịch hay cài đặt một bẻn phân phối.

Bit bake là một hệ thống biên dịch trên nền ngôn ngữ python được dùng để đọc các file *.bb chứa đừng các thông số cần thiết để build một phiên bản image cho NSLU2 (Hay các hệ thống nhúng khác mà chúng ta muốn. ). Bit bake được duy trì như là một subversion độc lập với các thành phần khác của OE. Các *bb files được duy trì trong 1 hệ thống dữ liệu monotone (monotone repository system). Ở đây chúng ta không cần quan tâm đến montone, trừ khi có bạn nào có ý định gia nhập nhóm phát triển OE và cập nhật ,chỉnh sửa, phát triển các *bb files. (Lúc đó nhớ cho duy_pham biết để gọi 1 tiếng sí phò)

Bây giờ không đi quá sâu vào OE kẻo có người tẩu hỏa nhập ma, duy_pham sẽ trình bày các bước để xây dựng công cụ biên dịch kernel cho NSLU2 trên 1 máy tính sử dụng hđh Linux (cụ thể là cái máy ở nhà duy_pham xài Ubuntu7.04)

1. Dùng apt-get để cài các tool cần thiết của OE

- Gõ những dòng lệnh sau vào command line của Ubuntu
sudo apt-get install build-essential
sudo apt-get install libz-dev diffstat texi2html cvs subversion texinfo gawk git
sudo apt-get install libboost-date-time-dev libboost-filesystem-dev libboost-regex-dev libboost-serialization-dev libboost-test-dev libboost-dev g+

Tham khảo thêm về các phần mềm bắt buộc phải có cho OE và công dụng của chúng tại đây

2. Setup các công cụ và thư mục download cho OE:

- Tải, dịch và cài đặt montone phiên bản 0.28 từ source. Đây không phải bản mới nhất nhưng nó là bản được dùng cho dự án NSLU2 nên cứ dùng nó cho chắc ăn

o Nếu bạn xài bản mới nhất của monotone, bạn sẽ bị tra tấn trong suốt quá trình convert datbase từ 0.28 lên phiên bản mới nhất khi build image cho NSLU2. Với cấu hình máy duy_pham là Dual Core 1.8G, 1GB DDRAM2 quá trình migration này mất khoảng ... 6 -> 7 tiếng đồng hồ.

- Thiết lập thư viện download cho OE để lưu trữ các đoạn mã nguồn (tar balls) và bản vá (patch) mà OE sử dụng. duy_pham đặt nó trong $HOME/oe_downloads và dẫn đường dẫn symbol (symbolic link) chỉ tới nó từ NSLU2 và các cây thư mục OE khác.

- Download các file BXD cho IXP425 về từ website của INTEL (Dò NSLU2 dùng con IXP42X mà).

o Đăng ký 1 tài khoản ở website Intel

o Tải các bản mà chúng ta cần về từ kho soft của INTEL

Cái mà mình cần là NPE Access Library và NPE micro code libraries ( ).

+ BSD_ixp400AccessLibrary-2_3.zip, IPL_ixp400NpeLibrary-2_3.zip
+ BSD_ixp400AccessLibrary-2_1.zip, IPL_ixp400NpeLibrary-2_1.zip

o Rename BSD* files thành IPL*
o Kiểm tra checksum bằng các md5 files

Gõ vào command line:

md5sum -b IPL_ixp400AccessLibrary-2_1.zip | awk '{print $1}' > IPL_ixp400AccessLibrary-2_1.zip.md5
md5sum -b IPL_ixp400AccessLibrary-2_3.zip | awk '{print $1}' > IPL_ixp400AccessLibrary-2_3.zip.md5
md5sum -b IPL_ixp400NpeLibrary-2_1.zip | awk '{print $1}' > IPL_ixp400NpeLibrary-2_1.zip.md5
md5sum -b IPL_ixp400NpeLibrary-2_3.zip | awk '{print $1}' > IPL_ixp400NpeLibrary-2_3.zip.md5


o Chép mấy thằng đó vô thư mục download vừa tạo hồi nãy.

Rùi, bây giờ bắt tay vào "Open Embedded" được rùi. Tham khảo hướng dẫn về nó tại website http://www.openembedded.org/wiki/MainPage nhé

3. Compile module videodev cho Unslung bằng Open Embedded.

Tùy vào loại webcam mà bạn sử dụng là dòng vi điều khiển nào mà chúng ta phải build kernel cho nó bằng những cách khác nhau. Ở đây duy_pham giới thiệu 2 tutorial để build module cho webcam dùng chip OV511 và PWC.

OV511 UNSLUNG 5.X

- Tải Master Makefile của NSLU2 xuống (trừ khi bạn đủ khả năng viết 1 Makefile cho nó)

mkdir nslug
cd nslug
ln -s $HOME/oe_downloads downloads
wget --cache=off http://www.nslu2-linux.org/Makefile

- Biên dịch image lại cho Unslung

gõ : make unslung ( rùi, đi pha 1 ly cafe đá, mở HBO lên coi phim hay ESPN để coi ManUtd đá banh đi. Có thể bạn sẽ mất khoảng 3-4h nếu máy mạnh, không thì tốt nhất nên treo máy đó mà ngủ 1 giấc, sáng ra nó chạy xong )

- Sau khi biên dịch xong, vào thư mục ${OEBUILD}/tmp/work/unslung-able-kernel-2.3r63-r7 và hiệu chỉnh các thông số trong file defconfig như sau:
1. CONFIG_VIDEO_DEV=m
2. CONFIG_USB_OV511=m
3. CONFIG_DEVFS_FS=y
4. (Còn lại những thông số khác thì để default hết, khỏi sửa gì cả)

- Xóa cái file ${OEBUILD}/tmp/stamps/unslung-able-kernel-2.3r63-r7.do_compile đi

- Biên dịch lại lần nữa (lại ngủ thêm 1 giấc dài nữa ...)

- Sau khi biên dịch xong, dùng dòng lệnh sau để tìm hai file videodev.o và ov511.o
find / -name videodev.o
find / -name ov511.o

- Chép hai file trên vào thư mục /opt/lib/modules trong NSLU2 (dùng WinSCP để chép)
- Cắm webcam vào NSLU2
- gõ lệnh insmod videodev.o và insmod ov511.o từ thư mục /opt/lib/modules
- kiểm tra file /var/log/messages để chắc rằng webcam đang họat động, nó sẽ có dạng như sau

Mã:
Nov 13 20:29:21 klogd: Linux video capture interface: v1.00
Nov 13 20:29:25 klogd: usb.c: registered new driver ov511
Nov 13 20:29:25 klogd: ov511.c: USB OV511 video device found
Nov 13 20:29:25 klogd: ov511.c: model: AverMedia InterCam Elite
Nov 13 20:29:25 klogd: ov511.c: Sensor is an OV7610
Nov 13 20:29:25 klogd: ov511.c: Device at usb-00:01.1-2 registered to minor 0
Nov 13 20:29:25 klogd: ov511.c: v1.63 for Linux 2.4 : ov511 USB Camera Driver


- tải trình lấy ảnh vidcat về : ipkg install vidcat
- dùng vidcat để capture ảnh, có thể tham khảo cách dùng vidcat bằng lệnh vidcat --help

Vậy là xong, bi giờ cắm webcam vô NSLU2 thỏai mái rùi đó. Có một chút vấn đề ở đây, và đó cũng là lý do tại sao duy_pham không sử dụng Unslung cho bài tóan OpenCV. Đó là kernel 2.4.22 của Unslung hỗ trợ độ phân giải của ảnh rất kém, maximum chỉ được 160x240 (too small). Nếu chỉ dùng cho các bài tóan CV nhỏ như tracking theo sự thay đổi trong ảnh (chống trộm) hay dùng NSLU2 làm server quan sát từ xa mà không cần kích thước file lớn (để dễ truyền đi) thì Unslung làm dễ nhất. Một vấn đề khác là tìm 1 webcam dùng chip ov511 ở VN là khá hiếm, mà chủ yếu là PWC. Việc biên dịch PWC cho Unslung tương đối phức tạp vì kernel thiếu hỗ trợ, thường thì duy_pham dùng SlugOS (cũng biên dịch bằng OE) hoặc Debian/NSLU. [/i]
Quên, chi tiết về cách setup 1 pwc webcam có thể tham khảo tại website http://www.nslu2-linux.org/wiki/HowTo/AddUsbWebcam.

Còn riêng về Debian/NSLU2 thì lý do để duy_pham xài nó là vì nó tích hợp sẵn module pwc.o và videodev.o rùi, chỉ việc insmod và sử dụng. Và kernel Debian Etch của nó hỗ trợ v4l2 (video for linux 2) nên cho chất lượng hình ảnh tốt. tuy nhiên bạn cũng có thể đạt được kết quả tương tự với 1 gói image nhỏ hơn bằng cách dùng OE để build kernel cho SlugOS.

Xong 2 bài rùi, hẹn vài tuần sau sẽ tiếp bài 3: Thư viện mã nguồn mở OpenCV và bài tóan điều khiển robot. (Lý do chậm trễ là tại vì đây là phần mới nảy sinh ra trong đề tài của duy_pham và robin_vh, cả hai đang nghiên cứu mong sẽ có kết quả sớm nhất).

@Zanghe, zxc, nattan: Liên lạc với anh ngay khi em đọc messages này, có việc cần mấy em giúp đây. Sorry, điện thọai hít tiền gòi...Chịu khó gọi cho an

Hây, hôm nay giới thiệu với bà con một thư viện các hàm xử lý ảnh cực kỳ pro, mà duy_pham và robinvh mới "đào" được trên mạng. Đó là thư viện Intel OpenCV.

Bài 4: Thư viện mã nguồn mở Intel OpenCV và bài tóan xử lý ảnh.

Thư viện OpenCV là gì: OpenCV là viết tắt của Open Source Computer Vision, là một thư viện mở gồm các hàm được xây dựng phục vụ cho việc xử lý thị giác máy thời gian thực (Real time computer vision). Các thuật tóan xử lý ảnh thông thường lẫn cao cấp đều được tối ưu hóa bởi các nhà phát triển thư viện thành các hàm đơn giản và rất dễ sử dụng. OpenCV hỗ trợ hai ngôn ngữ chính: C/C++ và python

Cài đặt thư viện OpenCV:

+ Đối với Window và Visual C++ 6.0:

1. Download file binary của OpenCV về tại đây
2. Chạy file binary để install
3. Mở 1 project trong Visual C++ lên. Tiếp theo, từ Project->Settings, hộp thoại Project Settings xuất hiện, chọn tab C/C++. Trên tab này, từ Catergory trổ xuống, bạn chọn Preprocessor. Sau đó, bạn thêm các đường dẫn sau vào hộp hộp text: Additional Include Directories
- C:\Program Files\OpenCV\cv\include
- C:\Program Files\OpenCV\cxcore\include
- C:\Program Files\OpenCV\cvaux\include
- C:\Program Files\OpenCV\otherlibs\cvcam\include
- C:\Program Files\OpenCV\otherlibs\highgui
Chú ý: Các đường dẫn trên phụ thuộc vào việc OpenCV được cài ở đâu, ở đây OpenCV được cài ở C:\Program Files\

4.Tiếp theo, cũng trong hộp thoại Project Settings, chúng ta chuyển sang chọn tab Link. Trên tab này, trog Category trổ xuống, chọn General. Trong hộp text Object/Library modules, ta nhập các thu viện sau vào đó và nhấn Enter để kết thúc:
- cv.lib
- cxcore.lib
- highgui.lib
- cvcam.lib
- cxts.lib

5. Từ Tools->Options, hộp thoại Options xuất hiện, chọn tab Directories, giữ nguyên mặc định cho Platform, trong Show directories for trổ xuống, chọn Include files. Tương ứng với Include files thì ở Directories bên dưới, chúng ta thêm các đường dẫn sau(nếu bạn đã biết các cài đặt cần thêm nằm ở đâu _ nếu không biết, bạn có thể nhấn chuột vào tận cùng của hàng đó để tìm đường giẫn tới đó).

- C:\PROGRAM FILES\OPENCV\CV\INCLUDE
- C:\PROGRAM FILES\OPENCV\CVAUX\INCLUDE
- C:\PROGRAM FILES\OPENCV\CXCORE\INCLUDE
- C:\PROGRAM FILES\OPENCV\FILTERS\PROXYTRANS
- C:\PROGRAM FILES\OPENCV\OTHERLIBS\CVCAM\INCLUDE
- C:\PROGRAM FILES\OPENCV\OTHERLIBS\HIGHGUI

6.Cũng từ tab Directories đổ xuống, chọn Library Files, ở Directories bên dưới, thêm các đường dẫn sau như đối với Include files.

- C:\PROGRAM FILES\OPENCV\LIB

Xong, bây giờ bạn đã có thể sử dụng các hàm của openCV trong Visual C++
Rùi, hôm nay là cách setup OpenCV trên Linux platform.

- Nếu bạn đang sử dụng Debian hoặc Ubuntu, rất đơn giản vì thư viện OpenCV đã được support trong cvs của các bản phân phối trên. Bạn chỉ cần gõ trong command line:

apt-get install libcv*

Là toàn bộ các package cần thiết sẽ được chọn để setup OpenCV cho bạn.

- Trường hợp bạn sử dụng các bản phân phối Linux không hỗ trợ opencv, ta phải build từ source. Quá trình này hơi phê 1 chút à nhe.

1. Download tar balls của openCV về từ website http://sourceforge.net/projects/opencvlibrary/
2. Kiểm tra xem hệ thống của bạn đã cài đặt tất cả các package cần thiết cho OpenCV chưa. Những package cần phải cài trước là:

- GTK+ 2.x or higher.

- libpng, libjpeg, libtiff with development files.

- libavcodec from ffmpeg 0.4.9-pre1 + headers.

Chú ý là các package trên cũng đòi hỏi một số package khác tương tự nên khá phức tạp. Nếu chúng ta dùng firmware SlugOS cho NSLU2 thì hãy tham khảo các package và dependencies của chúng tại website http://ipkgfind.nslu2-linux.org/. Bạn gõ tên các package vào và tìm kiếm sẽ thấy những dependencies của chúng. download các package (đóng gói dưới dạng .ipk) về nslu2 bằng lệnh sau:

wget <link> hoặc down về PC và dùng WinSCP để copy qua NSLU2.

- vào thư mục chứa các gói .ipk và nhập lệnh:
ipkg install <"tên gói">

3. Sau khi cài xong các dependencies của OpenCV, bạn giải nén file tar balls của OpenCV ra:

- tar -xvzf <"tên file nén openCV">
- cd <"thư mục giải nén">
- ./configure
Nếu chạy configure ko báo lỗi gì, bạn gõ tiếp:

- make
- make install

Rùi, vậy là cài xong OpenCV trong Linux. Đây là 1 thư viện xử lý hình ảnh rất mạnh, áp dụng cực kỳ tốt trong bài toán xử lý ảnh robot

Như đã hứa, hôm nay duy_pham xin post 1 sample về sử dụng openCV để xử lý ảnh. Hàm này sẽ load lên 1 file ảnh và chuyển file ảnh đó thành dạng các đường biên (edge detecting). Đây là một ví dụ điển hình về một bài toán Computer Vision với các bước thực hiện như duy_pham đã nêu ở những bài đầu tiên

MA
#include "cv.h"
#include "highgui.h"


char wndname[] = "Edge";
char tbarname[] = "Threshold";
int edge_thresh = 1;

IplImage *image = 0, *cedge = 0, *gray = 0, *edge = 0;

// define a trackbar callback
void on_trackbar(int h)
{
cvSmooth( gray, edge, CV_BLUR, 3, 3, 0, 0 );
cvNot( gray, edge );

// Run the edge detector on grayscale
cvCanny(gray, edge, (float)edge_thresh, (float)edge_thresh*3, 3);

cvZero( cedge );
// copy edge points
cvCopy( image, cedge, edge );

cvShowImage(wndname, cedge);
}

int main( int argc, char** argv )
{
char* filename = argc == 2 ? argv[1] : (char*)"fruits.jpg";

if( (image = cvLoadImage( filename, 1)) == 0 )
return -1;

// Create the output image
cedge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 3);

// Convert to grayscale
gray = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1);
edge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1);
cvCvtColor(image, gray, CV_BGR2GRAY);

// Create a window
cvNamedWindow(wndname, 1);

// create a toolbar
cvCreateTrackbar(tbarname, wndname, &edge_thresh, 100, on_trackbar);

// Show the image
on_trackbar(0);

// Wait for a key stroke; the same function arranges events processing
cvWaitKey(0);
cvReleaseImage(&image);
cvReleaseImage(&gray);
cvReleaseImage(&edge);
cvDestroyWindow(wndname);

return 0;
}


Rùi, bây giờ phân tích 1 chút về các hàm của openCV dùng trong bài toán này nhe.

Mã:
#include "cv.h"
#include "highgui.h"

Khai báo các thư viện của openCV được sử dụng trong chương trình. Nếu dùng Visual C 6 thì phải set up các thư viện trước cho project của bạn nhé.

Mã:
IplImage *image = 0, *cedge = 0, *gray = 0, *edge = 0;

Khai báo header cho các file ảnh, các header này sẽ quy định những thông số của ảnh như kích cỡ, định dạng ảnh, độ phân giải, v.v... Đây là một biến con trỏ kiểu struct được định nghĩa trong thư viện OpenCV. Code của struct này như sau:

Mã:
typedef struct _IplImage
{
int nSize; /* sizeof(IplImage) */
int ID; /* version (=0)*/
int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */
int alphaChannel; /* ignored by OpenCV */
int depth; /* pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported */
char colorModel[4]; /* ignored by OpenCV */
char channelSeq[4]; /* ditto */
int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels.
cvCreateImage can only create interleaved images */
int origin; /* 0 - top-left origin,
1 - bottom-left origin (Windows bitmaps style) */
int align; /* Alignment of image rows (4 or 8).
OpenCV ignores it and uses widthStep instead */
int width; /* image width in pixels */
int height; /* image height in pixels */
struct _IplROI *roi;/* image ROI. when it is not NULL, this specifies image region to process */
struct _IplImage *maskROI; /* must be NULL in OpenCV */
void *imageId; /* ditto */
struct _IplTileInfo *tileInfo; /* ditto */
int imageSize; /* image data size in bytes
(=image->height*image->widthStep
in case of interleaved data)*/
char *imageData; /* pointer to aligned image data */
int widthStep; /* size of aligned image row in bytes */
int BorderMode[4]; /* border completion mode, ignored by OpenCV */
int BorderConst[4]; /* ditto */
char *imageDataOrigin; /* pointer to a very origin of image data
(not necessarily aligned) -
it is needed for correct image deallocation */
}
IplImage;


Đầu tiên chúng ta sẽ mở một file ảnh chứa sẵn trong máy lên để xử lý bằng hàm cvLoadImage()

Mã:
if( (image = cvLoadImage( filename, 1)) == 0 )
return -1;
// Mo mot file anh, neu thanh cong tra ve 1, khong tra ve -1


Hàm này có hai đối số, cái thứ nhất là 1 string chỉ đường dẫn và tên file ta cần load, các định dạng ảnh được hỗ trợ gồm có :

Windows bitmaps - BMP, DIB
JPEG files - JPEG, JPG, JPE
Portable Network Graphics - PNG
Portable image format - PBM, PGM, PPM
Sun rasters - SR, RAS
TIFF files - TIFF, TIF

Đối số thứ hai là định dạng ảnh được đưa vào biến image. nếu đối số này là 1, ảnh là dạng RGB,2 là Grayscale còn -1 là không thay đổi so với nguyên mẫu. Sau khi thực hiện hàm,con trỏ header *image đã trỏ tới vùng nhớ chứa ảnh cần xử lý.

Bây giờ chúng ta sẽ tạo các file image rỗng để chứa các kết quả xử lý, để ý rằng các khai báo IplImage ban đầu chỉ là các header, ko phải file ảnh. Sau khi tạo file ảnh bằng hàm cvCreateImage(), chúng mới trỏ tới vùng nhớ chứa ảnh.

Mã:
// Create the output image
cedge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 3);
gray = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1);
edge = cvCreateImage(cvSize(image->width,image->height), IPL_DEPTH_8U, 1);

Khai báo như trên nghĩa là ảnh cedge là ảnh màu 8 bit, 3 kênh (RGB), gray và edge là ảnh grayscale, chỉ có 1 kênh.

Để có thể thực hiện các thuật toán dò cạnh như dò cạnh sobel hay dò cạnh cranny ảnh cần phải được chuyển thành grayscale. Lý thuyết về convert grayscale có thể theo dõi ở đây. Trong OpenCV, hàm cvCvtColor() sẽ giúp ta thực hiện việc này.

Mã:
cvCvtColor(image, gray, CV_BGR2GRAY);

Hàm này sẽ chuyển ảnh image màu thành ảnh gray là dạng grayscale.

Sau đó ảnh sẽ được lọc nhiễu, phân ngưỡng và xuất ra màn hình. Ở đây các thuật toán đó được viết trong hàm con on_trackbar.

Mã:
void on_trackbar(int h)
{
cvSmooth( gray, edge, CV_BLUR, 3, 3, 0, 0 );
cvNot( gray, edge );

// Run the edge detector on grayscale
cvCanny(gray, edge, (float)edge_thresh, (float)edge_thresh*3, 3);

cvZero( cedge );
// copy edge points
cvCopy( image, cedge, edge );

cvShowImage(wndname, cedge);
}


Dưới đây là hai file chạy chương trình và file ảnh mẫu, các bạn có thể thấy hiệu quả của openCV

À wên, phải cài openCV vào nó mới chạy được. File cài nè

Tập tin đính kèm:
Chú thích tập tin: Thư viện OpenCV
OpenCV_1.0.rar [17.12 MiB]
Đã tải về 28 lần.


bác duy_pham ui!
chương trình bác viết là sử dụng phần mềm visual c++ hả
thực ra em thấy code là c đó ngưng chẳng biết c gì (c,c++,visual c++)
em muốn biết anh sài chương trình gì để em nghiên cứu lun cho tiện (không biết cũng còn có người hỏi)

Rất hoan nghênh tinh thần học hỏi của bạn phuong_vt. duy_pham sẵn sàng giải đáp tất cả thắc mắc của bạn liên quan đến công nghệ xử lí ảnh, dĩ nhiên là trong tầm hiểu biết giới hạn của duy_pham mà thôi.

Q: chương trình bác viết là sử dụng phần mềm visual c++ hả?
A: đúng vậy, đó là chương trình mình viết trên visual C++ của window và sử dụng thư viện Intel OpenCV. Bạn có thể tìm hiểu về thư viện này ]ở đây

Q: MÁy tính không cài win XP mà Linux ?
A: cũng không nhất thiết phải cài Linux trên PC cho lắm, dùng WinXP cũng kết nối được với thiết bị NSLU2. Tuy nhiên ta sẽ cần Linux cho quá trình biên dịch kernel cho NSLU2 bằng Open Embedded. duy_pham dùng phần mêm VMware để chạy giả lập 1 hđh Linux song song với Window trên máy. Ngòai ra, việc làm quen với một máy tính dùng Linux cũng giúp ta thuận lợi hơn khi làm việc với NSLU2.

Q: chẳng biết máy tính nhúng nối với PC theo dây mạng hay theo USB hỉ!!!
A: Máy tính nhúng NSLU2 và PC kết nối với nhau qua cáp Ethernet. Nếu bạn dùng 1 cái switch để cắm thì bấm cáp kiểu bình thường thui, còn nếu kết nối trực tiếp vào PC thì phải bấm cáp chéo (crossover cable). NSLU2 giao tiếp với PC bằng telnet hoặc SSH, với địa chỉ mạng của NSLU2 là 192.168.1.77. Nếu mạng nhà bạn là mạng DHCP thì NSLU2 sẽ được cấp 1 địa chỉ IP động, thay đổi tùy theo số lượng thiết bị trong mạng lúc NSLU2 khởi động. ví dụ nhà bạn có 3 máy tính nốii mạng với nhau, và khi cắm vào NSLU2 thì nó sẽ có IP là 192.168.1.4. Cách telnet vào NSLU2 duy_pham có hướng dẫn ở trên.

Q: Máy tính nhúng đó oh mình có bán không nhỉ giá cở bao nhiêu SV có thể mua "chơi" đc kô nhỉ!!!!
A: Lúc duy_pham mua thì giá của nó là 125 US$, có bán ở TPHCM. Công ty bán thiết bị này là công ty Tân Niềm Tin (TNT), nhà phân phối của Linksys ở TPHCM. NSLU2 có rất nhiều ứng dụng cực hay, ko chỉ dùng để sử lí ảnh, mà còn dùng làm file server, web server v.v... Kể ra thì cũng đáng đồng tiền bát gạo

Q: Hình như mình phải cài hệ diều hành cho nó nữa hả. Cài kiểu gì đây???? Hu hu
A: Không phải hình như mà là chính xác như vậy. Bạn có thể tìm thông tin về cách hack NSLU2 và cài hđh khác vào tại website http://www.nslu2-linux.org

Q: rồi mình có một phần mềm lập trình trên PC. viết một chương trình xử lý ảnh dịch ra file exe rồi nạp file đó vào kit đó phải không
A: Cái này thì sai gòi. Linux có một phần mềm biên dịch là gcc, cũng tương tự như visual C của Window vậy. Chúng ta lập trình trên PC để thử các kết quả, do PC thì nó có giao diện đồ họa, dễ kiểm tra hơn. Sau khi làm chạy trên PC rồi thì cứ copy paste cái file .c đó vào NSLU2 rồi dùng gcc dịch và chạy ngay trên đó luôn. Có điều phải chú ý các khai báo thư viện chuẩn trong VisualC và gcc khác nhau, chẳng hạn gcc Linux ko có conio.h mà thay bằng ncurse.h và stdlib.h v.v...

TÀI LIỆU VỀ CÔNG NGHỆ XỬ LÝ ẢNH NÓI TRÊN ĐƯỢC EITVIET SƯU TẦM TRÊN TRANG WEB WWW.DIENTUVIENTHONG.NET CỦA TÁC GIẢ PHẠM NGUYỄN ANH DUY, CỰU SINH VIÊN CỦA TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN TPHCM