You are on page 1of 78

1

LỜI NÓI ĐẦU


Trong những năm gần đây, trên thế giới nghiên cứu ứng dụng công nghệ xử
lý và nhận dạng ảnh đang là hướng nghiên cứu tập trung của rất nhiều nhà khoa học
trong các lĩnh vực. 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 video thì một khái niệm nữa về xử lý ảnh
nữa ra đời đó là: Thị giác máy - Computer vision.Có thể nói xử lý ảnh số và thị giác
máy đã được phát triển và trở thành một lĩnh vực khoa học. Xử lý ảnh số không chỉ
nâng cao chất lượng của ảnh mà còn phân tích và lý giải tìm ra giải thuật để ứng
dụng vào thực tiễn. 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. Việc kết hợp giữa thị giác máy với các kỹ thuật
khác như công nghệ thông tin, truyền thông, điện tử, điều khiển tự động, cơ khí…
cho chúng ta rất nhiều ứng dụng trong đời sống hàng ngày cũng như trong khoa
học, an ninh, y học, quân sự… Ngày nay, ứng dụng của thị giác máy đã trở nên rất
rộng lớn và đa dạng, len lỏi vào mọi lĩnh vực từ quân sự, khoa học, vũ trụ, cho đến
y học, sản xuất, và tự động hóa tòa nhà.

Trong thời gian qua dưới sự hướng dẫn tận tình của Cô HÀ THỊ KIM
DUYÊN em đã dành thời gian nghiên cứu về xử lý ảnh và nhận dạng ảnh hay nói
đúng hơn là thuật toán xử lý ảnh bám đối tượng – Tracking. Những nội dung mà em
nghiên cứu được ở đây bao gồm:

• Nghiên cứu tổng quan về xử lý ảnh số và hệ bám đối tượng


• Tìm hiểu và nghiên cứu về thư viện mã nguồn mở OpenCV trên
nền C
• Nghiên cứu và xây dựng thuật toán bám ảnh di động tối ưu dựa trên
thư viện mã nguồn mở OpenCV của Intel
• Xây dựng được một hệ thống camera di động (phần cứng lẫn phần
mềm) bám theo mục tiêu di dộng ứng dụng thuật toán bám ảnh Camshitf.
• Đánh giá được kết quả đạt được trong thời gian nghiên cứu.
2

Để hoàn thành đồ án này đúng tiến độ và có chất lượng, em xin gửi lời cảm ơn
chân thành nhất tới Cô Th.s HÀ THỊ KIM DUYÊN là người trực tiếp hướng dẫn em
làm đồ án này. Đồng thời em cũng xin gửi lời cảm ơn sâu sắc tới các anh, các bác
phòng Quang – điện tử, Viện vật lý – Viện khoa học công nghệ Việt Nam đã tạo
điều kiện tối đa giúp đỡ em về mặt thiết bị và dụng cụ thí nghiệm phục vụ quá trình
làm đồ án.

Và cuối cùng, chúng em xin dành tất cả lòng biết ơn và kính trọng sâu sắc nhất
tới bố mẹ chúng em, những người đã sinh thành, nuôi dưỡng chúng em nên người,
đã lo lắng, chỉ bảo từ những việc nhỏ nhất, đã tạo mọi điều kiện cho chúng em được
sống và học tập một cách tốt nhất để vươn tới những ước mơ và hoài bão của mình.
Em xin chân thành cảm ơn!
Hà nội ngày 28 tháng 5 năm 2011
Sinh viên thực hiện
Hà Tiến Thanh
3

Chương 1: TỔNG QUAN VỀ XỬ LÝ ẢNH VÀ HỆ


THỐNG BÁM ĐỐI TƯỢNG

1.1 Tổng quan về xử lý ảnh

Xử lý ảnh 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 người chúng ta, quá trình “học” thông qua 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ư máy tính,
robot… 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à 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… 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 nhiều. Một số lĩnh
vực ứng dụng công nghệ xử lý ảnh mang tính đột phá như sau:

1.1.1 Trong lĩnh vực quân sự

Các hệ thống tích hợp quang hồng ngoại có khả năng tự động điều khiển dàn
hỏa lực (pháo, tên lửa) được lắp đặt cho các trận địa cao xạ, trên xe tăng, tàu chiến,
máy bay, tên lửa hoặc vệ tinh (Hình 1.1). Chúng được thay thế và hỗ trợ các dàn
rada dễ bị nhiễu trong việc tự động phát hiện, cảnh giới, bám bắt mục tiêu. Đặc biệt
có những loại lắp trên máy bay có khả năng điều khiển hỏa lực đánh phá hàng chục
mục tiêu một lúc. Ngoài ra còn phải kể đến các đầu tự dẫn tên lửa và đạn thông
minh.

1.1.2 Trong an ninh, phòng chống tội phạm, bảo vệ pháp luật

Các hệ thống camera nhận dạng khuôn mặt vân tay tự động cũng như phát
hiện, theo dõi, cảnh báo các âm mưu và hoạt động khủng bố. Các xe robốt tự hành
có gắn các camera cũng được ứng dụng trong các môi trường độc hại, dò phá bom
mìn (Hình 1.1).
4

1.1.3 Trong lĩnh vực hàng không vũ trụ

Các hệ thống ống kính chụp ảnh viễn thám (remote sensing) lắp trên các vệ
tinh bay quanh trái đất có thể chụp và quan sát được các vật kích cỡ 0,5 m từ độ cao
750 km trong mọi điều kiện thời tiết (Hình 1.1).. Việc nối ghép các ống kính này
với hệ thống GPS sẽ cho phép xây dựng các bản đồ số có những lĩnh vực ứng dụng
cực kỳ quan trọng trong quốc phòng an ninh, phát triển kinh tế, xã hội...

1.1.4 Trong công nghiệp, giao thông, xây dựng

Hệ thống quang điện tử đóng vai trò của các thị giác máy (machine vision) có
khả năng tự động đo đạc kiểm tra chất lượng sản phẩm trong các dây truyền sản
xuất: phân loại hạt ngũ cốc, cà phê; tìm lỗi lắp ráp linh kiện các bản vi mạch và
khuyết tật các mối hàn và động cơ... Các hệ thống quang điện tử cũng được ứng
dụng ngày càng nhiều trong giao thông như đo tốc độ, tự động kiểm soát điều khiển
và phân luồng giao thông (Hình 1.2).

1.1.5 Trong nghiên cứu y sinh dược học

Các kính hiển vi có khả năng tự động nhận dạng và đo đếm các tế bào với độ
chính xác cao. Các kính hiển vi có hệ thống dẫn đường laser cho phép thực hiện
những phẫu thuật rất phức tạp như mổ u não, nơi mà một sự không chính xác cỡ μm
cũng gây tổn hại đến các dây thần kinh chằng chịt xung quanh..

1.1.6 Trong công nghiệp giải trí truyền hình

Các hệ thống tích hợp có thể điều khiển các camera kích thước và khối lượng lớn dễ
dàng tự động bám theo các đối tượng chuyển động nhanh như bóng đang bay, đua
xe...
5

Hình 1.1: Một số hệ thống tích hợp quang-điện tử và ảnh nhiệt trong
quân sự và chiến đấu

Hình 1.2: Một số hệ thống tích hợp camera giám sát trên tàu viễn thám và
trong công nghiệp và công nghệ vũ trụ

Hình 1.3: Hệ thống camera điện tử ứng dụng trong nghiên cứu thời tiết và
trong công nghiệp
6

1.2 Giới thiệu chung về Robot


Rô bốt (robot) hay người máy là một loại máy có thể thực hiện công việc một
cách tự động hoặc được điều khiển gián tiếp qua máy tính.
Rô bốt là một tác nhân cơ khí, nhân tạo, thường là một hệ thống cơ khí-điện tử
kết hợp hoàn hảo.Với sự xuất hiện và chuyển động của mình, rô bốt gây cho con
người cảm giác là nó cũng có những giác quan như con người. Từ “rô bốt” (người
máy) thường được hiểu với hai nghĩa đó là 1 cơ cấu cơ khí chính xác và phần mềm
tự hoạt động.Về lĩnh vực người máy thì Nhật Bản đang đi đầu về lĩnh vực này.
Ngày nay, Rô bốt đang là tâm điểm của một cuộc cách mạng lớn sau Internet.
Rô bốt ngày càng được sử dụng rộng rãi trong công nghiệp, y tế, giáo dục và đào
tạo, giải trí và an ninh quốc phòng, thám hiểm không gian.
Rô bốt là sản phẩm công nghệ có độ phức tạp cao chứa hàm lượng tri thức vô
cùng phong phú về tất cả cac lĩnh vực của khoa học và công nghệ.
Ngày nay người ta vẫn còn tranh cãi về vấn đề “Một loại máy đủ những tiêu
chuẩn gì để được coi là một rô bốt???” Một cách gần chính xác, rô bốt phải có một
vài (không nhất thiết phải đầy đủ) đặc điểm sau đây:
1. Không phải tự nhiên, tức là do con người chế tạo ra.
2. Có khả năng nhận biết môi trường xung quanh.
3. Có thể tương tác với các vật thể trong môi trường.
4. Có sự thông minh và có khả năng đưa ra các lựa chọn dựa trên môi trường
và có thể hoạt động theo 1 chu trình đã được lập trình sẵn.
5. Có khả năng điều khiển bằng các lệnh để có thể thay đổi tùy theo yêu cầu
của người sử dụng.
6. Có thể di chuyển quay tịnh tiến một chiều hay nhiều chiều.
7. Có sự khéo léo trong vận động.
7

1.3 Giới thiệu tổng quan về hệ thống rô bốt camera bám đối tượng (Tracking
mobile robot)
Hệ thống rô bốt hoạt động bằng các cảm biến như cảm biến màu sắc, hồng
ngoại, cảm biến dò đường, siêu âm giờ đây đã dần dần được phát triển và tích hợp
thêm “thị giác”.Với sự phát triển của khoa học công nghệ, việc tích hợp trên rô bốt
hệ thống camera thông minh ứng dụng công nghệ xử lý ảnh là rất cần thiết phục vụ
cho công nghiệp, quốc phòng và xã hội.

Hệ thống thị giác có thể phân thành 2 lớp, theo như cấu trúc của hệ, đó là hệ
có camera gắn cố định và hệ có camera gắn trên tay máy (eye-in-hand). Trong hệ
camera cố định, camera được gắn cố định so với hệ trục tọa độ thực, thu thập ảnh
của cả mục tiêu và cả môi trường. Mục tiêu của hệ camera cố định này là cung cấp
tín hiệu điều khiển sao cho tay máy đặt được vị trí mong muốn. Mục đích của cấu
trúc eye-in-hand là điều khiển tay máy sao cho ảnh của mục tiêu di động hoặc cố
định được duy trì ở vị trí mong muốn trên mặt phẳng ảnh thu được.

Máy tính
Camera
Robot

Tín hiệu điều khiển

Hình 1.4: Cấu trúc hệ camera cố định điều khiển và giám sát cánh tay rô bốt
8

camera

Vật thể cần giám sát Robot eye-in-hand

Hình 1.5: Cấu trúc hệ Camera rô bốt eye-in-hand

Các nghiên cứu của môi trường động bị bỏ khá xa so với môi trường tĩnh do
ảnh hưởng khá lớn của tốc độ tinh toán cũng như độ chinh xác của việc phân tích
ảnh. Do vậy có nhiều thuật toán để cải thiện tốc độ xử lý ảnh và cải thiện can nhiễu
trong quá trình thu thập dữ liệu từ camera.

Một khó khăn và thách thức của thị giác máy là việc phân loại đối tượng. một
rô bốt có thể phải đối mặt với nhiều đối tượng khác nhau, trong khi chỉ một đối
tượng được quan tâm còn các đối tượng khác thì không. Để nhận biết được vị trí
của mục tiêu trong môi trường động, các đặc trưng của mục tiêu là rất quan trọng.
Các điểm lỗ, các góc cạnh, các đặc điểm điển hình có thể dễ dàng tính toán xử lý ở
môi trường tĩnh, nhưng trong môi trường động thì rất khó vì chi phí về thời gian là
rất lớn, ảnh hưởng của tốc độ làm cho việc xử lý ảnh tách lấy đặc trưng của đối
tượng là rất khó.

Bài toán bám mục tiêu di động với quỹ đạo không biết trước yêu cầu phải giữ
được đối tượng ở một vị trí nhất định trên mặt phẳng ảnh. Thuật toán CamShift
trong OpenCV được sử dụng để tính toán tọa độ trọng tâm của đối tượng trên mặt
phẳng ảnh.

Một số hệ thống tracking rô bốt thực tế đã được triển khai:


9

Hình 1.6: PAN robot và Robot Pops (nguồn: www.mobilerobot.org)

Hình 1.7: Robot Talon và Robot MARRS (nguồn Internet)

Hình 1.8: Robot thám hiểm sao hỏa và Robot MIDbo

Ngày nay việc xây dựng một hệ thống rô bốt thông minh và có khả năng thay
thế con người làm việc trong các điều kiện khắc nghiệt và nguy hiểm là rất cần
10

thiết, đơn cử như việc làm việc trong các hầm mỏ các nhà máy hạt nhân và các vùng
nguy hiểm bom mìn…thì khi ấy các rô bốt như thế này hoàn toàn hữu dụng và là
lựa chọn tối ưu.

Với mục tiêu hướng tới xây dựng một hệ thống rô bốt camera thông minh có
thể phục vụ trong công tác dò mìn cứu trợ cứu nạn, và có khả năng do thám, tôi
cũng đã tìm hiểu và đi vào nghiên cứu chế tạo một hệ tracking thông minh có khả
năng tự hành và bám mục tiêu di động dựa trên công nghệ xử lý ảnh có giao tiếp và
kiểm soát, lưu trữ thông tin bằng máy tính.

Có thể hệ thống lại rằng, một hệ thống bám đối tượng bao gồm:

Đế và
cảm biến
LOS
ảnh

Bộ xử lý

Mục tiêu

Hình 1.9: Cảm biến ảnh, gimbal và bộ vi xử lý

Hình 1.10: Tổng quan về một hệ thống bám

Mục đích của hệ thống bám video, ảnh tự động là duy trì một đường ngắm viết
tắt là LOS (Line Of Sight) giữa cảm biến – mục tiêu một cách ổn định và hoàn toàn
11

tự động trong khi tồn tại cả chuyển động tương đối của mục tiêu và chuyển động
của đế gắn cảm biến làm nhiễu loạn tới dữ liệu cảm biến hình ảnh. Mục tiêu thường
được định vị ban đầu, bởi hoặc là người điều khiển hoặc là hệ thống nhận dạng mục
tiêu tự động. Sau đó hệ thống bám sẽ khóa chặt mục tiêu và duy trì LOS tự động.

Hệ thống bám ảnh tự động thường có 3 bộ phận chính (hình 1.8): (1) bộ cảm
biến hình ảnh (camera chẳng hạn), (2) bộ chấp hành thường là các trục khớp quay
(gimbal) có gắn động cơ hoặc khí nén, và (3) bộ vi xử lý.Một vòng điều khiển phản
hồi,được gọi là vòng bám, liên tục hiệu chỉnh bộ chấp hành để giữ mục tiêu vào tâm
của trường nhìn viết tắt là FOV (Field Of View) của bộ cảm biến. Bộ vi xử lý sẽ
khép kín vòng này bằng cách tính toán độ lệch để điều khiển cơ cấu chấp hành. Các
thành phần hoạt động theo thứ tự: (1) bộ vi xử lý định vị tín hiệu mục tiêu trong các
dòng hình ảnh từ bộ cảm biến, (2) bộ vi xử lý ước lượng trạng thái mục tiêu và tạo
ra các lệnh điều khiển cơ cấu chấp hành trên cơ sở các thông tin trạng thái, (3) lệnh
điều khiển được áp dụng vào LOS cảm biến, (4) bộ cảm biến tạo ra một vòng video
mới, và (5) quá trình được lặp lại.

Cảm biến hình ảnh, có thể là các camera hoặc các cảm biến hình ảnh khác
như: cảm biến ảnh CCD (Charge Couple Device) là loại cảm biến sử dụng một lưới
hình chữ nhật của các điểm (site) thu thập điện tử phủ trên một đế silic mỏng để ghi
lại năng lượng ánh sáng đến mỗi điểm trong chúng. Mỗi một điểm được tạo thành
bằng cách cấy một lớp SiO2 trên đế và sau lắng đọng một cấu trúc dẫn lên trên. Khi
photon ánh sáng đập vào silic, thì cặp điện tử lỗ trống sẽ được tạo ra và các điện tử
mang điện tích âm (electron) sẽ được bật ra ở cổng tương ứng. Với mỗi ánh sáng có
bước sóng khác nhau thì các điện tích bật ra tương ứng cũng sẽ khác nhau.các dòng
điện tử này đi qua bộ biến đổi để lấy ra được mức điện áp quy định tương ứng với
mỗi màu sắc. Và tập hợp những tín hiệu điện này sẽ được xử lý để khôi phục lại
hình ảnh của đối tượng thông qua thiết bị chuyên dụng chuyển đổi.
12

Hình 1.11: Cảm biến CCD

Có thể nói rằng, khối cảm biến hình ảnh có thể sử dụng các cảm biến màu sắc
hoặc camera, tuy nhiên có thể khẳng định rằng, khối này có ảnh hưởng rất lớn đến
chất lượng và tốc độ của một hệ bám ảnh. Vì tốc độ thu thập dữ liệu để gửi về bộ vi
xử lý rất quan trọng, nó ảnh hưởng đến việc tính toán của bộ vi xử lý để nhanh
chóng đưa ra luật điều khiển cho cơ cấu chấp hành.Camera tốc độ và chất lượng
càng cao thì hệ bám sẽ hoạt động với xác suất chính xác cao.

Ngày nay với sự phát triển của khoa học công nghệ thì cảm biến hình ảnh
cũng được hiện đại hóa và cải thiện được tốc độ cũng như chất lượng hình ảnh, điển
hình là các hệ thống camera tích hợp, hồng ngoại, lade, không dây…

Với yêu cầu mục đích của đồ án thì khối cảm biến hình ảnh của tôi sử dụng ở
đây là hệ thống camera không dây tích hợp hồng ngoại quan sát ban đêm. Vì
camera là lựa chọn tối ưu trong việc xây dựng một hệ thống triển khai thực nghiệm,
trong khi các cảm biến hình ảnh khác chỉ dùng trong một mục đích nghiên cứu nhất
định, tốc độ không cao và khó sử dụng và khó tiếp cận. Ngược lại camera thì hoàn
toàn đáp ứng đủ yêu cầu để xây dựng một hệ thống bám ảnh thực nghiệm và dễ tiếp
cận.
13

Hình 1.12: Camera quan sát tích hợp

Về hệ cơ cấu chấp hành thì có thể sử dụng là khí nén hoặc động cơ để điều
khiển. Tuy nhiên tùy vào mục đích sử dụng và yêu cầu riêng của hệ thống ta có thể
sử dụng cơ cấu chấp hành nào để phù hợp nhất. Ở đây ta có thể sử dụng hệ thống đế
xoay dùng động cơ điều khiển và kiểm soát góc độ và tốc độ quay. Các hệ trên thị
trường hiện nay như các hệ PTS, HN (đế xoay camera) tuy nhiên các hệ này thường
là các động cơ xoay chiều điều khiển cho nên việc điều khiển tốc độ và kiểm soát
góc quay cũng gặp nhiều khó khăn.

Hình 1.13: Đế xoay PST, HN để gắn camera quan sát

Trong hệ thống của tôi sử dụng hoàn toàn là động cơ 1 chiều có gắn encoder
để kiểm soát tốc độ và góc quay, được điều khiển bằng phương pháp điều xung
PWM, nên hoàn toàn phù hợp với yêu cầu của hệ thống.
14

Việc lựa chọn động cơ 1 chiều DC (Direct Current) là một lựa chọn tối ưu và
có tính cơ động cao nhỏ gọn, có thể di chuyển đến mọi vị trí vì có khả năng dùng
acqui và pin lưu trữ, phù hợp với nhiều điều kiện khác nhau, phù hợp với nhiều địa
hình có thể triển khai thực tế.

Về bộ vi xử lý, có thể là các vi mạch xử lý chuyên dụng DSP (Digital signal


processing) hay các mạch vi điều khiển hoạc là máy vi tính PC (Personal computer).
Ngoài nhiệm vụ thu thập dữ liệu, chúng có nhiệm vụ xử lý các dữ liệu này bằng các
chương trình được nhúng trong bộ xử lý hoặc chạy trên các PC. Một vi điều khiển
(microcontroller) là một máy tính trên một chip (Computer-on–a–chip, single-chip-
computer). Thường thì các vi điều khiển này được gọi là các bộ điều khiển nhúng
(embedded controller) vì chúng và các mạch điện tử hổ trợ thường được thiết kế lắp
đặt (nhúng) ngay bên trong thiết bị điều khiển. Một số loại mạch nhúng thường gặp
như: Psoc, PC 104, FPGA, SBC (Single board computer), CMUCAM1 2 3, DSP và
các máy tính nhúng.(hình 1.13).

Hình 1.14: Các mạch nhúng ( SBC use PSoC, FPGA, CMUCAM,
DSP, máy tính công nghiệp PC104)

Các mạch nhúng trên đều có ưu điểm là nhỏ gọn, có thể can thiệp và cấu trúc
của chúng có nghĩa là có thể trực tiếp lập trình trên nó, tuy nhiên chúng có nhược
điểm là khó sử dụng, phức tạp và mang tính chuyên ngành cao, không phổ biến và
có dung lượng bộ nhớ nhỏ chỉ có thể xử lý và ít có khả năng lưu trữ thông tin hình
15

ảnh hoặc video khi cần thiết (nếu muốn lưu trữ phải dùng thêm thiết bị ngoại vi nên
khá phức tạp).

Một trong những thiết bị vừa có thể lập trình và vừa có thể xử lý tín hiệu đồng
thời có khả năng lưu trữ thông tin lớn đó là máy tính cá nhân PC. Máy PC ra đời
nhằm phục vụ những yêu cầu của người sử dụng, sử dụng đơn giản, phổ biến đáp
ứng được những yêu cầu của hệ thống. Hiện nay máy tính cá nhân cũng đã được
thiết kế nhỏ gọn với đầy đủ chức năng. Do vậy trong khuôn khổ đề tài này tôi đã lựa
chọn máy tính laptop để xử lý và có thể lưu trữ được thông tin hình ảnh và video,
âm thanh.Giúp người điều khiển có thể quan sát trực tiếp mục tiêu và khi cần thiết
sẽ can thiệp trực tiếp vào quá trình điều khiển. Như vậy việc lựa chọn máy tính
laptop là phù hợp với yêu cầu đề tài.

Như vậy, mục tiêu của đề tài là xây dựng được một hệ thống bám ảnh di động
bao gồm một hệ tích hợp rô bốt điều khiển camera thông minh thu thập dữ liệu gửi
về trung tâm lưu trữ và điều khiển từ xa thông qua hệ thống máy tính. Rôbốt và
camera có thể hoàn toàn hoạt động tự động bám ảnh, vật thể hoặc có thể can thiệp
điều khiển bởi người sử dụng, phục vụ cho công tác nghiên cứu, công tác cứu hộ,
dò phá bom mìn, phục vụ nhiều mục đích trong cuộc sống.
16

Chương 2: TỔNG QUAN VỀ THƯ VIỆN MÃ NGUỒN


MỞ OPENCV TRÊN NỀN C

2.1 Thư viện OpenCV

2.1.1 OpenCV là gì?

OpenCV viết tắt của Open Source Computer Vision Library. Nó có chứa hon
500 hàm sử dụng thị giác máy, và được phát triển bởi tập đoàn Intel. OpenCV là
một thư viện mã nguồn mở (open source) tham khảo tại: http://www.sourceforge.net
Thư viện được viết bằng ngôn ngữ C và C++ có thể chạy trên các hệ điều
hành như Linux, Window và Max OS X. OpenCV được thiết kế để nâng cao hiệu
suất tính toán và nhấn mạnh đến hệ thống thời gian thực. Một điều tuyệt vời của
OpenCV là nó đưa ra một hệ thống đơn giản, dễ sử dụng giúp mọi người nhanh
chóng xây dựng các ứng dụng trong thị giác máy, kể cả các hệ thống kiểm tra trong
nhà máy, bức ảnh trong các lĩnh vực y học, bảo mật, rô bốt học… Nó chứa các lạp
trình xử lý ảnh rất đơn giản, kể cả khi thực thi các hàm bậc cao như dò tìm khuôn
mặt, theo dõi khuôn mặt, nhận dạng khuôn mặt, lọc Kalman.

Kể từ khi được giới thiệu và sử dụng vào tháng 1 năm 1999, OpenCV đã được
sử dụng trong rất nhiều ứng dụng, các sản phẩm và các nghiên cứu. Ví dụ như trong
lĩnh vực hàng không vũ trụ, bản đồ web trực tuyến, sử dụng giảm nhiễu trong y học,
phân tích đối tượng, an ninh, hệ thống dò tìm và cảnh báo, quản lý hê thống sản
xuất, xử lý camera, ứng dụng trong quân sự, hàng không không người lái, trên mặt
đắt và trên tàu ngầm. Ngoài ra nó còn sử dụng trong nhận dạng âm thanh. OpenCV
là một chìa khóa quan trọng trong các rô bốt sử dụng thị giác máy như Stanford hay
Asimo của Nhật Bản. Quá trình phát triển của OpenCV được thể hiện ở hình 2.1:
17

Hình 2.1: Quá trình phát triển của OpenCV

Trên thế giới còn một số thư viện như Emugu CV nhưng phát triển trên nền C# .
OpenCV được phát triển trên nền C và C++ thì sẽ dễ dàng cho những người mới
tiếp cận hơn Emugu CV.

2.1.2 Vì sao lựa chọn OpenCV?

Thị trường thị giác máy đang ngày càng mở rộng và lên tục phát triển. Thư
viện tiêu chuẩn sẽ tạo ra các ứng dụng mới và các giải pháp xử lý dễ dàng hơn. Đặc
biệt tối ưu khi sử dụng cấu trúc Intel. Tạo ra các mẫu ứng dụng bằng các thư viện
được cập nhật thường xuyên và thực hiện các thuật toán nặng như dò tìm khuôn
mặt. Có rất nhiều công nghệ hiện đại và các công ty lớn sử dụng thư viện OpenCV
trong ứng dụng của mình như : Intel, Microsoft, IBM, Siemens, Google… và các
trung tâm nghiên cứu như: Stanford, MIT, Cambridge, INRIA…

Hơn 14000 thành viên trên forum OpenCVyahoogroup.com với trung bình
một ngày có đến 10-20 thông điệp comment trao đổi hàng ngày.

Điều đó khẳng định rằng OpenCV thực sự đã góp phần vô cùng lớn trong lĩnh
vực thị giác máy.
18

2.1.3 Cấu trúc và nội dung OpenCV như thế nào?

Để hiểu OpenCV làm việc như thế nào chúng ta bắt đầu từ sự phân chia cấu
trúc và nội dung của OpenCV ở 5 phần. Cấu trúc của openCV được chia làm 5 phần
chính, 4 trong số đó được chỉ ra trong hình 2.2

CV MLL HighGUI

Xử lý ảnh và thuật toán Thống kê và tập hợp Giao diện, truy xuất
về thị giác máy các công cụ xử lý ảnh và video

CXCORE

Cấu trúc cơ sở và các thuật toán, hỗ trợ XML, các


hàm vẽ

Hình 2.2: Cấu trúc của OpenCV

CXCORE chứa các định nghĩa kiểu dữ liệu cơ sở. Ví dụ, các cấu trúc dữ liệu
cho ảnh, điểm và hình chữ nhật được định nghĩa trong cxtypes.h . CXCORE cũng
chứa đại số tuyến tính và phương pháp thống kê, chức năng duy trì và điều khiển
chuỗi. Một số ít, các chức năng đồ họa để vẽ trên ảnh cũng được đặt ở đây.

CV chứa các thuật toán về xử lý ảnh và định kích cỡ camera. Các chức năng
hình họa máy tính cũng được đặt ở đây.

CVAUX được mô tả trong tài liệu của OpenCV như chứa các mã cũ và thứ
nghiệm. Tuy nhiên, các giao diện đơn cho sự nhận diện ảnh ở trong module này.
Code sau này chúng được chuyên dụng cho nhận diện mặt và chúng được ứng dụng
rộng rãi cho mục đích đó.

HIGHGUI và CVCAM được đặt trong cùng thư mục là “otherlibs”.


19

HIGHGUI chứa các giao diện vào ra cơ bản, nó cũng chứa các khả năng cửa
sổ mở rộng và vào ra video.

CVCAM chứa các giao diện cho video truy cập qua DirectX trên nền
Windows 32 bits.

Kèm theo thư viện là tài liệu hướng dẫn và các ví dụ mẫu thể hiện một phần
các chức năng của công cụ OpenCV. Các chức năng của openCV tập trung vào thu
thập ảnh, xử lí ảnh và các thuật toán phân tích dữ liệu ảnh, bao gồm:

- Truy xuất ảnh và phim: đọc ảnh số từ camera, từ file, ghi ảnh và phim
- Cấu trúc dữ liệu ảnh số và các dữ liệu hỗ trợ cần thiết: ma trận, vector,
chuỗi, xâu và cây
- Xử lí ảnh căn bản: các bộ lọc có sẵn, tìm chi tiết cạnh, góc, chỉnh đổi màu,
phóng to thu nhỏ, và hiệu chỉnh histograms
- Xử lí cấu trúc: tìm viền, nhận chuyển động, thay đổi trong không gian 3D,
đối chiếu bản mẫu, xấp xỉ các đơn vị hình học cơ sở - mặt phẳng, đa giác, ellipse,
đường thẳng...
- Phân tích dữ liệu ảnh: nhận dạng thực thể, theo dõi các chi tiết và phân tích
chuyển động
- Tạo giao diện đơn giản: hiển thị ảnh, thao tác bàn phím, chuột, thanh trượt
để chỉnh thông số (nếu cần thiết các bạn có thể tự tạo thêm các phím điều khiển
thông qua thao tác chuột, hoặc tích hợp thêm các thư viện về giao diện như
wxWidgets)
- Chức năng vẽ, chú thích lên ảnh.
20

2.2 Thư viện OpenCV và môi trường làm việc Microsoft visual studio 2008

2.2.1 Cài đặt OpenCV phiên bản 2.1 dành cho VC++ 2008

Trước hết vào trang web: http://sourceforge.net/projects/opencvlibrary/ download


OpenCV 2.1 phiên bản dành cho VC++ 2008 trên nền window.

Tiến hành cài đặt:

Hình 2.3: Setup OpenCV 2.1

Click Next:

Hình 2.4: Chọn I Agree


21

Click I Agree để tiếp tục:

Hình 2.5: Chon Add OpenCV to the system PATH

Chọn Add OpenCV to the system PATH for all users, để chạy trên tất cả quyền
Admin lẫn users, sau đó click Next chọn mặc định và tiếp tục cho đến khi cài đặt
xong finish.

Hình 2.6: Click Finish để kết thúc


Sau khi cài đặt ta tiến hành copy tất cả các file trong thư mục bin, include
và lib của OpenCV cho vào thư mục bin, include và lib của VC++2008 để sử
dụng thư viện OpenCV.
22

2.2.2 Tạo một dự án bằng VC++ 2008

Mở phần mềm Visual C 2008, chọn Create project ở MFC sau đó tiến
hành MFC Application chọn tên dự án và đường dẫn lưu dự án của mình sau
đó ấn Ok.

Hình 2.7: Tạo một dự án trong VC++ 2008

Sau đó chọn thiết kế giao diện Dialog based và chọn Next:


23

Hình 2.8: Chọn thiết kế Dialog based và môi


trường làm việc của dự án
Sau đó chọn Next và Finish, như vậy ta đã thiết lập được một dự án bây giờ ta
có thể thiết kế và lập trình theo ý muốn.

Sau đây là kết quả của một của một chương trình nhận diện khuôn mặt được
sử dụng thư viện mã nguồn mở của OpenCV và đếm số người trong bức ảnh.
24

Hình 2.9: Kết quả thử nghiệm của lập trình nhận diện khuôn
mặt
25

Chương trình nhận diện khuôn mặt và đếm số người trong một bức ảnh dùng
thư viện: "haarcascade_profileface.xml”.

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include <iostream>

// Create a string that contains the exact cascade name


const char* cascade_name =
"C:/OpenCV2.1/data/haarcascades/haarcascade_frontalface_alt2.xml";
/* "haarcascade_profileface.xml";*/

// Function prototype for detecting and drawing an object from an image


void detect_and_draw( IplImage* image );
int dem=0;
// Main function, defines the entry point for the program.
int main( int argc, char** argv )
{

// Create a sample image


IplImage *img = cvLoadImage("D:\\IMG_8036.jpg");

// Call the function to detect and draw the face positions


detect_and_draw(img);

// Wait for user input before quitting the program


cvWaitKey();

// Release the image


cvReleaseImage(&img);
std::cout << "co tat ca"<<dem << " nguoi//";
// Destroy the window previously created with filename: "result"
cvDestroyWindow("result");
//MessageBox(dem);

// return 0 to indicate successfull execution of the program


26

system("pause");
return 0;
}

// Function to detect and draw any faces that is present in an image


void detect_and_draw( IplImage* img)
{

// Create memory for calculations


static CvMemStorage* storage = 0;

// Create a new Haar classifier


static CvHaarClassifierCascade* cascade = 0;

int scale = 1;

// Create a new image based on the input image


IplImage* temp = cvCreateImage( cvSize(img->width/scale,img-
>height/scale), 8, 3 );

// Create two points to represent the face locations


CvPoint pt1, pt2;
int i;

// Load the HaarClassifierCascade


cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );

// Check whether the cascade has loaded successfully. Else report and error
and quit
if( !cascade )
{
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
return;
}

// Allocate the memory storage


storage = cvCreateMemStorage(0);

// Create a new named window with title: result


cvNamedWindow( "result", 1 );

// Clear the memory storage which was used before


cvClearMemStorage( storage );

// Find whether the cascade is loaded, to find the faces. If yes, then:
if( cascade )
{
27

// There can be more than one face in an image. So create a growable


sequence of faces.
// Detect the objects and store them in the sequence
CvSeq* faces = cvHaarDetectObjects( img, cascade, storage,
1.1, 2, CV_HAAR_DO_CANNY_PRUNING,
cvSize(40, 40) );

// Loop the number of faces found.


for( i = 0; i < (faces ? faces->total : 0); i++ )
{
// Create a new rectangle for drawing the face
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );

// Find the dimensions of the face,and scale it if necessary


pt1.x = r->x*scale;
pt2.x = (r->x+r->width)*scale;
pt1.y = r->y*scale;
pt2.y = (r->y+r->height)*scale;

// Draw the rectangle in the input image


cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
dem++;
}
}

// Show the image in the window named "result"


cvShowImage( "result", img );

// Release the temp image created.


cvReleaseImage( &temp );
}
28

Chương 3: XÂY DỰNG THUẬT TOÁN XỬ LÝ ẢNH


BÁM ĐỐI TƯỢNG TỐI ƯU (TRACKING)
3.1 Giải thuật chung về hệ thống bám (Tracking camera robot)

Start

Khởi tạo

Tính tọa độ
Chụp ảnh
tâm, hướng

Lấy mẫu
Giao tiếp
RS232,RF
Histogram

Lọc nhiễu Điều kiện


dừng

Camshift
Dừng

Hình 3.1: Lưu đồ thuật toán bám đối tượng

Dựa vào lưu đồ thuật toán ta có thể hình dung về một hệ thống bám tổng quan
nhất để có thể xây dựng được một thuật toán điều khiển tối ưu phù hợp vói hệ
thống, đáp ứng đủ các yêu cầu đặt ra của bài toán. Sau bước khởi tạo ban đầu mục
tiêu sẽ được đưa vào hệ cảm biến hình ảnh để chụp ảnh, sau đó được lấy mẫu tín
hiệu từ không gian màu RGB đến không gian màu HSV. Mọi màu sắc tự nhiên đều
được tổ hợp từ 3 màu cơ bản: đỏ R (red), xanh lục G (green) và xanh dương B
(blue). Để tiêu chuẩn hóa việc đo màu sắc trên thế giới, dựa vào kết quả thực
nghiệm người ta đã qui định 3 màu cơ bản này tương ứng với các bước sóng 700nm
29

đối với (R), bước sóng 546,8 nm đối với (G) và 435,8 nm đối với (B). Ba màu cơ
bản này là để tạo ra các màu khác với tỷ lệ pha trộn tương ứng. VD: vàng =
đỏ+xanh lục (tham khảo thêm tại: http://vi.wikipedia.org/wiki/ ) Để cảm nhận màu
sắc thì có 3 thuộc tính chủ yếu:

Sắc màu (Brightness), còn gọi là độ chói.


Sắc lượng (Hue), còn gọi là sắc thái màu.
Độ bão hòa màu (Saturation)
Có thể chuyển đổi từ không gian màu RGB sang không gian màu HSV và
ngược lại, chính nhờ sự chuyển đổi này mà chúng ta có thể lập trình lấy mẫu tín
hiệu thu được từ camera. Và có thể nói trong OpenCV có hàm cvCvtColor() chuyên
dụng để thực hiện nhiệm vụ này.

Hình 3.2: Không gian màu RGB và không gian màu HSV

Histogram chính là quá trình mô tả đối tượng, thông tin hình ảnh và video
dưới dạng biểu đồ (Histogram) để dễ quan sát. Histogram có thể sử dụng để chỉ ra
sự khác nhau giữa các đối tượng và chỉ ra xác suất phân bố màu sắc. Thực hiện quá
trình tạo Histogram liên tiếp và quan sát nếu thấy Histogram nào gần giống với
Histogram của đối tượng nhất thì sẽ được chọn, đây cũng chính là một trong những
yếu tố cần thiết trong thuật toán bám ảnh của công nghệ xử lý ảnh nói chung và thư
viện OpenCV nói riêng.
30

Hình 3.3: Histogram của hai lần lấy mẫu

Lọc nhiễu nhằm mục đích loại bỏ can nhiễu để lấy ra được tín hiệu chính xác
cần lấy mẫu. Có thể nói rằng nhiễu phát sinh trong quá trình xử lý ảnh là rất lớn do
vậy cần phải loại bỏ nhiễu bằng các bộ lọc như Kalman hay bộ lọc g-h hay g-h-k…

Hình 3.3: Kết quả trước khi lọc và sau khi lọc

Từ những yếu tố trên thuật toán bám của hệ là như sau: phải có thể lấy mẫu và
chuyển đổi được giữa các không gian màu RGB và HSV và ngược lại, phải tạo ra
Histogram để so sánh đưa ra luật điều khiển, và quan trọng phải xác định được đặc
tính của ảnh.Tính toán được trọng tâm và hướng của vật thể có kết hợp các bộ lọc
nhằm loại bỏ nhiễu vào hệ thống.
31

3.2 Thuật toán Camshift trong tối ưu hóa hệ bám đối tượng

Trong xử lý ảnh việc đi nghiên cứu thuật toán bám đối tượng là rất quan trọng,
một số thuật toán thường gặp đó là: thuật toán KLT, phương pháp Correlation-base
template matching, thuật toán Meanshift, thuật toán Camshift.

Thuật toán KLT viết tắt của tên hai nhà nghiên cứu Lucas and Kanade và
Tomasi kết hợp với Birchfield vào năm 1991 đã cho ra đời thuật toán xử lý bám các
đặc tính của ảnh, được thực thi bằng ngôn ngữ C và được gọi là thuật toán bám
KLT (KLT tracker). Thuật toán KLT dùng toán học tính toán ra các đặc tính sau đó
cũng dùng toán học để tính ra xác suất xuất hiện của các đặc tính đó trong lần di
chuyển tiếp theo. Nó có nhược điểm là rất phức tạp và lập trình tốn bộ nhớ của
chương trình, tỷ lệ trượt cao vì khó chọn ra đặc tính của đối tượng và chỉ phù hợp
với 1 đối tượng được lập trình từ trước, khi bám đối tượng khác thì phải lập trình và
lấy lại đặc tính cho đối tượng mới.

Phương pháp Correlation-base template matching là phương pháp so sánh với


một ảnh hoặc thư viện mẫu có sẵn (template), do vậy phải dùng toàn bộ ảnh của đối
tượng chứ không phải dùng một số điểm ảnh như các thuật toán khác, đồng thời
không dùng các thông tin chuyển động, tính toán nhiều hơn nên khối lượng chương
trình rất lớn.

Thuật toán Meanshift được phát triển từ phương pháp Gauss dùng ước lượng
đối tượng trên một cửa sổ ảnh cố định, chia ảnh của đối tượng thành các ma trận
điểm ảnh (pixel) sau đó thực hiện ước lượng các điểm ảnh này bằng phương pháp
Gauss, sau đó tính trung bình các pixel đó trên khung ảnh cố định của đối tượng,
quá trình lặp lại cho đến khi hội tụ có thể tham khảo thêm tại trang web sau để hiểu
thêm về phương pháp Gauss:
(http://saravananthirumuruganathan.wordpress.com/2010/04/01/introduction-
to-mean-shift-algorithm/)

Cuối cùng là thuật toán Camshift, Camshift viết gọn của “Continuously
Adaptive Meanshift” là cơ sở của thuật toán theo dõi khuôn mặt trong OpenCV. Nó
bao gồm thuật toán cơ sở Meanshift với thích ứng các bước thay đổi kích cỡ của
32

vùng. Nhân là một hàm step đơn giản nằm trong một bản đồ vỏ xác suất (skin-
probability). Vỏ xác suất của mỗi điểm ảnh được tính toán dựa trên màu sắc bằng
cách sử dụng một phương pháp gọi là Histogram backprojection. Màu sắc được đưa
ra như sắc thái màu (Hue) từ mô hình HSV. Trong thuật toán Camshift, một bức
ảnh về xác suất phân bố màu của bức ảnh trong chuỗi video được tạo ra. Đầu tiên
nó tạo ra một mẫu mô tả Hue sử dụng một biểu đồ màu sắc (color Histogram) và sử
dụng không gian màu Hue Saturation Value (HSV) được tham chiếu từ không gian
màu tiêu chuẩn RGB. Vì phân bố màu sắc của bức ảnh trong video thay đổi theo
thời gian, nên thuật toán Camshift được sửa đổi để dễ dàng thích ứng với sự thay
đổi phân bố xác suất màu sắc của mục tiêu nó theo dõi. Trong OpenCV thuật toán
Camshift được điều chỉnh từ thuật toán Meanshift. Nó được tính toán như sau:
Bước 1: Chọn vị trí ban đầu của Search Window.
Bước 2: Dùng thuật toán Meanshift (lặp một hoặc nhiều lần) lưu ra một vùng gọi là
moment thứ 0.
Bước 3: Đặt kích cỡ của cửa sổ tìm kiếm bằng một hàm của moment thứ 0 tìm được
trong bước 2.
Bước 4: Lặp lại bước 2 và bước 3 cho đến khi hội tụ.

Với những ưu điểm của thuật toán Camshift trong việc xử lý ảnh bám đối
tượng và nhận diện ảnh, kết hợp với ngôn ngữ C tôi đã lựa chọn và xây dựng riêng
cho đề tài của mình một thuật toán tối ưu trong việc xử lý ảnh bám đối tượng. Thuật
toán Camshift đã được cụ thể hóa bằng lưu đồ hình 3.4. Đầu tiên là một Histogram
được tạo ra, Histogram này chứa các thuộc tinh liên quan đến màu sắc và tiếp theo
tâm và kích cỡ của mục tiêu được tinh toán để theo dõi mục tiêu khi hình dạng và
kích cỡ của nó thay đổi. Tính xác suất phân bố mục tiêu căn cứ và Histogram nhận
được. Dịch chuyển đến vị trí mới với mỗi khung hình vừa nhận được từ video.
Camshift sẽ dịch chuyển đến vị trí mà nó ước lượng trên đối tượng nó mà nó tập
trung nhiều điểm sáng nhất trong bức ảnh xác suất. nó tìm vị trí mới bắt đầu từ vị trí
trước đó và tính toán giá trị trọng tâm vừa tìm được. OpenCV sử dụng hàm
cvCamshift() để thực hiện chuyển dịch này. Việc tính toán trọng tâm dựa vào thuật
toán Meanshift.
33

Video

Xác suất
Chụp Tính toán
RGB HSV phân bố Camshift
ảnh Histogram
màu

X,Y

Tạo vị trí và
kích cỡ search Reset vùng Đặt tâm search
window tính toán window

Hình 3.4: Lưu đồ thuật toán Camshift

Hình 3.5: Kết quả của việc thực hiện hàm Camshift trong việc
tính tọa độ của mục tiêu
34

Chương 4: XÂY DỰNG, THI CÔNG PHẦN CỨNG


VÀ LẬP TRÌNH PHẦN MỀM CHO HỆ THỐNG BÁM
ĐỐI TƯỢNG
4.1 Tổng quan về các linh kiện xây dựng phần cứng

Việc chọn lựa các linh kiện để xây dựng mạch phần cứng là rất quan trọng sau
khi đã xây dựng xong thuật toán xử lý tối ưu. Trong hệ thống này ngoài bộ vi xử lý
chung là máy tính laptop còn có một khối giao tiếp để thực hiện bắt tay giữa
camera, cơ cấu chấp hành và máy tính. Để đáp ứng đủ yêu cầu về khả năng điều
khiển cơ cấu chấp hành và vừa có khả năng xử lý, chống nhiễu tốt tôi quyết định
chọn và sử dụng vi điều khiển AVR, ATmega128 vì nó có đầy đủ tính năng và có
khả năng chống nhiễu tốt. Để sử dụng điều khiển các cơ cấu chấp hành và kiểm soát
tốc độ và góc quay tôi đã sử dụng một số linh kiện chuyên dụng điều khiển cầu
động cơ đó là dòng MC của Freescale và DVR của Texas Intrument. Với mục đích
xây dụng một kit vi điều khiển đa năng có thể vừa thực hiện nhiệm vụ điều khiển cơ
cấu chấp hành vừa có khả năng thực hiện nhiệm vụ xử lý tín hiệu từ các cảm biến
trong công nghiệp như PIR, IR của Sharp, cảm biến gia tốc và độ nghiêng ADXL
hay MMA7455… và có thể giao tiếp RS232 hoặc giao tiếp không dây RF để phục
vụ quá trình truyền và xử lý tín hiệu.

Giới thiệu về vi điều khiển ATmega128

Atmega 128 là một bộ vi xử lý CMOS điện áp thấp dựa trên nền kiến trúc
AVR RISC nâng cao . Bằng cách thi hành các lệnh một cách mạnh mẽ trong một
chu kì đồng hồ duy nhất, Atmega128 có thể cho phép tốc độ đạt được là 1 MPIS
trên 1 MHz từ đó giúp người thiết kế hệ thống có khả năng tối ưu hóa điện năng sử
dụng so với tốc độ xử lý.

4.1.1 Những Tính Năng Chính Của ATmega128:

• ROM : 128 Kbytes


• SRAM: 4Kbytes
• EEPROM : 4Kbytes
• 64 thanh ghi I/O
35

• 160 thanh ghi vào ra mở rộng


• 32 thanh ghi đa mục đích.
• 2 bộ định thời 8 bit (0,2).
• 2 bộ định thời 16 bit (1,3).
• Bộ định thời watchdog
• Bộ dao động nội RC tần số 1 MHz, 2 MHz, 4 MHz, 8 MHz
• ADC 8 kênh với độ phân giải 10 bit (Ở dòng Xmega lên tới 12 bit)
• 2 kênh PWM 8 bit
• 6 kênh PWM có thể lập trình thay đổi độ phân giải từ 2 tới 16 bit
• Bộ so sánh tương tự có thể lựa chọn ngõ vào
• Hai khối USART lập trình được
• Khối truyền nhận nối tiếp SPI
• Khối giao tiếp nối tiếp 2 dây TWI
• Hỗ trợ boot loader
• 6 chế độ tiết kiệm năng lượng
• Lựa chọn tần số hoạt động bằng phần mềm
• Đóng gói 64 chân kiểu TQFP.
• Tần số tối đa 16MHz
• Điện thế : 4.5v - 5.5v (Riêng dòng ATmega128L thì nguồn
cung cấp là 3.3V)
Sơ đồ chân:

Hình 4.1: Sơ đồ chân của ATmega128


36

4.1.2 Cấu trúc của ATmega128

Hình 4.2: Sơ đồ cấu trúc của ATmega128

4.1.3 Cổng và ra

Cổng vào ra là một trong số các phương tiện để vi điều khiển giao tiếp với các
thiết bị ngoại vi. ATmega128 có cả thảy 7 cổng ( port ) vào ra 8 bit là : PortA,
PortB, PortC, PortD, PortE, PortF, PortG, tương ứng với 56 đường vào ra. Các cổng
vào ra của AVR là cổng vào ra hai chiều có thể định hướng, tức có thể chọn hướng
của cổng là hướng vào (input ) hay hướng ra (output ). Tất các các cổng vào ra của
AVR điều có tính năng Đọc – Chỉnh sửa – Ghi ( Read – Modify – write ) khi sử
dụng chúng như là các cổng vào ra số thông thường. Điều này có nghĩa là khi ta
thay đổi hướng của một chân nào đó thì nó không làm ảnh hưởng tới hướng của các
chân khác. Tất cả các chân của các cổng (port ) điều có điện trở kéo lên ( pull-up )
riêng, ta có thể cho phép hay không cho phép điện trở kéo lên này hoạt động. Điện
37

trở kéo lên là một điện trở được dùng khi thiết kế các mạch điện tử logic. Nó có một
đầu được nối với nguồn điện áp dương (thường là Vcc hoặc Vdd) và đầu còn lại
được nối với tín hiệu lối vào/ra của một mạch logic chức năng. Điện trở kéo lên có
thể được lắp đặt tại các lối vào của các khối mạch logic để thiết lập mức logic lối
vào của khối mạch khi không có thiết bị ngoài nối với lối vào. Điện trở kéo lên
cũng có thể được lắp đặt tại các giao diện giữa hai khối mạch logic không cùng loại
logic, đặc biệt là khi hai khối mạch này được cấp nguồn khác nhau. Ngoài ra, điện
trở kéo lên còn được lắp đặt tại lối ra của khối mạch khi lối ra không thể nối nguồn
để tạo dòng, ví dụ các linh kiện logic TTL có cực góp hở. Đối với họ logic lưỡng
cực với nguồn nuôi 5 Vdc thì giá trị của điện trở kéo lên thường nằm trong khoảng
1000 đến 5000 Ohm, tùy theo yêu cầu cấp dòng trên toàngiải hoạt động của mạch.
Với lôgíc CMOS và lôgíc MOS chúng ta có thể sử dụng các điện trở có giá trị lớn
hơn nhiều, thường từ vài ngàn đến một triệu Ohm do dòng rò rỉ cần thiết ở lối vào là
rất nhỏ. Trong việc thiết kế các vi mạch ứng dụng, nếu một IC có ngõ ra loại cực
thu để hở giao tiếp với nhiều IC khác thì giá trị của điện trở kéo lên sẽ tương đối
nhỏ (khoảng vài trăm Ohm). Bởi vì lúc này hệ số fanout lớn dẫn đến dòng ngõ ra
của IC phải lớn để đủ cung cấp cho các ngõ vào của các IC khác, nếu không vi
mạch sẽ hoạt động chập chờn hoặc có thể không hoạt động.

Khi khảo sát các cổng như là các cổng vào ra số thông thường thì tính chất của
các cổng ( PortA, PortB,…PortG ) là tương tự nhau, nên ta chỉ cần khảo sát một
cổng nào đó trong số 7 cổng của vi điều khiển là đủ. Mỗi một cổng vào ra của vi
điều khiển được liên kết với 3 thanh ghi : PORTx, DDRx, PINx. ( ở đây x là để thay
thế cho A, B,…G ). Ba thanh ghi này sẽ được phối hợp với nhau để điều khiển hoạt
động của cổng, chẳn hạn thiết lập cổng thành lối vào có sử dụng điện trở pull-up,
..v.v.. . Sau đây là diễn tả cụ thể vai trò của 3 thanh ghi trên.

 Thanh Ghi DDRx.


Đây là thanh ghi 8 bit ( có thể đọc ghi ) có chức năng điều khiển hướng của
cổng (là lối ra hay lối vào ). Khi một bit của thanh ghi này được set lên 1 thì chân
tương ứng với nó được cấu hình thành ngõ ra. Ngược lại, nếu bit của thanh ghi
DDRx là 0 thì chân tương ứng với nó được thiết lập thành ngõ vào. Lấy ví dụ: Khi
ta set tất cả 8 bit của thanh ghi DDRA đều là 1, thì 8 chân tương ứng của portA là
38

PA1, PA2, … PA7 ( tương ứng với các chân số 50, 49, …44 của vi điều khiển )
được thiết lập thành ngõ ra.

Hình 4.3: Thanh ghi DDRx

 Thanh Ghi PORTx.


PORTx là thanh ghi 8 bit có thể đọc ghi. Đây là thanh ghi dữ liệu của PORTx,
Nếu thanh ghi DDRx thiết lập cổng là lối ra, khi đó giá trị của thanh ghi PORTx
cũng là giá trị của các chân tương ứng của PORTx, nói cách khác, khi ta ghi một giá
trị logic lên 1 bit của thanh ghi này thì chân tương ứng với bit đó cũng có cùng mức
logic. Khi thanh ghi DDRx thiết lập cổng thành lối vào thì thanh ghi PORTx đóng
vai trò như một thanh ghi điều khiển cổng. Cụ thề , nếu một bit của thanh ghi này
được ghi thành 1 thì điện trở treo ( pull-up resistor ) ở chân tương ứng với nó sẽ
được kích hoạt, ngược lại nếu bit được ghi thành 0 thì điện trở treo ở chân tương
ứng sẽ không được kích hoạt, cổng ở trạng thái cao trở ( Hi-Z ).

Hình 4.4: Thanh ghi PORTA

 Thanh Ghi PINx.


PINx không phải là một thanh ghi thực sự, đây là địa chỉ trong bộ nhớ I/O kết
nối trực tiếp tới các chân của cổng. Khi ta đọc PORTx tức ta đọc dữ liệu được chốt
trong PORTx, còn khi đọc PINx thì giá trị logic hiện thời ở chân của cổng tương
ứng được đọc. Vì thế đối với thanh ghi PINx ta chỉ có thể đọc mà không thể ghi.
Hình 4.5 thể hiện các các thiết lập cách hoạt có thể có của cổng.
39

Hình 4.5: Thanh ghi PINA

Hình 4.6: Cách thiết lập cho cổng

4.1.4 Các bộ định thời, cấu trúc ngắt, module PWM, USART/UART và các
ngoại vi khác

ATmega128 có 4 bộ định thời , bộ định thời 1 và 3 là bộ định thời 16 bit, bộ


định thời 0 và 2 là bộ định thời 8 bit (Timer/Couter0 và Timer/Couter2 với 2
module PWM 8bit).

Hình 4.7: Bộ định thời Timer/Counter0 với module PWM 8bit


40

Hình 4.8: Bộ định thời Timer/Counter 2 với module


PWM 8 bit

Hình 4.8: Bộ định thời 16 bit

4.1.5 Truyền nhận nối tiếp

USART (Universal Synchronous and Asynchronous serial Receiver and


Transmitter): Bộ Truyền Nhận Nối Tiếp Đồng Bộ Và Bất Đồng Bộ Phổ Dụng, đây
là khối chức năng dùng cho việc truyền thông giữa vi điều khiển với các thiết bị
khác. Trong vấn đề truyền dữ liệu số, có thể phân chia cách thức (method) truyền
dữ liệu ra hai chế độ (mode) cơ bản là : Chế độ truyền nhận đồng bộ (Synchronous)
và Chế độ truyền nhận bất đồng bộ (Asynchronous). Ngoài ra, nếu ở góc độ phần
41

cứng thì có thể phân chia theo cách khác đó là: Truyền nhận dữ liệu theo kiểu nối
tiếp (serial) và song song (paralell).

• Truyền đồng bộ: là kiểu truyền dữ liệu trong đó bộ truyền


(Transmitter) và bộ nhận (Receiver) sử dụng chung một xung đồng hồ
(clock). Do đó, hoạt động truyền và nhận dữ liệu diễn ra đồng thời. Xung
clock đóng vai trò là tín hiệu đồng bộ cho hệ thống (gồm khối truyền và khối
nhận). Ưu điểm của kiểu truyền đồng bộ là tốc độ nhanh, thích hợp khi
truyền dữ liệu khối (block).

• Truyền bất đồng bộ: Là kiểu truyền dữ liệu trong đó mỗi bộ truyền
(Transmitter) và bộ nhận (Receiver) có bộ tạo xung clock riêng, tốc độ xung
clock ở hai khối này có thể khác nhau, nhưng thường không quá 10 o/o . Do
không dùng chung xung clock, nên để đồng bộ quá trình truyền và nhận dữ
liệu, người ta phải truyền các bit đồng bộ (Start, Stop,…) đi kèm với các bit
dữ liệu. Các bộ truyền và bộ nhận sẽ dựa vào các bit đồng bộ này để quyết
định khi nào thì sẽ thực hiện hay kết thúc quá trình truyền hoặc nhận dữ liệu.
Do đó, hệ thống truyền không đồ bộ còn được gọi là hệ thống truyền “tự
đồng bộ”.

Từ hai kiểu truyền dữ liệu cơ bản trên, người ta đưa ra nhiều giao
thức (Protocol) truyền khác nhau như: SPI (đồng bộ), USRT (đồng bộ), UART (bất
đồng bộ),…Tuy vậy, cũng có giao thức truyền mà không thể xếp được vào kiểu
nào: đồng bộ hay bất đồng bộ, chẳn hạn kiểu truyền I2C (Trong AVR gọi là TWI),
tuy vậy một cách hơi gượng ép thì có thể thấy giao thức truyền I2C gần với kiểu
đồng bộ hơn vì các thiết bị giao tiếp với nhau theo chuẩn I2C điều dùng chung một
xung clock. Sơ đồ khối của cấu trúc truyền nhận nối tiếp USART và UART của
ATmega128, ATmega128 có hai bộ USART là USART0/UART0 và
USART1/UART1, dùng trong truyền nhận nối tiếp đồng bộ và không đồng bộ.
42

Hình 4.9: Sơ đồ khối bộ truyền nhận nối tiếp


4.1.6 Bộ biến đổi ADC
Bộ ADC chức năng biến đổi tín hiệu tương tự (analog signal) có giá trị thay
đổi trong một dải biết trước thành tín hiệu số (digital signal). Bộ ADC của
ATmega128 có độ phân giải 10 bit, sai số tuyệt đối ± 2 LSB, dải tín hiệu ngõ
vào từ 0V – VCC, tín hiệu ngõ vào có nhiều lựa chọn như : có 8 ngõ vào đa hợp
đơn hướng
(Multiplexed Single Ended), 7 ngõ vào vi sai (Differential Input), … Bộ ADC
của
ATmega128 là loại ADC xấp xỉ liên tiếp (succesive approximation ADC) với
hai chế độ hoạt động có thể lựu chọn là chuyển đổi liên tục (Free Running) và
chuyển đổi từng bước (Single Conversion). Sơ đồ khối đơn giản của một bộ ADC
được thể hiện ở hình
43

Hình 4.10: Bộ biến đổi ADC đơn giản

Nguyên tắc hoạt động của khối ADC : Tín hiệu tương tự đưa vào các ngõ
ADC0:7 được lấy mẫu và biến đổi thành tín hiệu số tương ứng. Tín hiệu số được
lưu trong hai thanh ghi ACDH và ADCL. Một ngắt có thể được tạo ra khi hoàn
thành một chu trình biến đổi ADC.
Thực tế, bộ ADC của ATmega128 phức tạp hơn nhiều, tuy nhiên cơ sở vẫn
dựa vào nguyên tắc trên. Để khảo sát bộ ADC của ATmega128 ta cần tìm hiểu các
khối chức năng sau:
 Điện Thế Tham Chiếu: là giá trị điện thế dùng để so sánh với điện
thế của tín hiệu tương tự cần biến đổi ở ngõ vào ADC. ATmega128 có 3 lựa
chọn điện thế tham chiếu là AVCC bằng với VCC, điện thế tham chiếu nội
2.56v, và Vref là tùy chọn. Bạn đọc cần để ý là AVR có 2 nguồn điện thế
tham chiếu nội là internal reference = 2.56v và bandgap reference = 1.24v.
Điện thế bandgap reference là một hằng số vật lý, nó luôn là 1.24v, còn điện
thế internal reference thì có thể thay đổi tùy theo các dòng chip khác nhau.
Trong AVR, internal reference được tạo ra từ bandgap reference. Trong tài
44

liệu này, tác giả điều dịch hai dạng điện thế trên điều là điện thế tham chiếu
nội, tuy vậy, bạn đọc nên hiểu sự khác nhau giữa hai khái niệm trên.
 Tần Số Clock ADC: là tần số clock cung cấp cho bộ biến đổi ADC,
giá trị có thể thay đổi từ vài KHz đến vài MHz. Tuy nhiên, tần số thích hợp
khoảng từ 50KHz đến 200KHz cho độ phân giải 10 bit và có thể cao hơn
200KHz nếu độ phân giải thấp hơn.
 Ngõ Vào Tương Tự: ATmega128 có hai lựa chọn ngõ vào tương
tự:
 10 ngõ vào đơn hướng (single ended): 10 ngõ vào này là
ADC0:7, AGND và bandgap reference. Thực tế ta thường dùng 8 ngõ
vào ADC0:7. Vì có 8 ngõ vào ADC0:7 nên ta có thể đưa vào 8 tín hiệu
tương tự khác nhau. Khi lựa chọn ngõ vào kiểu này (tức kiểu single
ended) thì kết quả chuyển đổi được tính như sau:

(4.1)

 Ngõ vào vi sai: Ta có thể đưa hai tín hiệu tương tự vào ngõ
vào ADC, hai tín hiệu tương tự này sẽ qua một bộ vi sai (mạch trừ), kết
quả ở ngõ ra có thể được khuếch đại rồi sau đó mới đưa vào khối ADC để
biến đổi. Bộ vi sai có 2 ngõ vào là Vpos (ngõ vào dương) và Vneg (ngõ
vào âm). Các chân ADC3:7 dùng làm ngõ vào dương, các chân ADC0:2
là ngõ vào âm, Đối với lựa chọn này, kết quả ADC sẽ là :

(4.2)

Ở đây Gain là độ lợi có thể tùy chọn. Công thức trên cho thấy kết quả ADC có
thể là số âm khi Vpos < Vneg. Do đó, dải giá trị của ADC trong trường hợp này là -
512 tới 511. Vì vậy, kết quả trong thanh ghi ADC được biểu diễn dưới dạng số bù
2. Để biết được kết quả là số âm hay dương ta kiểm tra bit ADC9 (trong thanh ghi
45

ADCH), nếu bit này là 1 thì kết quả là số âm, nếu bit này là 0 thì kết quả là số
dương.
Chú ý: Điện thế qua bộ vi sai có thể âm, nhưng điện thế cấp ở các ngõ vào
ADC0:7 (cho cả hai trường hợp ngõ vào vi sai và ngõ vào đơn hướng) phải luôn
nằm trong khoảng 0v – AVCC.

Hình 4.11: Ngõ vào vi sai

 Chế Độ Hoạt Động: Có hai chế độ hoạt động của bộ ADC là


chuyển đổi liên tục (Free Running) và chuyển đổi từng bước (Single
Conversion).
- Chuyển đổi liên tục: là chế độ mà sau khi khởi động thì bộ ADC thực
hiện chuyển đổi liên tục không ngừng.
- Chuyển đổi từng bước: là mà bộ ADC sau khi hoàn thành một chuyển
đổi thì sẽ ngừng, một chuyển đổi tiếp theo chỉ được bắt đầu khi phần mềm có
yêu cầu chuyển đổi tiếp.
Để hiểu rõ thêm về các thông số của ATmega128 ta có thể tra cứu trong datasheet
của ATmega128 của Atmel cung cấp.
46

Các bộ Driver điều khiển động cơ

4.1.7 Bộ Driver điều khiển động cơ dùng IC chuyên dụng DVR8432 (TI)

DVR8432 là IC chuyên dụng điều khiểu khiển động cơ được tích hợp bộ
cầu H bên trong với các chế độ được thiết lập bên ngoài, có bộ báo quá dòng,quá
áp, quá nhiệt và mạch bảo vệ.

Hình 4.12: Sơ đồ khối và sơ đồ chân của


DVR8432
47

DVR8432 có đặc điểm sau:


Nguồn cấp điều khiển VDD và GVDD là từ 10.8V đến 13.2V (yêu cầu nguồn
chuẩn)
Nguồn động lực PVDD trong dải từ 0V đến 70V
Dòng chịu tải 2 x 7A trong trường hợp hai kênh cùng hoạt động liên tục, và
14A trong khi hoạt động ở chế độ song song.
PWM hoạt động ở tần số cao có thể lên tới 500KHz.
DVR thích hợp cho việc điều khiển các động cơ DC trong công nghiệp và
trong nghiên cứu điều khiển chính xác.
4.1.8 Bộ Driver điều khiển động cơ dùng MC33486 và MC33887, MC33932
(Hãng Freescale)

Đặc điểm:
Điện áp hoạt động từ : 5VDC -28VDC.
Dòng điện cực đại của tải lên tới 10A đối với MC33486 và 5A đối với
MC33887, MC33932
Tần số xung PWM tối đa lên tới 10kHz.

Hình 4.13: Sơ đồ khối của MC 33486,


MC33887,MC33932

MC 33887 tích hợp bên trong 1 bộ cầu H nên chỉ điều khiển được một động
cơ, MC33486 điều khiển hai FET để điều khiển động cơ với dòng tải lên tới 10A
riêng MC33932 được tích hợp bên trong hai bộ cầu H nên điều khiển được hai động
cơ DC cùng lúc.
48

4.2 Xây dựng phần cứng và phần mềm của hệ thống bám đối tượng

Máy tính và lưu trữ Mạch VĐK

Camera Xử lý ảnh ATmega128

frame RF RF
RS232 RS232

Cảm biến
Driver ĐK
Công tác
Động cơ ĐC
hành trình

Hình 4.13: Cấu trúc hệ bám của đề tài

Cấu trúc của hệ bám gồm hai phần chính. Phần 1 xử lý ảnh dựa vào chuỗi hình
ảnh thu được từ camera để nhận dạng và tính toán vị trí của đối tượng mục tiêu.
Phần 2 là phần điều khiển, dựa vào thông số vị trí đối tượng nhận được trong mặt
phẳng ảnh, tính toán tín hiệu điều khiển rô bốt sao cho đối tượng di chuyển được
duy trì ở một vị trí nhất định trên mặt phẳng ảnh và ở một khoảng cách nhất định.
Trong quá trình tìm kiếm ta chia bức ảnh thành nhiều pixel bao gồm hai thành phần
hoặc thuộc đối tượng hoặc thuộc nền. Qua đó ta tiến hành xử lý các giá trị thuộc
tính của đối tượng trong vị trí mới và nhận dạng được đối tượng cần theo dõi.Mặt
phẳng ảnh là mặt phẳng có gốc nằm phía trên bên trái, truc x là trục nằm ngang, trục

X1
0 x

Y1

y Hình 4.14: Mặt phẳng ảnh


49

Căn cứ vào vị trí dịch chuyển của đối tượng trên mặt phẳng ảnh so với gốc tọa
độ mà ta tính toán được các khả năng di chuyển của rô bốt sao cho đối tượng nằm ở
một vị trí bất kỳ trên mặt phẳng ảnh.

Như vậy tất cả các yếu tố cần thiết để xây dựng một hệ thống triển khai thực
nghiệm đã đầy đủ, ta tiến hành và thiết kế phần cứng và lập trình phần mềm.

4.2.1 Phần cứng


Mạch phần cứng được chia làm 4 khối như sau:
-Khối điều khiển trung tâm ATmega128
-Khối nguồn cung cấp (Nguồn điều khiển+động lực)
-Khối Driver điều khiển động cơ
-Khối truyền thông RF và RS232
Khối điều khiển trung tâm ATmega128:

Hình 4.15: Mạch điều khiển trung tâm ATmega128


50

Khối nguồn cung cấp:

Hình 4.16: Mạch nguồn

Khối giao tiếp RS232 và RF:

Hình 4.17: Mạch giao tiếp RS232 và RF


51

Khối Driver điều khiển động cơ:

-MC33486:

Hình 4.18: Mạch điều khiển động cơ 33486


-MC33887:

Hình 4.19: Mạch MC33887


52

-MC33932:

Hình 4.20: Mạch MC33932

-DVR8432:

Hình 4.21: Mạch DVR8432


53

-DVR8432 kit:

Hình 4.22: DVR8432 kit

Hình ảnh mạch thực tế của hệ thống:

Hình4.23: Mạch MC thực tế


54

Hình 4.24: Mạch DVR8432 thực tế

Dff Hình 4.25: Mạch điều khiển trung tâm ATmega128


55

4.2.2 Giao diện phần mềm:

Giao diện phần mềm được thết kế thành các version với nhiều nhiệm vụ khác
nhau.

-Giao diện thứ nhất: giao diện phần mềm bám mục tiêu di động dùng thuật
toán Meanshift, có khả năng chụp ảnh, lưu ảnh và quay, lưu video.

Hình 4.26: Giao diện phần mềm dùng thuât toán Meanshift
56

-Giao diện thứ hai: Sử dụng thuật toán Camshift trên VC++ 6.0

Hình 4.27: Giao diện phần mềm trên VC++ 6.0


57

-Giao diện thứ ba: giao diện này được xây dựng đầy đủ trên Visual C++ 2008
với đầy đủ chức năng của một hệ thống bám.

Hình 4.27: Giao diện phần mềm trên VC++ 2008


58

Chương 5: ĐÁNH GIÁ VÀ CHẠY THỬ NGHIỆM


HỆ THỐNG
5.1 Ảnh thực nghiệm của mô hình hệ thống

Hình 5.1: Ảnh hệ thống thực tế chạy thử nghiệm khi


truyền không dây và thông qua RS2323
59

5.1 Đánh giá kết quả đạt được

Đồ án đã xây dựng được một hệ thống camera rô bốt bám mục tiêu di động, cả
về phần cứng lẫn chương trình phần mềm và giao diện điều khiển mục tiêu là các
đối tượng màu sẫm, hệ thống bám tốt trong điều kiện ánh sáng tốt và camera xử lý
tốt. Mục tiêu của đề tài hướng tới việc đưa công nghệ xử lý ảnh vào trong điều
khiển công nghiệp và trong rô bốt phát triển dựa trên hệ thống camera thông minh.
Nhằm phục vụ các công tác dò tìm phát hiện vật thể ở những điều kiện mà con
người không thể tới được như dò mìn, thám hiểm thu thập dữ liệu hoặc phục vụ
trong công tác an ninh. Hoàn chỉnh được cả phần cứng lẫn phần mềm của rô bốt,
tiến hành chạy thử nghiệm ở nhiều dạng môi trường khác nhau, ban ngày, ban đêm,
ánh sáng yếu, đường thẳng, vòng tròn,… và kết quả, rô bốt camera luôn giữ được
đối tượng nằm trên mặt phẳng ảnh mà ta đã chọn.
Báo cáo này mô tả hệ thống rô bốt camera rô bốt bám đối tượng sử dụng thư
viện xử lý ảnh OpenCV của Intel. Thuật toán sử dụng để nhận ảnh từ Camera tiến
hành khử nhiễu, histogram, sử dụng thuật toán Camshift, tính toán tọa độ tâm, kích
cỡ, góc, thiết kế khối vi điều khiển giao tiếp qua các chuẩn RS232 và chuẩn RF sử
dụng Mscomm trong Visual C. Thiết kế mạch điều khiển động cơ sử dụng vi điều
khiển ATmega128 và các IC chuyên dụng điều khiển cầu điều khiển động cơ DC và
60

kiểm soát tốc độ góc quay. Dưới điều kiện ánh sáng nhất định đối tượng có thể
được tìm ra nhanh chóng chính xác mà ít bị ảnh hưởng của nhiễu.
Tuy nhiên hệ thống đang trong giai đoạn phát triển nên việc thiết kế cơ khí
chưa được tốt, thẩm mỹ chưa cao, và muốn hệ thống chạy ổn định tốt hơn nữa cần
phải thiết kế hệ thống cơ khí chính xác. Chương trình sử dụng thuật toán Camshift
phải được kiểm nghiệm và phát triển để có thể chọn ra thuật toán tối ưu hơn
nữa.Kết hợp với bộ lọc Kalman để tăng khả năng chính xác, những điều này sẽ
được bổ xung trong thời gian gần đây để có thể có một hệ thống hoàn hảo. trong
thời gian tới sẽ nghiên cứu đưa ứng dụng mạng nơron (trí tuệ nhân tạo) vào công
nghệ xử lý ảnh và trong công nghệ bám ảnh và nhận dạng ảnh. Đó cũng chính là
hướng phát triển của đề tài trong thời gian tới.
61

KẾT LUẬN
Trong thời gian nghiên cứu cùng với những định hướng và hướng dẫn quý báu
của cô Hà Thị Kim Duyên, em đã hoàn thành đồ án của mình. Có thể nói rằng đồ án
này bược đầu là nền tảng định hướng cho em nghiên cứu và phát triển trong tương
lai.
Đồ án đã giải quyết được phần nào bài toán bám ảnh có màu sắc cố định (cụ
thể ở đây là ảnh màu tối).
Về mặt lý thuyết:
-Tổng quan về xử lý ảnh và thư viện mã nguồn mở Opencv
-Tìm hiểu và xây dựng được thuật toán xử lý ảnh tối ưu trong hệ bám
-Tìm hiểu về hệ thống bám đối tượng và các hệ tracking rô bốt.
Tuy nhiên cũng phải nói rằng dù đã cố gắng rất nhiều, nhưng chúng em vẫn
không tránh khỏi những sai sót trong việc xây dựng và thiết kế hệ thống cũng như là
cách thức trình bày một đồ án tốt nghiệp, vì vậy chúng em rất mong nhận được sự
chỉ bảo và đóng góp ý kiến của các thầy cô giáo cũng như các bạn sinh viên quan
tâm đến vấn đề này để đồ án của em hoàn thiện hơn.
Em xin chân thành cảm ơn!
62

Tài liệu tham khảo


Tiếng Việt:
1. Nhập môn xử lý ảnh số, ĐH Bách Khoa Hà Nội.
2. Nguyễn Văn Ngọ (2001), xử lý ảnh (dịch từ quyển Two Dimensional Signal
and Image Processing của tác giả Jae S.Lim)
3. Nguyễn Kim Sách (1997), xử lý ảnh và video số, NXB Khoa học kỹ thuật,
Hà Nội.
4. Ngô Diên Tập (1997) , xử lý ảnh bằng máy tính, NXB Khoa học kỹ thuật
Hà Nội.

Tiếng Anh:
1. David A. Forsyth & Jean Ponce (2003),Computer vision a moderm
approach, Prentic Hall PTR.
2. D.H. Ballard & C.M.Brown (1997), Computer vision, Prentice Hall PTR.
3. Jae S. Lim (1999),Two-Dimensional Signal and Image Processing.
Trang Web:
1.http://dientuvietnam.net.
2.http://picvietnam.com.
3.http://sourceforge.net/opencv/library.
4.http://atmel.com.
5.http://ti.com/forum.
6.http://freescale.com. và một số bài báo và tạp chí xử lý ảnh trên thế giới.
63

Phụ lục

Chương trình xử lý ảnh trên máy tính dùng thư viện OpenCV:
//Chương trình giao diện 1 chạy trên MFC Application VC++
// OpencvUIDlgDlg.cpp : implementation file
//Chuong Trinh Dieu Khien ma nguon mo.
//By HA TIEN THANH
//=================Chuong trình xử lý================

#include "stdafx.h"
#include "OpencvUIDlg.h"
#include "OpencvUIDlgDlg.h"
#include "cv.h"
#include "highgui.h"
/////////////////////////////////////////////////////////////
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
CvvImage m_CvvImage;
CvCapture * m_Video;
IplImage* m_Frame;//
IplImage* m_GrabFrame;//
CRect rect;
CDC *pDC;
HDC hDC;
CWnd *pwnd;
bool b_flagProcess;
bool b_flagSaveMovie=0;
bool b_flagTracking=0;
CvVideoWriter* m_Movie;
char chEdit[10];
double m_vieoProtery;
int m_fameCount=0;
long m_x,m_y,m_z;
//===============================
IplImage *imageTrack = 0, *hsvTrack = 0, *hueTrack = 0;
IplImage *maskTrack = 0, *backprojectTrack = 0, *histimgTrack = 0;//
CvHistogram *histTrack = 0;//
int backproject_mode = 0;
int select_object = 0;
64

int track_object = 0;
int show_hist = 1;
CvPoint origin;
CvRect selection;
CvRect track_window;
CvBox2D track_box; // Meanshift¸
CvConnectedComp track_comp;
int hdims = 50; //
float hranges_arr[] = {0,180};//
float* hranges = hranges_arr;//
int vmin = 10, vmax = 256, smin = 30;
int pointx, pointy;

class CAboutDlg : public CDialog


{
public:
CAboutDlg();

// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard generated virtual function overrides


//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV
support
//}}AFX_VIRTUAL

// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
virtual void OnOK();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)


{
CDialog::DoDataExchange(pDX);
65

//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COpencvUIDlgDlg dialog

COpencvUIDlgDlg::COpencvUIDlgDlg(CWnd* pParent /*=NULL*/)


: CDialog(COpencvUIDlgDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(COpencvUIDlgDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in
Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void COpencvUIDlgDlg::DoDataExchange(CDataExchange* pDX)


{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(COpencvUIDlgDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(COpencvUIDlgDlg, CDialog)
//{{AFX_MSG_MAP(COpencvUIDlgDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_BN_CLICKED(IDC_OPENCAMERA, OnOpencamera)
ON_BN_CLICKED(IDC_CLOSECAMERA, OnClosecamera)
ON_BN_CLICKED(IDC_GRABFRAME, OnGrabframe)
ON_BN_CLICKED(IDC_SAVEMOVIE, OnSavemovie)
ON_BN_CLICKED(IDC_STOPSAVEMOVIE, OnStopsavemovie)
ON_BN_CLICKED(IDC_STARTTRACKING, OnStarttracking)
ON_BN_CLICKED(IDC_STOPTRACKING, OnStoptracking)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
66

//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COpencvUIDlgDlg message handlers

BOOL COpencvUIDlgDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.


ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);


if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX,
strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here

pwnd = GetDlgItem(IDC_SHOWPIC);
pwnd->MoveWindow(35,30,640,480);
pDC =pwnd->GetDC();
//pDC =GetDC();
hDC= pDC->GetSafeHdc();
pwnd->GetClientRect(&rect);

CDC MemDC;
CBitmap m_Bitmap1;
m_Bitmap1.LoadBitmap(IDB_BLANK);
67

MemDC.CreateCompatibleDC(NULL);
MemDC.SelectObject(&m_Bitmap1);

//CClientDC dc(this);
pDC-
>StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,0,0,48,48,SR
CCOPY);

m_Bitmap1.DeleteObject();
MemDC.DeleteDC();
b_flagProcess=0;
Invalidate();
SetDlgItemText(IDC_EDIT_TIME,"Stop");
SetDlgItemText(IDC_EDIT_FRAME_WIDTH,"Stop");
SetDlgItemText(IDC_EDIT_FRAME_HEIGHT,"Stop");
SetDlgItemText(IDC_EDIT_FPS,"Stop");
SetDlgItemText(IDC_EDIT_FOURCC,"Stop");
SetDlgItemText(IDC_EDIT_FRAME_COUNT,"Stop");
SetDlgItemText(IDC_EDIT_X,"Stop");
SetDlgItemText(IDC_EDIT_Y,"Stop");
SetDlgItemText(IDC_EDIT_Z,"Stop");

//////////////////////////////////////////////////////

return TRUE; // return TRUE unless you set the focus to a control
}

void COpencvUIDlgDlg::OnSysCommand(UINT nID, LPARAM lParam)


{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void COpencvUIDlgDlg::OnPaint()
{
if (IsIconic())
68

{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM)
dc.GetSafeHdc(), 0);

// Center icon in client rectangle


int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon


dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}

if (!b_flagProcess)
{
CDC MemDC;
CBitmap m_Bitmap1;
m_Bitmap1.LoadBitmap(IDB_BLANK);
MemDC.CreateCompatibleDC(NULL);
MemDC.SelectObject(&m_Bitmap1);

//CClientDC dc(this);
pDC-
>StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,0,0,48,48,SR
CCOPY);

m_Bitmap1.DeleteObject();
MemDC.DeleteDC();
}
}

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR COpencvUIDlgDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
69

void COpencvUIDlgDlg::OnTimer(UINT nIDEvent)


{
// TODO: Add your message handler code here and/or call default
/**************************************************************
**********/
/* ÏÔʾÉãÏñÍ· */
/**************************************************************
**********/
m_Frame=cvQueryFrame(m_Video);
// cvNamedWindow("new",1);
// cvShowImage("new",m_Frame);
m_CvvImage.CopyOf(m_Frame,1);
if (!b_flagTracking)
{
m_CvvImage.DrawToHDC(hDC, &rect);
//cvWaitKey(10);
}
b_flagProcess=1;
// KillTimer(nIDEvent);

//=====================================================
m_vieoProtery=cvGetCaptureProperty(m_Video,CV_CAP_PROP_POS_
MSEC);

m_vieoProtery=cvGetCaptureProperty(m_Video,CV_CAP_PROP_FRA
ME_WIDTH);
itoa(m_vieoProtery,chEdit,10);
SetDlgItemText(IDC_EDIT_FRAME_WIDTH,chEdit);
m_vieoProtery=cvGetCaptureProperty(m_Video,CV_CAP_PROP_FRA
ME_HEIGHT);
itoa(m_vieoProtery,chEdit,10);
SetDlgItemText(IDC_EDIT_FRAME_HEIGHT,chEdit);

m_vieoProtery=cvGetCaptureProperty(m_Video,CV_CAP_PROP_FPS);
itoa(m_vieoProtery,chEdit,10);
SetDlgItemText(IDC_EDIT_FPS,chEdit);

m_vieoProtery=cvGetCaptureProperty(m_Video,CV_CAP_PROP_FOU
RCC);

m_fameCount++;
m_vieoProtery=cvGetCaptureProperty(m_Video,CV_CAP_PROP_FRA
ME_COUNT);
itoa(m_fameCount,chEdit,10);
SetDlgItemText(IDC_EDIT_FRAME_COUNT,chEdit);
//============tạo trackbox==================
m_x=track_window.x+track_window.width/2;
70

itoa(m_x,chEdit,10);
SetDlgItemText(IDC_EDIT_X,chEdit);

m_y=track_window.y+track_window.height/2;
itoa(m_y,chEdit,10);
SetDlgItemText(IDC_EDIT_Y,chEdit);

m_z=(track_window.width+track_window.height)/2;
itoa(m_z,chEdit,10);
SetDlgItemText(IDC_EDIT_Z,chEdit);

//=============================================
if (b_flagSaveMovie)
{
if (!m_Movie)
return;
cvWriteFrame(m_Movie,m_Frame);
}
//=====Chuyển đổi không gian màu RGB => HSV=======

int i, bin_w, c;
if (!b_flagTracking)
return;

cvCopy( m_Frame, imageTrack, 0 );


cvCvtColor( imageTrack, hsvTrack, CV_BGR2HSV ); // °

if( track_object )//


{
int _vmin = vmin, _vmax = vmax;

cvInRangeS( hsvTrack,
cvScalar(0,smin,MIN(_vmin,_vmax),0),cvScalar(180,256,MAX(_vmin,_vmax),
0), maskTrack ); //
cvSplit( hsvTrack, hueTrack, 0, 0, 0 ); //

if( track_object < 0 )//


{
float max_val = 0.f;
cvSetImageROI( hueTrack, selection ); //
cvSetImageROI( maskTrack, selection ); //

cvCalcHist( &hueTrack, histTrack, 0, maskTrack ); //

cvGetMinMaxHistValue( histTrack, 0, &max_val, 0, 0 );


71

cvConvertScale( histTrack->bins, histTrack->bins, max_val ?


255. / max_val : 0., 0 ); //
cvResetImageROI( hueTrack ); // remove ROI
cvResetImageROI( maskTrack );
track_window = selection;
track_object = 1;

cvZero( histimgTrack );
bin_w = histimgTrack->width / hdims;

for( i = 0; i < hdims; i++ )


{
int val = cvRound(
cvGetReal1D(histTrack->bins,i)*histimgTrack-
>height/255 );
CvScalar color = hsv2rgb(i*180.f/hdims);
cvRectangle( histimgTrack,
cvPoint(i*bin_w,histimgTrack->height),
cvPoint((i+1)*bin_w,histimgTrack->height -
val),color, -1, 8, 0 );//
}
}

cvCalcBackProject( &hueTrack, backprojectTrack, histTrack ); //

cvAnd( backprojectTrack, maskTrack, backprojectTrack, 0 );//


cvCamShift( backprojectTrack, track_window,cvTermCriteria(
CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),&track_comp,
&track_box );//
track_window = track_comp.rect;//

if( backproject_mode )
cvCvtColor( backprojectTrack, imageTrack, CV_GRAY2BGR
); //
if( imageTrack->origin )
track_box.angle = -track_box.angle;
cvEllipseBox( imageTrack, track_box, CV_RGB(255,0,0), 3, CV_AA, 0 );//
}

if( select_object && selection.width > 0 && selection.height > 0 )//


{
cvSetImageROI( imageTrack, selection );
cvXorS( imageTrack, cvScalarAll(255), imageTrack, 0 );
cvResetImageROI( imageTrack );
}
72

m_CvvImage.CopyOf(imageTrack,1);
m_CvvImage.DrawToHDC(hDC, &rect);
//=============Thiết lập timer================
CDialog::OnTimer(nIDEvent);
}

CvScalar COpencvUIDlgDlg:: hsv2rgb( float hue )//


{
int rgb[3], p, sector;
static const int sector_data[][3]={{0,2,1}, {1,2,0}, {1,0,2}, {2,0,1}, {2,1,0},
{0,1,2}};
hue *= 0.033333333333333333333333333333333f;
sector = cvFloor(hue);
p = cvRound(255*(hue - sector));
p ^= sector & 1 ? 255 : 0;

rgb[sector_data[sector][0]] = 255;
rgb[sector_data[sector][1]] = 0;
rgb[sector_data[sector][2]] = p;

return cvScalar(rgb[2], rgb[1], rgb[0],0);//


}

void COpencvUIDlgDlg::OnOpencamera()
{
// TODO: Add your control notification handler code here

//m_Video=cvCaptureFromCAM(-1);
if (!m_Video)
m_Video=cvCreateCameraCapture(-1);//HIGHGUI
//

if (!m_Video)
{
int nChoice = MessageBox("No
Camera","Note!",MB_OK|MB_ICONWARNING);
if(nChoice=IDOK) {}

return;
}

SetTimer(1,100,NULL);
73

void COpencvUIDlgDlg::OnClosecamera()
{
// TODO: Add your control notification handler code here
KillTimer(1);
cvReleaseCapture(&m_Video);
cvReleaseVideoWriter(&m_Movie);
b_flagProcess=0;
m_fameCount=0;
b_flagSaveMovie=0;

CDC MemDC;
CBitmap m_Bitmap1;
m_Bitmap1.LoadBitmap(IDB_BLANK);
MemDC.CreateCompatibleDC(NULL);
MemDC.SelectObject(&m_Bitmap1);
pDC-
>StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,0,0,48,48,SR
CCOPY);
m_Bitmap1.DeleteObject();
MemDC.DeleteDC();

SetDlgItemText(IDC_EDIT_TIME,"Stop");
SetDlgItemText(IDC_EDIT_FRAME_WIDTH,"Stop");
SetDlgItemText(IDC_EDIT_FRAME_HEIGHT,"Stop");
SetDlgItemText(IDC_EDIT_FPS,"Stop");
SetDlgItemText(IDC_EDIT_FOURCC,"Stop");
SetDlgItemText(IDC_EDIT_FRAME_COUNT,"Stop");
SetDlgItemText(IDC_EDIT_X,"Stop");
SetDlgItemText(IDC_EDIT_Y,"Stop");
SetDlgItemText(IDC_EDIT_Z,"Stop");
}

void COpencvUIDlgDlg::OnGrabframe()
{
if (!m_Video)
{
int nChoice = MessageBox("No
camera!","Note",MB_OK|MB_ICONWARNING);
if(nChoice == IDOK){};
return;
}

m_GrabFrame=cvQueryFrame(m_Video);
74

if (!m_GrabFrame)
return;

static char countsnap='1';


CString m_name="";
m_name=+countsnap;
m_name+=".bmp";

IplImage *
m_snap=cvCreateImage(cvGetSize(m_GrabFrame),m_GrabFrame-
>depth,m_GrabFrame->nChannels);
cvCopy(m_GrabFrame,m_snap,NULL);
m_snap->origin=0;
const char* pszStr = m_name.GetBuffer(m_name.GetLength());
cvSaveImage(pszStr,m_snap); //

countsnap++;

void COpencvUIDlgDlg::OnSavemovie()
{
// TODO: Add your control notification handler code here
//m_Movie=cvCreateVideoWriter("video.avi",-1,10,cvSize(352,288),1);
if (b_flagProcess)
{

//m_Movie=cvCreateVideoWriter("video.avi",CV_FOURCC('P','I','M','1
'),10,cvSize(352,288),1);
m_Movie=cvCreateVideoWriter("video.avi",-
1,10,cvSize(640,480),1);
b_flagSaveMovie=1;
}
else
MessageBox("No
Camera","Note",MB_OK|MB_ICONWARNING);

void COpencvUIDlgDlg::OnStopsavemovie()
{
// TODO: Add your control notification handler code here
cvReleaseVideoWriter(&m_Movie);
b_flagSaveMovie=0;
}

void COpencvUIDlgDlg::OnStarttracking()
75

{
// TODO: Add your control notification handler code here
if (!b_flagProcess)
{
MessageBox("Press Button
Start!","Note",MB_OK|MB_ICONWARNING);
return;
}

b_flagTracking=1;
imageTrack=0;
track_object=-1;

if (!imageTrack)
{
imageTrack = cvCreateImage( cvGetSize(m_Frame), 8, 3 );//
imageTrack->origin = m_Frame->origin;
hsvTrack = cvCreateImage( cvGetSize(m_Frame), 8, 3 );
hueTrack = cvCreateImage( cvGetSize(m_Frame), 8, 1 );
maskTrack = cvCreateImage( cvGetSize(m_Frame), 8, 1 );//
backprojectTrack = cvCreateImage( cvGetSize(m_Frame), 8, 1
);//
histTrack = cvCreateHist( 1, &hdims, CV_HIST_ARRAY,
&hranges, 1 ); //·
histimgTrack = cvCreateImage( cvSize(320,200), 8, 3 );//·
cvZero( histimgTrack );//
}

origin = cvPoint(150,150);
selection = cvRect(150,150,20,20);//
// cvNamedWindow( "CamShiftDemo", 1 );//
// cvNamedWindow( "Histogram", 1 );
// cvSetMouseCallback( "CamShiftDemo", on_mouse ); //

void COpencvUIDlgDlg::OnStoptracking()
{
// TODO: Add your control notification handler code here
b_flagTracking=0;
imageTrack=0;
track_object=0;
}

void COpencvUIDlgDlg::OnMouseMove(UINT nFlags, CPoint point)


76

{
// TODO: Add your message handler code here and/or call default

//pwnd = GetDlgItem(IDC_SHOWPIC);
//pwnd->GetWindowRect(&rect);
//pwnd->MoveWindow(35,30,352,288);
//if ((point.x>rect.left)&&(point.x<rect.right)&&
(point.y>rect.top)&&(point.y<rect.bottom))
if ((point.x>35)&&(point.x<675)&& (point.y>30)&&(point.y<510))
{
SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR1));

if (select_object)
{
pointx=point.x-35;
pointy=point.y-30;
if( imageTrack->origin )
pointy = 480 - pointy;//480
selection.x = MIN(pointx,origin.x);
selection.y = MIN(pointy,origin.y);
selection.width = selection.x + CV_IABS(pointx - origin.x);
selection.height = selection.y + CV_IABS(pointy - origin.y);
selection.x = MAX( selection.x, 0 );
selection.y = MAX( selection.y, 0 );
selection.width = MIN( selection.width, imageTrack->width );
selection.height = MIN( selection.height, imageTrack->height );
selection.width -= selection.x;
selection.height -= selection.y;

}
}

CDialog::OnMouseMove(nFlags, point);
}

void COpencvUIDlgDlg::OnLButtonDown(UINT nFlags, CPoint point)


{
// TODO: Add your message handler code here and/or call default

if( !imageTrack )
{
MessageBox("Press Button
StartTracking!","Note!",MB_OK|MB_ICONWARNING);
return;
}
77

if ((point.x>35)&&(point.x<387)&& (point.y>30)&&(point.y<318))
{

pointx=point.x-35;
pointy=point.y-30;
if( imageTrack->origin )
pointy = 288 - pointy;

if (imageTrack->width==800)
{
pointx=pointx*640/352;
pointy=pointy*480/288;
}

origin.x = pointx;
origin.y = pointy;

selection = cvRect(pointx,pointy,0,0);//

select_object = 1;//¡
}

CDialog::OnLButtonDown(nFlags, point);
}

void COpencvUIDlgDlg::OnLButtonUp(UINT nFlags, CPoint point)


{
// TODO: Add your message handler code here and/or call default
select_object = 0;//
if( selection.width > 0 && selection.height > 0 )
track_object = -1;//

CDialog::OnLButtonUp(nFlags, point);
}

void COpencvUIDlgDlg::OnAboutbox()
{
// TODO: Add your control notification handler code here
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
78

void CAboutDlg::OnOK()
{

CDialog::OnOK();
}

void COpencvUIDlgDlg::OnCancel()
{
// TODO: Add extra cleanup here
int user_choice =
MessageBox("Exit?","Exit!",MB_OKCANCEL|MB_ICONWARNING);
if(user_choice == IDOK)
/*{
if(m_Video)
destoryWindow();
};*/

CDialog::OnCancel();
}

BEGIN_EVENTSINK_MAP(COpencvUIDlgDlg, CDialog)
//{{AFX_EVENTSINK_MAP(COpencvUIDlgDlg)

//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

You might also like