Tài liệu Khóa luận Xử lý ảnh và ứng dụng theo dõi đối tượng chuyển động: ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
Lê Anh Vũ
XỬ LÝ ẢNH VÀ ỨNG DỤNG THEO DÕI ĐỐI TƯỢNG
CHUYỂN ĐỘNG
KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC CHÍNH QUY
Ngành : Công Nghệ Điện Tử - Viễn Thông
HÀ NỘI 2005
ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
Lê Anh Vũ
XỬ LÝ ẢNH VÀ ỨNG DỤNG THEO DÕI ĐỐI TƯỢNG
CHUYỂN ĐỘNG
KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC CHÍNH QUY
Ngành : Công Nghệ Điện Tử - Viễn Thông
Cán bộ hướng dẫn : Nguyễn Vinh Quang
HÀ NỘI 2005
Lời cảm ơn
Để hoàn thành được khóa luận này đó là sự giúp đỡ nhiệt tình và hết sức tạo
điều kiện của các thầy cô và nhà trường cùng các bạn trong lớp , Sự tận tình và
cảm thông của gia đình,anh em.
Em xin chân thành cảm ơn thầy Nguyễn Vinh Quang, người đã hưỡng dẫn
em làm khóa luận này, thầy đã nhiệt tình giúp đỡ em trong suốt quá trình làm
khóa luận về cả vật chất lẫn tinh thần.
Em xin cảm ơn Nhà Trường và đặc biệt là các thầy cô của khoa Điện Tử thuộc
Phòng Thí Nghiệm ROBOTIC của Trường, những người...
62 trang |
Chia sẻ: haohao | Lượt xem: 1250 | Lượt tải: 0
Bạn đang xem trước 20 trang mẫu tài liệu Khóa luận Xử lý ảnh và ứng dụng theo dõi đối tượng chuyển động, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
Lê Anh Vũ
XỬ LÝ ẢNH VÀ ỨNG DỤNG THEO DÕI ĐỐI TƯỢNG
CHUYỂN ĐỘNG
KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC CHÍNH QUY
Ngành : Công Nghệ Điện Tử - Viễn Thông
HÀ NỘI 2005
ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
Lê Anh Vũ
XỬ LÝ ẢNH VÀ ỨNG DỤNG THEO DÕI ĐỐI TƯỢNG
CHUYỂN ĐỘNG
KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC CHÍNH QUY
Ngành : Công Nghệ Điện Tử - Viễn Thông
Cán bộ hướng dẫn : Nguyễn Vinh Quang
HÀ NỘI 2005
Lời cảm ơn
Để hoàn thành được khóa luận này đó là sự giúp đỡ nhiệt tình và hết sức tạo
điều kiện của các thầy cô và nhà trường cùng các bạn trong lớp , Sự tận tình và
cảm thông của gia đình,anh em.
Em xin chân thành cảm ơn thầy Nguyễn Vinh Quang, người đã hưỡng dẫn
em làm khóa luận này, thầy đã nhiệt tình giúp đỡ em trong suốt quá trình làm
khóa luận về cả vật chất lẫn tinh thần.
Em xin cảm ơn Nhà Trường và đặc biệt là các thầy cô của khoa Điện Tử thuộc
Phòng Thí Nghiệm ROBOTIC của Trường, những người mà hàng ngày vẫn tạo điều
kiện và bảo ban em.
Cảm ơn các bạn lớp K46DC, nhưng người luôn sát cánh và chia sẻ cùng
mình!
Hà Nội, ngày 05/06/2005
Mục lục
Mở đầu…………………………………………………………………………….1
Phần 1: LÝ THUYẾT XỬ LÝ ẢNH …………………………………………….2
Chương 1: Lý Thuyết xử lý ảnh …………………………………………………2
1.1:Thu nhận ảnh và số hóa…………………………………………………2
1.2:Phân tích ảnh…………………………………………………………….2
1.3:Quyết định………………………………………………………………..3
Chương 2: Thu nhận hình ảnh…………………………………………… …...3
2.1:Thu nhận ảnh…………………………………………………………….3
2.2:Lưu ảnh…………………………………………………………………..7
Chương 3: Phân tích ảnh……………………………………………………….…8
3.1:Khái niệm pixel và pixil lân cận…………………………………………8
3.2:Một số công cụ trợ giúp xử lý ảnh………………………………………8
3.2.1:Tích chập………………………………………………………………..8
3.2.2:Kỹ thuật lọc số………………………………………………………….11
3.2.3:Biến đổi Fourier……………………………………………………….. 11
3.3:Tiền xử lý…………………………………………………………………16
3.3.1:Phương pháp tiền xử lý trong miền không gian……………………..16
3.3.2:Phương pháp tiền xử lý trong miền tần số…………………………...17
3.4:Làm trơn ảnh………………………………………………………….…18
3.4.1:Lấy trung bình các điểm ảnh lân cận, lọc tuyến tính………………..18
3.4.2:Phương pháp lọc trung vị……………………………………………..19
3.4.3:Trung bình hóa hình ảnh……………………………………………...19
3.4.4:Làm trơn hình ảnh nhị phân………………………………………….20
3.5:Phát hiện biên…………………………………………………………….22
3.6:Lập ngưỡng………………………………………………………………25
Phần 2: PHẦN THỰC NGHIỆM:……………………………………………….....26
Chương 1: Ngôn ngữ lập trình……………………………………………...28
Chương 2:Điều khiển công LPT trên Win200/NT/XP…………………….31
Chương 3:Minh họa thuật toán và chương trình………………………….34
Tài liệu tham khảo:………………………………………………………………….52
TÓM TẮT NỘI DUNG KHÓA LUẬN:
Nội dung của khóa luận là ứng dụng lý thuyết của xử lý ảnh số qua thiết bị thu ảnh , ở
đây là web camera để điều khiển một hệ cơ tự động theo dõi đối tượng chuyển động.
Khóa luận được chia làm hai phần chính, phần lý thuyết và phần thực nghiệm :
-Trong phần lý thuyết , ta sẽ tìm hiểu các khái niệm cơ bản của xử lý ảnh số,
bao gồm lý thuyết về Xử lý ảnh,Thu nhận hình ảnh và Phân tích ảnh.
-Ở phần này, giới thiệu các khái niệm về xử lý ảnh và ứng dụng các thuật toán
về xử lý ảnh như là công cụ toán học tích chập, các phưong pháp tiền xử lý : lọc nhiễu,
phát hiện biên, phân ngưỡng ảnh….
-Phần thực hành gồm 3 phần:
Phần 1 tìm hiểu ngôn ngữ lập trình và thư viện AVICap của Microsoft.
Phần 2 sẽ giới thiệu về cách giao tiếp và điều khiển công LPT trên VC++.
Phần 3 là phần chính , bao gồm thuật toán và chương trình chính điều khiển.
LỜI MỞ ĐẦU
Trong mấy thập kỷ gần đây, xử lý ảnh đã được nghiên cứu mạnh mẽ và đã có
rất nhiều ứg dụng trong thực tế. Như trong y học, xử lý ảnh số đã được dùng để phát
hiện và nhận dạng khối u , cải thiện ảnh X quang , nhận dạng đường biên mạch máu
từ những ảnh chụp mạch bằng tia X. trong cuộc sống gia đình, xử lý ảnh được dùng để
cải thiện ảnh Ti vi. Trong truyền thông video như hội nghị video, điện thoại video thì
một vấn đề chính là cần có giải tần rộng. Việc mã hóa thẳng các chương trình video
chất lượn quảng bá cần đến 100 triệu bit/s. Điều này không thể đáp ứng được.Nhưng
bằng cách mã hóa số và khôi phục ảnh (là những vấn đề của xử lý ảnh ) thì việc trên
có thể thực hiện chỉ với băng tần 100 nghìn bit/s. Còn trong lĩnh vực khoa học kỹ
thuật, xử lý ảnh đã và đang có những đóng góp quan trọng, đặc biệt là trong lĩnh vực
Robot. Robot thông minh ngày nay không thể thiếu yếu tố xử lý ảnh. Đó là các vấn đề
nhận dạng các đối tượng ngoài môi trường. Từ việc nhận dạng có thể giải quyết rất
nhiều bài toán như tránh vật cản, dò đường....Xử lý ảnh có thể được chia ra làm các
quá trình sau: Thu nhận hình ảnh, phân tích ảnh và quyết định.
Mô hình sản phẩm theo dõi đối tượng dùng camera .
PHẦN 1: LÝ THUYẾT XỬ LÝ ẢNH
CHƯƠNG 1 : HỆ THỐNG XỬ LÝ ẢNH
Một hệ thống xử lý ảnh điển hình được cho trên hình vẽ sau:
Hình 1.1, Các giai đoạn chính trong xử lý ảnh.
Thu nhận
ảnh Số hoá
Phân tích
ảnh
Nhận
dạng
Lưu
trữ
Lưu trữ
Hệ quyết định
Thiết bị thu nhận
ảnh (Camera.
Sensor)
Từ hình vẽ 1.1 ta thấy một hệ thống xử lý ảnh bao gồm thu nhận ảnh, số hóa
ảnh, phân tích ảnh và cuối cùng là quyết định (tùy thuộc vào yêu cầu ứng dụng cụ
thể mà đưa ra quyết định cho phù hợp)
1.1 Thu nhận ảnh và số hóa
Việc thu nhận ảnh có thể thông qua camera. Các camera có thể hoặc là tương tự
(loại camera ống kiểu CCIR) hoặc là số (loại camera kiểu CCD_ Charge Coupled
Device). Ảnh cũng có thể được thu qua các thiết bị khác như máy quét v..v . Nếu ảnh
nhận được là tương tự nó phải được số hóa nhờ quá trình lấy mẫu và lượng tử hóa
trước khi phân tích, xử lý hay lưu trữ ảnh.
1.2 Phân tích ảnh
Ở giai đoạn này ảnh được xử lý theo nhiều công đoạn nhỏ như: cải thiện ảnh, khôi
phục ảnh để làm nổi bật một số đặc tính chính của ảnh hay làm ảnh gần với trạng thái
gốc. Tiếp theo là phát hiện các đặc tính như biên, phân vùng.
1.3 Quyết định
Cuối cùng tùy theo mục đích của ứng dụng, sẽ là giai đoạn nhận dạng hay các
quyết định khác.
CHƯƠNG 2: THU NHẬN HÌNH ẢNH
2.1 Thu nhận ảnh
Để thu nhận ảnh người ta thường dùng các camera truyền hình, các camera gồm
tube hoặc sensor mạch rắn và các thiết bị điện tử đi kèm. Camera sensor mạch rắn
có một số ưu điểm so với camera tube như nhẹ hơn, nhỏ hơn, bền hơn, bền hơn và
tiêu thụ công suất thấp hơn. Tuy nhiên, một số camera tube có độ phân giải cao
hơn camera sensor mạch rắn. Một trong số những loại được sử dụng phổ biến của
camera tivi là Vidicon.
Camera Vidicon là một vỏ kính hình lăng trụ chứa một súng phóng electron ở đầu
và một màn hình (faceplate) ở đầu kia. Dòng electron được hội tụ và làm lệch điện
áp đặt vào các cuộn dây như trên hình vẽ 2.1. Mạch làm lệch làm cho dòng electron
quết lên bề mặt trong của màn hình để “đọc” hình ảnh . Bề mặt bên trong của màn
hình được phủ một màng mỏng kim loại trong suốt, màng mỏng này tạo thành một
điện cực mà từ đó tạo ra tín hiệu điện của hình ảnh. Một lớp nhạy sáng được phủ
trên màng mỏng kim loại. Lớp tạo thành bao gồm những quả cầu trở kháng có kích
cỡ rất nhỏ, trở kháng của những quả cầu này tỷ lệ nghịch với cường độ sáng của
nó.. Phía sau lớp nhạy sáng đó có một lưới tích điện dương để giảm tốc các
electron được phát ra từ súng phóng electron sao cho khi các electron này tới bề
mặt đích về cơ bản vận tốc là bằng không.
Ở chế độ hoạt động bình thường, điện áp dương được đặt vào lớp kim loại của màn
hình. Khi không có ánh sáng, lớp nhạy sáng đóng vai trò như chất điện môi, dòng
electron phủ một lớp electron lên bề mặt bên trong của màn hình để cân bằng với
điện tích dương trên lớp kim loại. Khi chùm electron quét bề mặt của màn hình,
lớp nhày sáng trở th ành một tụ điện với điện tích âm trên bề mặt phía trong và điện
tích dương ở bề mặt đối diện. Khi ánh sáng va vào màn hình, trở kháng của nó
giảm và el ectron được phép chuyển động tự do và trung hòa với điện tích dương.
Vì lượng điện tích chuyển động tự do tỷ l ệ với ánh sáng trong một vùng cục bộ bất
kỳ của màn hình, hiệu ứng này t ạo ra một hình ảnh trên màn hình giống với ảnh
chiếu trên màn hình của tube. Nghĩa là, sự tập trung của c ác điện tích electron là
cao trong các vùng tối và thấp hơn trong các vùng sáng. Khi dòng electron quét
màn hình lần thứ hai nó thay thế các điện tích bị mất, và do đó tạo thành một dòng
điện chảy trong lớp kim loại và ở phía ngoài của một trong các chân tube. Dòng
này tỷ lệ với số electron được thay thế và do đó tỷ l ệ với cường độ sáng tại vị trí
cụ thể của dòng quét. Sự thay đổi này khi dòng electron quét sẽ tạo ra một tín hiệu
hình ảnh tỷ lệ với cường độ của ảnh đầu vào.
Cuộn hội tụ dòng electron: Lớp nhạy sáng
Các chân tube
Màn hình
Lưới
Dòng electron
Súng phóng electron
Lớp phủ kim loại trong suốt
Cuộn làm lệch dòng electron
Hình 2.1.Sơ đồ một vidicon
Hình 2.2 Mẫu quét dòng electron:
Hình 2.2 minh họa một chuẩn quét.Dòng electron quét toàn bộ màn hình 30 lần
mỗi giây, mỗi một vết quét hoàn chỉnh (gọi là một khung) gồm 525 dòng trong đó có
480 dòng chứa thông tin về hình ảnh. Nếu các dòng được quét một cách tuần tự và kết
quả được hiển thị lên một màn hình TV, hình ảnh sẽ nhấp nháy rõ rệt. Có thể khắc
phục hiện tượng này bằng cách sử dụng cơ cấu quét mà trong đó mỗi khung được chia
ra thành hai trường mành xen kẽ nhau, mỗi trường gồm 2625 dòng và được quét 60 lần
trong một giây hay tốc độ khung tăng lên gấp đôi. Trường hợp đầu tiên của mỗi khung
quét các dòng lẻ (là các đường chấm chấm trong hình 2.2) trong khi đó mành thứ hai
quét các dòng chẵn. Sơ đồ quết này được gọi chuẩn là RETMA (Radio-Electronics
Television Manufacturers Association ). Hiệp hội các hãng chế tạo Radio, Tivi, và
máy móc điện tử). Các chuẩn khác có tốc độ dòng trên mỗi mành cao hơn , nhưng về
cơ bản nguyên lý hoạt độn4g của các mạch này là giống nhau.
Các thiết bị CCD gồm hai loại: Sensor quét dòng và sensor khối. Thành phần cơ
bản của Sensor CCD quét dòng là một hàng phân tử ảnh silic gọi là photosites. Các
photo hình ảnh cho qua một cấu trúc cổng đa tinh thể trong suốt và được hấp thụ
trong tinh thể silic, do đó tạo nên một cặp lỗ electron. Các quang điện tử tạo ra
được tập hợp vào các photosite, lượng điện tích được tập hợp trong mỗi photosite
tỷ lệ với cường độ chiếu sáng tại điểm đó. Một sensor quét dòng điển hình gồm
một hàng các phân tử ảnh photosite, hai cổng truyền được sử dụng để chốt lại nội
dung của các phần tử hình ảnh vào các thanh ghi vận chuyển và một cổng nối ra
được sử dụng để chốt nội dung của các thanh ghi vận chuyển vào bộ khuyếch đại,
lối ra của bộ khuyếch đại này là một tín hiệu điện áp tỷ lệ với các nội dung của
hàng photosites.
Các thanh
Ghi điều khiển
. Lối ra
.
.
.
Thanh ghi vận chuyển
Cổng
N Photosites 2 1
Bộ
khuếch
đại
Cổng
Lối
Ra
Thanh ghi truyền
Cổng
Hình 2.3.Sensor quét dòng CCD
Các mảng khối ghép diện tích giống các sensor quét dòng, ngoại trừ các photosite
được sắp xếp theo dạng ma trận và có một tổ hợp thanh ghi vận chuyển cổng giữa
các cột photosite như trong hình 2.4. Nội dung của các photosite lẻ được chốt lần
lượt vào các thanh ghi vận chuyển dọc và sau đó lại được chốt vào các thanh ghi
vận chuyển ngang. Nội dung của các thanh ghi vận chuyển ngang này được dẫn
vào bộ khuyếch đại, lối ra của bộ khuyếch đại là một dòng lẻ hình ảnh. Thực hiện
tương tự với các photosite chẵn để hoàn thành trường thứ hai của khung TV. Cơ
cấu quét này được lặp lại 30 lần mỗi giây.
Các camera quét dòng chỉ cho ra một dòng hình ảnh của hình ảnh lối vào. Những
thiết bị này đặc biệt phù hợp cho các ứng dụng mà các đối tượng chuyển động qua
sensor (như trong các băng truyền) . Sự chuyển động của một đối tượng theo hướng
vuông góc với sensor tạo ra hình ảnh hai chiều. Các sensor quét dòng có độ phân giải
thấp 32x3, trung bình 256x256 và cao 480 phân tử ảnh và các sensor thí nghiệm CCD
có khả năng đạt được độ phân giải khoảng 1024x1024 hay cao hơn.
Ở đây, ta ký hiệu ảnh lối ra hai chiều của camera hay thiết bị cho ảnh khác là
f(x,y) trong đó x, y biểu thị toạ độ không gian (ví dụ mặt phẳng ảnh) và giá trị f tại
điểm (x,y) bất kỳ tỷ lệ với toạ độ (cường độ sang) của hình ảnh tại điểm đó . Hình 2.5
minh hoạ một điểm ảnh và quy ước toạ độ của nó.
Hình 2.5. Quy ước toạ độ cho biểu diễn hình ảnh Giá trị của điểm ảnh (x.y) bất kỳ
được cho bởi giá trị (cường độ sáng) của f tại điểm đó.:
Gốc hình ảnh
y
f(x,y)
•
x
Để máy tính có thể xử lý, hàm ảnh (x,y) phải được số hoá cả về không gian lẫn
biên độ (cường độ). Việc số hoá các toạ độ không gian (x,y) được coi như là việc lấy
mấu hình ảnh, trong khi đó việc số hoá biên độ được coi là lượng tử hoá cường độ cho
những hình ảnh đơn sắc và phản ảnh bản chất của các ảnh này là biến thiên từ đen tới
trắng theo các mức xám khác nhau. Hai thuật ngữ cường độ sang và mức xám có thể
dung hoán chuyển cho nhau.
Giả sử một hình ảnh liên tục được lấy mẫu đồng nhất cho một mảng N hang và M
cột, ở đây mỗi mẫu cũng được lượng tử hoá về biên độ. Mảng này được gọi là ảnh số,
có thể được viết như sau:
F(x,y) =
( ) ( ) ( )[ ]
( ) ( ) ( )
( ) ( ) ( 1,1........1,10,1
................................................................
1,1.......................1,10,1
1,0....................1,0,0
−−−−
−
)
−
MNfNfNf
Mfff
mfoff
(2.1)
ở đây các biến rời rạc:x=0, 1, 2 …, N-1
y= 0, 1, 2, …, M-1
Mỗi phần tử trong mảng được gọi là một phần tử ảnh hay pixel. Từ mảng ta thấy
pixel tại gốc của ảnh được biểu thị là f(0,0), pixel bên phẩi là f(0,1), v.v. Thông thường
N, M và số mức cường độ rời rạc của mỗi pixel đã lượng tử hoá là luỹ thừa nguyên
của 2.
2.2 Lưu ảnh.
Để lưu trữ ảnh trên máy tính, một số định dạng ảnh đã được nghiên cứu như
IMG, PCX, TIFF, GIF.
Định dạng ảnh IMG dung cho ảnh đen trắng. Phần đầu của ảnh IMG có 16 byte
chứa các thông tin:
• 6 byte đầu: dung để đánh dấu định dạng ảnh IMG. Giá trị của 6 byte này được
viết là 0x0001 0x0008 0x0001.
• 2 byte tiếp theo: chứa độ dài mẫu tin. Đó là độ dài của dãy các byte kề liền nhau
mà dãy này sẽ được lặp lại một số lần nào đó. Số lần lặp lại này sẽ được lưu
trong byte đếm. Nhiều dãy giống nhau được lưu trong một byte. Đây là một
cách lưu trữ hình ảnh dưới dạng nén.
• 4 byte tiếp theo: mô tả kích cỡ pixel
• 2 byte tiếp theo: cho biết số pixel trên một dòng ảnh
• 2 byte cuối: cho biết số dòng ảnh trong ảnh.
Định dạng ảnh PCX là một trong những định dạng ảnh cổ điển nhất. Định dạng
này sử dụng phương pháp mã loại dài RLE (Run-Length-Encoded) để nén dữ liệu ảnh.
Quá trình nén và giải nén được thực hiện trên từng dòng ảnh. Tệp PCX gồm 3 phần :
đầu tệp(header), dữ liệu ảnh (image data), và bảng màu mở rộng.
Định dạng ảnh TIFF được thiết kế để làm nhẹ bớt các vấn đề liên quan đến việc
mở rộng tệp ảnh cố định. Định dạng này cũng gồm 3 phần: IFH, IFD, DE.
Định dạng ảnh GIF (Graphics Interchange Format). Định dạng này được đưa ra
để khắc phục những vấn đề mà các định dạng ảnh khác gặp phải khi số màu trong ảnh
tăng lên. Định dạng tổng quát của ảnh GIF được cho trên hình vẽ 2.6
Hình 2.6 Định dạng tổng quát GIF của một hình ảnh.:
GIF note
GIF header
Global Palette
Header image (_10 byte)
Palette of image 1 (nếu có)
Data of image 1
‘’ Ký tự liên tiếp
………………………..
‘’ GIF terminator
CHƯƠNG 3: PHÂN TÍCH ẢNH
3.1 Khái niệm pixel và pixel lân cận
Pixel là phân tử nhỏ nhất cấu tạo nên hình ảnh. Mỗi pixel có một toạ độ ̣̣̣̣̣(x,y) và
màu xác định.
Hình 3.1 Pixel P và các lân cận của P
P1
̣(x-1, y-1)
P2
(x-1, y)
P3
(x-1, y+1)
P4
̣(x, y-1)
P
(x, y)
P5
(x, y+1)
P6
(x+1, y-1)
P7
(x+1, y)
P8
(x+1, y+1)
Một pixel p tại các toạ độ ̣(x, y) có ô pixel lân cận theo chiều dọc và chiều ngang,
và toạ độ tương ứng của các pixel này , như hình vẽ 3.1 là:
P2(x-1, y) P7(x+1, y)
P6(x+1, y-1) . P5(x, y+1)
Tập các pixel này gọi là lân cận của p và ký hiệu là N4(p). Mỗi pixel lân cận cách
(x, y) một đơn vị và nếu (x, y) ở mép của màn hình thì sẽ có một số pixel lân cận của p
nằm ở ngoài hình ảnh.
Ngoài 4 pixel lân cận của p theo chiều dọc và chiêu ngang, xung quanh p còn có
4 pixel chéo góc có các toạ độ tương ứng là:
P1(x-1, y-1) P3(x-1, y+1)
P6(x+1, y-1) P8(x+1, y+1)
Tập các pixel này được ký hiệu là NḌ(p).Bốn pixel này cùng với 4 pixel ở trên
tạo thành 8 pixel lân cận cuả p và được ký hiệu là N8 (p) .Tập hợp này cũng sẽ có một
số pixel ở bên ngoài hình ảnh nếu (x, y) nằm ở mép của hình ảnh.
3.2 Một số công cụ trợ giúp xử lý ảnh
3.2.1 Tích chập
Toán tử tích chập được định nghĩa như sau:
◊ Trường hợp liên tục:
g(x,y) = h(x,y) ⊗ f(x,y)
= h(x-x( ) ( )∫∫ ∞∞−∞∞− −− ''','',' dydxyxfyyxxh `,y-y`) f(x`,y`) dx` dy` (3.1)
◊ Trường hợp rời rạc:
y(m,n) = h(m,n) ⊗ x(m,n) = (3.2) ( ) (∑∑ ∞
∞−
∞
∞−
−− ','',' nmxnnmmh )
n’ n’ Xoay180o
x (m’, n’) C
h (m’, n’) A m h(m-m’, n-n’)
B C m’ n A m’
a) Đáp ứng xung b) Tín hiệu ra ở vị trí (m,n)
Hình 3.2 Một biểu diễn của toán tử tích chập
Ví dụ:
Cho các ma trận:
+ Ma trận tín hiệu :
⎥⎥
⎥
⎦
⎤
⎢⎢
⎢
⎣
⎡
352
141
+ Ma trận đáp ứng xung:
⎥⎥
⎥
⎦
⎤
⎢⎢
⎢
⎣
⎡
− 11
11
Ma trận tích chập của x và h là một ma trận 4x3. Nói chung chập của hai ma trận số
(M1xN1) và (M2xN2) là một ma trận cỡ (M1+M2, N1+N2 -1). Quá trình nhân chập của h và x
được minh hoạ trong hình 3.3 sau:
1 4 1 n n
2 5 3 1 1 -1 1
1 4 1 1
a) x(m,n) b) h(m,n) c) h(-m,-n)
-1 1 -2 5 1 5 5 1
1 1 0 0 3 10 5 2
2 3 -2 -3
d) h(1-m,-n) e) y(1,0) = -2+3=1 f) y(m,n)
Hình 3.3 . Ví dụ về toán tử nhân chập
Tích chập là một khái niệm rất quan trọng trong xử lý ảnh, đặc biệt là tính chất
của nó có liên quan đến biến đổi Fourier: Biến đổi Fourier của một tích chập bằng tích
đơn giản các biến đổi Fourier của tín hiệu đó:
F[H (x,y) ⊗ I(x,y)] = F [H (x,y) , F[I(x,y)] ̣(3.3)
Trong kỹ thuật H(x,y) được gọi là nhân chập hay nhân cuộn hay mặt nạ : I(x,y) gọi
là ảnh đối tượng.
Thuật toán tổng quát để tính nhân chập dùng cho mọi trường hợp. Để sử dụng thuật
toán chỉ cần thay đổi hai thông số:ma trận biểu diễn ảnh số cần xử lý và ma trận
biểu diễn nhân chập.
Nhân chập (ImageIn, ImageOut: ảnh H: nhân chập N: kích thước ảnh W; kích
thước nhân chập)
{ Vào: ImageIn
Nhân chập
Ra: ImageOut}
Begin
For i = 1 to N do
For i = 1 to N do
Begin
Sum = 0
Le:= (w+1) div2:
For k:=1 to w do
For k:=1 to w do
Begin
Col:=1-k+Lc;
R ow:=j+l+Lc
If(Col 0 and (Col<=N) then
If(Row 0 and (Row <=N) then
Sum:=Sum+ImageIn [Col, Row ] * H [k,l]
End;
ImageOut [i,j] = Sum
End;
End;
3.2.2 Kỹ thuật lọc số
Chất lượng hình ảnh kém do rất nhiều nguyên nhân như do nhiễm điện tử của máy
thu hay chất lượng bộ số hóa kém. Nhiễu ảnh số được xem như là sự dịch chuyển
nhanh của tín hiệu thu nhận trên một khoảng cách ngắn. Về mặt tần số, nhiễu ứng
với các thành phần tần số cao trong ảnh. Như vậy để xử lý nhiễu ta có thể lọc các
thành phần tần số cao. Việc lọc dựa vào tính dư thừa thông tin không gian ; các
pixel lân cận có thể có cùng hoặc gần cùng một số đặc tính. Kỹ thuật lọc này dùng
một mặt nạ và di chuyển khắp ảnh gốc. Tùy theo cách tổ hợp điểm đang xét với các
điểm lân cận mà ta có kỹ thuật lọc tuyến tính hay kỹ thuật lọc phi tuyến. Điểm ảnh
chịu tác động của biến đổi là điểm ở tâm của mặt nạ. Các kỹ thuật lọc này được
trình bày kỹ trong phần làm trơn ảnh.
3.2.3 Biến đổi Fourier
3.2.3.1 Khái niệm và công thức
Biến đổi Fourier cho một tín hiệu có thể biểu diễn như sau:
FT
x(t) X(f)
Miền thời gian Miền tần số
Dạng phức
X(n ) X(z)
Biến đổi Fourier thuận cho tín hiệu một chiều gồm một cặp biến đổi
-Biến đổi Fourier thuận: chuyển sự biểu diễn từ không gian thực sang không gian tần
số (phổ và pha) . Các thành phần tần số n ày đ ược gọi là các biểu diễn trong không
gian Fourier của tín hiệu.
- Biến đổi Fourier ngược: Chuyển đổi sự biểu diễn của đối tượng từ không gian
Fourier sang không gian thực.
a)Không gian một chiều.
Cho một hàm f(x) liên tục. Biến đổi Fourier của f(x), ký hiệu F(u) , u biểu diễn
tần số không gian , được định ngh ĩa l à:
F(u) = ƒ(x)e∫∞∞− -2jπ ux dx (3.4)
Trong đ ó:
F(x) : biểu diễn biên độ tín hiệu
e-2jπ ux: biểu diễn pha.
Biến đổi Fourier ngược của F(u) cho f(x) đ ược định nghĩa như sau:
ƒ(x) = F(u)e∫∞∞− ∫∞∞− -2jπ ux du (3.5)
b) Không gian hai chiều
Cho f(x,y) là hàm biểu diễn ảnh liên tục trong không gian hai chiều, cặp biến đổi
Fourier được định nghĩa như sau:
-Biến đổi Fourier thuận:
F(u,v) = f(x,y) e∫ ∫∞∞− ∞∞− -2jπ (ux+vy) dxdy (3.6)
U,v biểu diễn tần số không gian
-Biến đổi Fourier ngược
f(u,v) = F(x,y) e∫ ∫∞∞− ∞∞− -2jπ (ux+vy) dxdv (3.6)
3.2.3.2 Biến đôỉ Fourier rời rạc_DFT
Biến đổi DFT được phát triển dựa trên bi ến đổi Fourier cho ảnh số. Ở đây, tích
phân được thay bằng tổng. Biến đổi Fourier DFT t ính các giá trị của biến đ ổi
Fourier cho một t ập các giá trị trong không gian tần số được cách đều.
a) DFT cho tín hiệu một chiều
Với tín hiệu một chiều, người ta biến đổi bởi một chuỗi trực giao các hàm cơ sở.
Với các hàm liên tục, khai triển chuỗi trực giao sẽ cung cấp chuỗi các hệ số ùng
trong nhiều quá trình khác nhau hay trong phân tích hàm. Khai triển Fourier rời rạc
DFT cho một dãy {u(n), n=0,1,....N} được định nghĩa bởi:
V(k) = u(v) W∑−
=
1
0
N
n
kn
N v ới k=0, 1,....., N-1 (3.7)
với WN = e-j2π/N
và biến đổi ngược
u(n) = ∑−
=
1
0
1 N
k
v
N
(k)WN-kn với k=0,1,….N-1 (3.8)
Thực tế trong xử lý ảnh người ta hay dung DFT đơn vị:
v(k)= ∑−
=
1
0
1 N
nN
u(k)WNkn với k=0,1,….N-1 (3.9)
u(n)= ∑−
=
1
0
1 N
nN
u(k)WN-kn với k=0,1,….N-1 (3.10)
Các DFT và DFT đơn vị có tính đối xứng. Hơn nữa khai triển DFT và DFT đơn vị
của một chuỗi và biến đổi ngược lại của nó có tính chu kỳ và chu kỳ N.
b) DFT cho tín hiệu hai chiều (ảnh số)
DFT hai chiều của một ảnh MxN:{u(m,n)} là một biến đổi tách được và được định
nghĩa:
V(k,l) = u(m,n) W∑∑−
=
−
=
1
0
1
0
N
m
N
n
N
km WNln với 0 ≤1,k≤ N-1 (3.11)
Và biến đổi ngược:
V(k,l) = ∑∑−
=
−
=
1
0
1
0
1 N
m
N
nN
v(k,l) WN-km WN-ln với 0 ≤m,n≤ N-1 (3.12)
Cặp DFT đơn vị hai chiều được định nghĩa:
V(k,l) = ∑∑−
=
−
=
1
0
1
0
1 N
m
N
nN
u(m,n) WNkm WNln với 0 ≤1,k≤ N-1
(3.13)
U(m,n) = ∑∑−
=
−
=
1
0
1
0
1 N
m
N
nN
v(k,l) WN-km WN-ln với 0 ≤m,n≤ N-1
(3.14)
Viết lại các công thức (3.13) và (3.14) ta có:
V(k,l) = ∑∑−
=
1
0 0
1 N
mN
u(m,n)WN(km +ln) với 0 ≤m,n≤ N-1 (3.15)
u(m,n) = ∑∑−
=
−
=
1
0
1
0
1 N
m
N
lN
v(k,l)WN-(km +ln) Với 0 ≤m,n≤ N-1 (3.16)
Ở đây, WN(km +ln) là ma trận ảnh cơ sở.
Ta có: WN-(km +ln) =e-j2π(km+ln)/N =cos [2π(km+ln)/N] -jsin [2π(km+ln)/N]
Như vậy các hàm cơ sở trong ma trận cơ sở của biến đổi Fourier là các hàm cosine
và hàm sine. Chỉ biến đổi Fourier biểu diễn ảnh trong không gian mới theo các hàm
sine và cosine.
3.2.3.3. Định lý chập cuộn hai chiều.
DFT của cuộn chập hai chiều của hai ma trận bằng tích DFT của chúng:
u(m,n) = h(m-m’, n-n’)∑∑−
=
−
=
1
0
1
0
N
m
N
l
c u1(m’,n’) với 0 ≤m,n≤ N-1 (3.17)
với h(m,n), u1(m,n) là ma trận NxN và h(m,n)c =h(m mod N, n mod N)
3.2.3.4. Thuật toán biến đổi Fourier nhanh.
- Trường hợp một chiều
Từ công thức v(k) = ∑−
=
1
0
1 N
nN
u(n) WNkn với k= 0,1,…., N-1 ta thấy với mỗi giá
trị k ta cần N phép tính nhân và N phép cộng. Nên để tính N giá trị của v(k) ta phải
tính N2 phép tính. Để khắc phục điều này người ta sử dụng thuật toán biến đổi Fourier
nhanh FFT chỉ cần N.log2N phép tính.
Thuật toán Fourier nhanh được tóm tắt như sau:
-Giả sử N=2n
-Giả sử WN là nghiệm thứ N của đơn vị WN =e-2jπ/N và M=N/2 ta có:
v(k) = ∑−
=
12
02
1 M
nM
u(n)W2Mnk (3.18)
- Khai triển công thức trên ta được
v(k) = ( ∑−
=
1
0
1 M
nM
u(2n) W2M2nk + M
1 ∑ u(2n+1) W2M(2n+1)k)/2 (3.19)
vì W2M2nk =W2Mnk, do đó:
v(k) =
2
1 [uchẵn (n)+ulẻ (n)] (3.20)
v(k) với k=[0,M-1] là một DFT trên M =N/2. Thực chất của thuật toán FFT là dung
nguyên tắc chia đôi và tính chu kỳ để tính DFT. Với k=[0,M-1] dung công thức (3.19).
Với k=[M,M-1] dung phép trừ trong công thức (3.19) có thể dung thuật toán này để
tính DFT ngược.
-Trường hợp hai chiều:
Do DFT hai chiều là tách được nên từ công thức (3.14) ta có:
V(k,l) = ∑−
=
1
0
1 N
mN
WNkn u(m,n) W∑−
=
1
0
N
n
N
ln (3.21)
Từ công thức (3.21) , cách tính DFT hai chiều như sau:
-Tính DFT 1 chiều với mỗi giá trị của X (theo cột)
-Tính DFT 1 chiều theo hướng ngược lại (theo hàng) với giá trị thu được ở trên.
3.3 Tiền xử lý
Có hai phương pháp cơ bản được sử dụng trong tiền xử lý ảnh. Phương pháp thứ
nhất dựa vào các kỹ thuật tiền xử lý trong miền không gian và phương pháp thứ
hai sử dụng các khái niệm trong miền tần số thông qua biến đổi Fourier.
3.3.1 Phương pháp tiền xử lý trong miền không gian.
Thuật ngữ miền không gian ở đây muốn nói đến số lượng pixel tạo nên một hình
ảnh. Các phương pháp tiền xử lý trong miền không gian là các thủ tục tác động trực
tiếp lên các pixel tạo lên hình ảnh đó. Các hàm tiền xử lý trong miền không gian có
thể được viết như sau:
g(x,y) =h[f(x.y)] (3.22)
Ở đây f(x,y) là hàm điểm ảnh chưa được xử lý.
g(x,y) là hàm điểm ảnh đã được xử lý.
h là toán tử áp lên f. Dạng đơn giản nhất của h là lân cận có kúch tghước1x1, khi
đó g chỉ phụ thuộc vào giá trị của f tại (x,y) và h trở thành hàn ánh xạ cường độ
sáng điểm ảnh.
Một trong những kỹ thuật được sử dụng rộng rãi nhất là sử dụng mặt nạ nhân
chập. Trên hình 3.4 minh hoạ một mặt nạ là một mảng 2 chiều có kích thước 3x3,
các hệ số của mặt nạ được chọn để phát hiện một thuộc tính cho trước trong một
hình ảnh.
Hình 3.4. Một lân cận kích thước 3x3 quanh điểm (x,y)
y
(x,y)
x
•
Để hiểu rõ về mặt nạ nhân chập ta xét một ví dụ cụ thể sau. Giả sử chúng ta có
một hình ảnh có cường độ không đổi chứa một số điểm ảnh tách rời nhau, cường độ
của các điểm ảnh này khác với nền. Các điểm ảnh này có thể được phát hiện bằng một
mặt nạ nhân chập có kích thước 3x3 với các hệ số đã chọn trên hình 3.5
Hình 3.5. Mặt nạ dung để xác định các điểm ảnh
Tách biệt trên một nền không đổi
-1 -1 -1
-1 8 -1
-1 -1 -1
Thủ tục phát hiện điểm ảnh như sau: Cho tâm của mặt nạ chuyển động xung quanh
hình ảnh. Tại mỗi vị trí pixel trong hình ảnh, ta nhân mỗi pixel nằm trong vùng mặt
nạ tương ứng ; Nghĩa là pixel ở tâm của mặt nạ được nhân với 8, còn 8 pixel lân
cận được nhân với –1. Sau đó cộng kết quả của 9 phép nhân này lại. Nếu tất cả các
pixel trong mặt nạ có cùng giá trị (tức nền không đổi), thì tổng sẽ bằng 0. Ngược
lại nếu tâm của mặt nạ trùng với một trong các điểm ảnh cần xác định, thì tổng sẽ
khác 0. Nếu điểm ảnh cần xác định không nằm đúng tâm của mặt nạ, tổng cũng sẽ
khác 0, nhưng giá trị biên độ của đáp ứng sẽ yếu hơn. Những đáp ứng yếu hơn này
có thể loại bỏ bằng cách so sánh tổng với một ngưỡng.
Xét một mặt nạ có các hệ số w1, w2,….w9 và 8 điểm ảnh lân cận của điểm ảnh
(x,y) như hình 3.6. Ta có thể khái quát hoá một hàm tiền xử lý cho một mặt nạ 3x3
như sau:
h[f(x,y)]= w1f(x-1, y-1) +w3f(x-1, y+1) +w4f(x, y-1) +w5f(x,y)+w6f(x,y+1)
+w7f(x+1,y-1)+w8f(x+1,y) +w9f(x+1, y+1) (3.23)
Hình 3.6. Mặt nạ tổng quát kích thước
3x3 trình bày các hệ số và vị trí pixel hình
ảnh tương ứng.
W1
(x-1,y-1)
W2
(x-1,y)
W3
(x-1,y+1)
W4
(x, y-1)
W5
(x,y)
W6
(x,y+1)
W7
(x+1, y-1)
W8
(x+1, y)
W9
(x+1,
y+1)
3.3.2 Phương pháp tiền xử lý trong miền tần số.
Thuật ngữ miền tần số ở đây có nghĩa là tổng số pixel phức được tạo ra từ việc lấy
biến đổi Fourier hình ảnh . Khái niệm “tần số” thường được sử dụng trong giải
thích biến đổi Fourier và suy ra từ bản chất của biến đổi Fourier là tổ hợp của các
hàm sin phức. Phương pháp naỳ đóng vai trò rất quan trọng trong lĩnh các vực như
phân tích chuyển động của một vật và miêu tả vật.
Xét các hàm rời rạc của một biến, f(x), x=0, 1, …., N-1. Biến đổi Fourier thuận của
hàm f(x) là:
F(u) = ∑−
=
1
0
1 N
xN
f(x)e-2jπux / N (3.24)
với u = 0, 1, 2,…..N-1. Trong phương trình này j=√-1 và u gọi là biến tần số. Biến đỏi
Fourier ngược cho lại f(x) được định nghĩa như sau:
f(x) = e( )∑−
=
1
0
N
u
uF 2jπux / N (3.25)
Nếu tính trực tiếp từ các phương trình (3.24) và (3.25) với u=x=0,1, 2, ...N-1 thì
phải thực hiện khoảng N2 phép cộng và phép nhân. Sử dụng thuật toán biến đổi
Fourier nhanh cho phép giảm đáng kể số lượng phép tính xuống còn N.log2 N phép
tính, ở đây N được giả sử là một số nguyên mũ 2.
Cặp biến đổi Fourier hai chiều của hình ảnh NxN được định nghĩa như sau:
F(u,v) =
N
1 ∑−
=
1
0
N
x
∑−
=
1
0
N
y
f(x,y)e-j2π (ux+vy)/N (3.26)
với u,v=0,1,2..., N-1 và
f(x,y) =
N
1 ∑−
=
1
0
N
u
∑−
=
1
0
N
v
F(u,v)ej2π (ux+vy)/N (3.27)
với x,y=0, 1, 2,...N-1.
Bằng cách coi biên của vật như mảng một chiều các điểm, sau đó tính biến đổi
Fourier các phần tử của mảng đó, từ các giá trị F(u) thu được có thể biết được dạng
biên của vật. Biến đổi Fourier một chiều cũng là một công cụ rất mạnh trong việc
phát hiện chuyển động của vật. Tuy vẫn còn hạn chế về mặt tính toán nhưng biến
đổi Fourier rời rạc có rất nhiều ứng dụng trong các lĩnh vực tái tạo ảnh, cải thiện
ảnh và khôi phục ảnh. Đối với biến đổi Fourier liên tục, hai chiều, việc tính toán có
thể đạt tới tốc độ ánh sáng nhờ sử dụng các thiết bị quang học .
3.4 Làm trơn ảnh.
3.4.1 Lấy trung bình các điểm ảnh lân cận- Lọc tuyến tính.
Lấy trung bình các điểm ảnh lân cận là một kỹ thuật miền không gian đơn giản để
làm trơn ảnh. Cho một hình ành f(x,y) , thủ tục sẽ tạo ra một hình ảnh đã làm trơn
g(x,y), cường độ tại mỗi điểm (x,y) của ảnh này có được bằng cách lấy trung
bình các giá trị cường độ các điểm ảnh của f nằm trong một lân cận xác trước định
của (x,y). Nói cách khác, ảnh đã được làm nhẵn có được bằng cách sử dụng
phương trình:
G(x,y) =
( )∑∈Smnp ,
1 f(n,m) (3.28)
với mọi x,y nằm trong f(x,y) , S là tập hợp tọa độ các điểm trong lân cận (x,y) gồm cả
(x,y) và P là tổng số điểm trong lân cận.
3.4.2. Phương pháp lọc điểm giữa (lọc trung vị)_ Lọc phi tuyến.
Một trong những khó khăn chủ yếu của phương pháp lấy trung bình các điểm ảnh
lân cận là nó làm mờ biên của hình ảnh và các chi tiết sắc nét khác. Sự mờ này có
thể làm giảm đáng kể nhờ việc sử dụng bộ lọc điểm giữa ở đây chúng ta sẽ thay
cường độ của mỗi điểm ảnh bằng độ lớn cường độ của điểm giữa trong một lân cận
xác định trước của điểm ảnh đó thay vì lấy trung bình các điểm ảnh.
Để thực hiện lọc điểm giữa trong một lân cận của một điểm ảnh, trước tiên phải sắp
xếp các giá trị của pixel và các lân cận của nó, xác định điểm giữa và gán giá trị
này cho pixel. Ví dụ: trong lân cận 3x3 điểm giữa là giá trị lớn nhất thứ 5, trong
lân cận 5x5 điểm giữa là giá trị lớn nhất thứ 13v.v…Khi trong lân cận có nhiều giá
trị giống nhau, ta nhóm các giá trị bằng nhau như :giả sử một lân cận 3x3 có các
giá trị (10,20,20,20,15,20,20,25,100). Các giá trị này được sắp xếp như
sau(10,15,20,20,20,20,25,100) và các điểm giữa của lân cận này là 20 Như vậy
thực chất của việc lọc điểm giữa là ép các điểm có cường độ khác biệt giống các
lân cận của nó hơn, tức làm loại bỏ các điểm nhọn cường độ xuất hiện trong các
mặt nạ lọc.
3.4.3 Trung bình hoá hình ảnh
Xét một hình ảnh nhiễu g(x,y) tạo ra do cộng nhiễu n(x,y) vào hình ảnh f()x,y tức
là:
G(x,y) = f(x,y) +n(x,y) (3.29)
ở đây giả sử nhiễu là không tương quan và có giá trị trung bình bằng 0. Mục tiêu của
phương pháp trung bình hoá là tạo ra một hình ảnh tốt hơn bằng cách cộng các hình
ảnh nhiễu cho trước gi(x,y), i=1,2,…K .
Nếu nhiễu thoả mãn các ràng buộc nêu trên, bài toán sẽ là đơn giản và hình ảnh
g(x,y) được tạo ra bằng cách lấy trung bình K hình ảnh nhiễu khác nhau.
g (x,y) =
K
1 ∑
=
K
i 1
g(x,y) (3.30)
do đó ta có:
E { g (x,y)} = f(x,y) (3.31)
Và :
σ
g
2 (x,y) =
K
1 σ
n
2 (x,y) (3.32)
ở đây E { g (x,y)} là giá trị mong đợi của g , σ
g
2 (x,y), và σ
n
2 (x,y) là các biến của g và
n tại toạ độ (x,y). Độ lệch chuẩn tại bất kỳ điểm nào trong hình ảnh trung bình được
cho bởi:
σ
g
(x,y) =
K
1 σ
n
(x,y) (3.33)
3.4.4 Làm trơn hình ảnh nhị phân
Trong ảnh nhị phân điểm đen được quy định là 1 và điểm trắng được quy định là 0.
Vì hình ảnh nhị phân có hai giá trị nhiễu trong trường hợp này tạo ra các hiệu ứng
như biên mấp mô, các lỗ nhỏ, thiếu góc và các điểm bị tách ra.
Ý tưởng cơ bản là kiểm tra một hàm BOOL đối với lân cận tâm tại pixel p và gán p
là 1 hoặc 0 phụ thuộc vào sự sắp xếp về mặt không gian và giá trị của các pixel lân
cận. Do hạn chế về thời gian xử lý nên việc phân tích chỉ giới hạn trong 8 lân cận
của p, lân cận này cho một mặt nạ kích thước 3x3 như hình 3.7.
Hình 3.7. Các lân cận của p sử dụng để làm nhẵn ảnh
a b c
d p e
f g h
nhị phân điểm tối là một và điểm sang là 0
Làm nhẵn ảnh nhị phân được tiến hành theo các bước sau:
1. bổ xung các lỗ nhỏ
2. bổ xung các khấc trong các cạnh
3. Loại bỏ các điểm 1 biệt lập
4. loại bỏ các biếu nhỏ dọc các cạnh
5. bổ xung các góc thiếu
Hai quá trình làm nhẵn đầu tiên được thực hiện bằng cách dung biểu thức Bool sau:
Bi =p+b.g.(d+e) +d.e(b+g) (3.34)
ở đây “.” Và “+” lần lượt là ký hiệu của AND và OR. Theo qui ước, pixel trong mặt
nạ được gán là 1 và pixel trắng được gán là 0. Do đó nếu Bi =1, p được gán là 1, ngược
lại p được gán là 0. Phương trình (3.34) được áp dụng đồng thời cho tất cả các pixel,
trong đó giá trị tiếp theo của mỗi vị trí pixel được xác định trước khi các pixel khác đã
bị thay đổi.
Bước 3,4 được thực hiện tương tự bằng cách đánh giá biểu thức Bool sau:
B2 =p{(a+b+c). (e+g+h)+(b+c+e).(d+f+g)} (3.35)
đồng thời cho tất cả các pixel . Và p=1 nếu B2 =0.
Các điểm thiếu ở góc phải trên được bổ xung bằng biểu thức sau:
B= p (d.f.g) . )( hecba ++++ +p (3.36)
ở đây dấu gạch trên cho biết phần bù logic. Tương tự, các điểm thiếu góc phải dưới
trái trên, và trái dưới được bố sung bằng các biểu thức:
B= p (a.b.d) . )( hecgf ++++ +p (3.37)
B= p (e.g.h) . )( fdcab ++++ +p (3.38)
Và
B= p (b.c.e) . )( fdhag ++++ +p (3.39)
Bốn biểu thức này thực hiện bước 5 của thủ tục làm trơn ảnh:
Ví dụ
1
1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1
1 1
1
1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1
1
1
3.9(a) Hình ảnh gốc 3.9(b) Ảnh sau khi áp dụng B1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
3.9 (c) Ảnh sau khi áp dụng B2 3.9 (d) Ảnh cuối cùng sau bước 5
x
1
1 1 1 1 1 1 x
x 1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1
x x
3.5 Phát hiện biên
Phát hiện biên đóng vai trò quan trọng trong nhìn thấy máy, được coi là
bước xử lý khởi đầu cho rất nhiều bài toán phát hiện vật.
3.5.1 Nguyên tắc.
Về cơ bản ý tưởng phát hiện biên của vật là tính đạo hàm cục bộ được minh
hoạ trên hình 1.10.
ảnh
Tiết diện
của đường
nằm ngang
Đạo hàm
bậc nhất
Đạo hàm
bậc hai
( a ) ( b )
Hình 3.10. Quá trình phát hiện biên bằng phương pháp lấy đạo hàm
a) Vật sang trên nền đen
b) Vật sang trên nền sang
Toán tử độ dốc: Độ dốc của một hình ảnh f(x,y) tại vị trí (x,y) được định nghĩa
như vectơ hai chiều :
G{f(x,y)} = = ⎥⎦
⎤⎢⎣
⎡
Gy
Gx
⎥⎥
⎥⎥
⎥⎥
⎥
⎦
⎤
⎢⎢
⎢⎢
⎢⎢
⎢
⎣
⎡
y
f
x
f
δ
δ
δ
δ (3.40)
G cho biết hướng tốc độ thay đổi cực đại của f tại vị trí (x,y). Tuy nhiên, trong phát
hiện biên chỉ quan tâm đến giá trị biên độ của véctơ và được gọi là độ dốc và được
ký hiệu là :
G[f(x,y)], ở đây:
G[f(x,y)] = [Gx2 +Gy2]⅟2 = ⎢⎣
⎡ ⎟⎠
⎞⎜⎝
⎛
x
f
δ
δ ⎥⎦
⎤
⎟⎟⎠
⎞
⎜⎜⎝
⎛
y
f
δ
δ (3.41)
Lấy xấp xỉ, ta có:
G[f(x,y)] = |Gx| + |Gy| (3.42)
Việc lấy xấp xỉ dễ thực hiện với phần cứng:
Từ phương trình (3.41) việc tính toán độ dốc dựa vào các đạo hàm bậc nhất
xf δδ và yf δδ . Có một số cách để tính các đạo hàm bậc nhất này trong hình ảnh số.
Một trong các phương pháp đó là sử dụng các vi phân bậc nhất giữa các pixel liền kề
nhau, nghiã là:
Gx = x
f
δ
δ = f(x,y) –f(x-1, y) (3.43)
và:
Gx = x
f
δ
δ = f(x,y) –f(x,y-1) (3.44)
Đối với lân cận kích thước 3x3 tâm tại (x,y), Gx, Gy được tính như sau:
Gx= x
f
δ
δ =
( ) ( ) ( )[ ] ( ) ( ) ( )[ ]
( ) ( )cbaihg
yxfyxfyxfyxfyxfyxf
++−++=
−++−+−−−+++++−+
22
1,1,121,11,1,121,1
(3.45)
Và : Gx= x
f
δ
δ = ( ) ( ) ( )[ ]1,11,21,1 ++++++− yxfyxfyxf
- ( ) ( ) ( )1,11,21,1 −++−+−− yxfyxfyxf
(3.46) ( ) ( gdaec ++−++= 212 )
ở đây các lân cận của (x,y) được biểu diễn bởi các chữ cái từ a đến i. Một lân cận 3x3
cảu (x,y) dung các chữ cái này được trình bày trên hình 3.11a
-1 0 1
-2 0 2
-1 0 1
-1 -2 -1
0 0 0
1 2 1
a b c
d (x,y) e
g h i
3.11(a) Lân cận 3x3 của (x,y) 3.11(b) Mặt nạ để tính Gx 3.11 (c) Mặt nạ để tính
Gy
Việc tính toán độ dốc trên vùng 3x3 có ưu điểm hơn so với dung các phương
trình (3.39) và (3.40) là tăng giá trị trung bình, do đó làm giảm độ dốc giảm nhạy đối
với nhiễu. Dựa {vào phương pháp mặt nạ ta có thể tính Gx theo mặt nạ hình 3.11b và
Gy được tính theo mặt nạ hình 3.11 c. Hai mặt nạ này thường được gọi là các toán tử
Sobel. Các đáp ứng cảu hai mặt nạ này tại điểm (x,y bất kỳ được kết hợp nhờ hai
phương trình (3.37 và (3.38) để có được sự xấp xỉ độ dốc tại điểm đó. Bằng cách di
chuyển các mặt nạ này khắp hình ảnh f(x,y sẽ thu được độ dốc của tất cả các điểm
trong ảnh.
Có nhiều phương pháp tạo ra ảnh lối ra g(x,y ) dựa vào tính toán độ dốc. Phương pháp
đơn giản nhất cho giá trị g tại (x,y) bằng độ dốc của ảnh lối vào tại điểm đó nghĩa là:
G(x,y) = G ( )[ ]yxf , (3.47)
Phương pháp khác tạo ảnh nhị phân bằng cách dùng quan hệ sau:
G(x,y) = (3.48)
⎪⎩
⎪⎨
⎧
0
1
ở đây T là ngưỡng không âm. Trong trường hợp này chỉ các pixel mép mà độ dốc của
chúng lớn hơn T mới được coi là quan trọng . Do đó sử dụng phương trình (3.44) có
thể được xem như là một thủ tục lấy ra những pixel được đặc trưng bởi sự chuyển
dịch đáng kể về cường độ sáng.
Toán tử Laplacian.: Laplacian là một toán tử đạo hàm bậc hai được định nghĩa như
sau:
L = ([ ]yxf , )
2
2
x
f
δ
δ +
2
2
y
f
δ
δ (3.49)
Với các ảnh số, Laplacian được định nghĩa như sau:
L = ([ ]yxf , ) ( ) ( ) ( ) ( )[ ]1,1,,1,1 −+++−++ yxfyxfyxfyxf -4f (x,y) (3.46)
Laplician sẽ bằng 0 trong các vùng không đổi và trên phần dốc của mép. Thực hiện
phương trình (3.46) có thể dựa vào mặt nạ như trong hình 3.10
Hình 3.12. Mặt nạ để tính Laplician
Laplician phản ứng với những sự dịch chuyển về cường độ, toán tử này ít khi được sử
dụng một mình để phát hiện biên. Vì là đạo hàm bậc hai nên nó không nhạy với nhiễu.
Do đó toán tử này thường được coi như bộ phát hiện việc thiết lập pixel cho trước là ở
trên mặt nạ đen hay trắng của mép.
0 1 0
1 4 1
0 1 0
3.6 Lập ngưỡng
Phân ngưỡng là một trong những kỹ thuật chủ yếu được sử dụng tỷong các hệ
thống nhìn trong công nghiệp để phát hiện vật, nhất là trong các ứng dụng đòi hỏi năng
suất dữ liệu cao.
Giả sử biểu đồ cường độ được trình bày trong hình 3.13a tương ứng với một
hình ảnh f(x,y) tạo thành các vật sáng trên nền đen, các pixel nền và vật này có các
cường độ được nhóm thành hai mode trội chủ yếu. Cách để phân chia các vật thành hai
mode là chọn một ngưỡng T và so sánh cường độ của vật với ngưỡng đó. Do đó, một
điểm (x,y) bất kỳ có f(x,y) >T được gọi là một điểm của vật: ngược lại nó là một điểm
của nền. Trong hợp tổng quát hơn được trình bày trong hình 3.13b. Trong trường hợp
này biểu đồ hình ảnh được đặc trưng bởi 3 mode trội (ví dụ hai vật sang trên một nền
tối). Ở đây, ta cũng dung phương pháp cơ bản trên, phân các điểm có T1 < f(x,y) [ 2T <
T1 vào một lớp đối tượng, các điểm có f(x,y) > T2 cho một lớp đối tượng khác và
thuộc nền nếu f(x,y) [ . Loại ngưỡng đa mức này nói chung là độ tin cậy kém hơn 1T
loại ngưỡng đơn mức do sự khó khăn trong việc thiết lập ngưỡng đa mức để tách hiệu
quả các vùng mong muốn, nhất là khi số mode biểu đồ tương ứng là lớn.
T
T1 T2
Hình 3.13. Lược đồ cường độ (a). Một ngưỡng (b) Nhiều ngưỡng
Dựa vào các khái niệm ở trên ta có thể xem lập ngưỡng như là một phép toán như
sau:
T= T ( ) ( )[ ]yxfyxpyx ,,,,
ở đây f(x,y) là cường độ của điểm (x,y)
p(x,y) biểu thị một vài thuộc tính cục bộ của điểm này. Ví dụ như cường độ trung
bình của lân cận có tâm tại (x,y)
Một ảnh g(x,y) đã lấy ngưỡng được định nghĩa như sau:
1 if f(x,y) > T (3.50)
G(x,y) =
0 if f(x,y) T ≤
Do đó bằng cách kiểm tra g(x,y) ta thấy các pixel có giá trị 1 (hoặc mức cường độ
quy ước khác) tương ứng với vật, còn pixel có giá trị không ứng với nền.
Khi T chỉ phụ thuộc vào f(x,y), ngưỡng được gọi là toàn cục hay ngưỡng đơn (hình
3.10a). Nếu T phụ thuộc cả f(x,y) và p(x,y), ngưỡng cục bộ hay đa ngưỡng (hình
3.10b). Ngoài ra nếu T phụ thuộc vào các tọa độ x và y, nó được gọi là ngưỡng .
PHẦN 2:PHẦN THỰC NGHIỆM
Hình P2.1: Mô hình thực nghiệm : camera và mạch đk motơ bước.
• TÓM TẮT MÔ HÌNH SẢN PHẨM WEBCAM TỰ ĐỘNG THEO
DÕI ĐỐI TƯỢNG DI CHUYỂN:
Như là một phần của đề tài, tôi đã cho thực hành cho camera theo dõi vật dựa
trên phần cứng đơn giản.Với mục tiêu minh hoạ cho đề tài nên các phần cứng và
chương trình đã được đơn giản hoá …như là camera chỉ bám vật theo hai chiều trái và
phải, chương trình cũng chỉ cho phép điều khiển camera bám theo một vật chuyển
động duy nhất.Tuy nhiên ở phần lý thuyết sau đây tôi sẽ cố gắng trình bày những gì tốt
nhất của đề tài thực sự có thể làm được.Nền tảng cho chương trình ở đây là thư viện
mã mở của Microsoft: AVICap và được triển khai trên nền của ngôn ngữ lập trình
Visual C++ vesion 6.0.
webcam
USB camera
LPT port
Môtơ
Bước
PC
Hình P2.2: Sơ đồ khối mô hình thưc nghiệm
CHƯƠNG 1: NGÔN NGỮ LẬP TRÌNH
1.1 Giới thiệu
Hiện nay có rất nhiều ngôn ngữ lập trình mới và mạnh. Các ngôn ngữ lập trình trên
Window vừa có khả năng như các ngôn ngữ chạy trong DOS vừa có khả năng
cung cấp một giao diện trực quan giúp người sử dụng giao tiếp với ứng dụng một
cách
dễ dàng. Ngôn ngữ lập trình Visual C++ là một trong những ngôn ngữ như vậy. Trong
luận văn sẽ sử dụng ngôn ngữ này.
1.2 Một số hàm và thủ tục xử lý ảnh
1.2.1 Tạo một số cửa sổ hiện ảnh.
Để tạo một cửa sổ ta dùng hàm “capCreateCaptureWindow”
Ví dụ:
HWndc = capCreateCaptureWindow (
(LPSTR) “My Capture Window”, // tên cửa sổ
WS_CHILD | WS_VISIBLE, // tên cửa sổ
0, 0, 160, 120, // vị trí và kích thước của cửa sổ
(HWND) hwndParent,
(int) nID/ * child ID */);
1.2.2 Kết nối với thiết bị thu ảnh.
Để kết nối và dừng kết nối cửa sổ hiện ảnh với thiết bị thu ảnh dùng macro
“capDriverDisconnect”.
Ví dụ:
fOK = SendMessage (hWndc, WM_CAP_DRIVER_CONNECT, 0, 0L);
CapDriverDisconnect(hWndC);
1.2.3. Thiết lập trạng thái của cửa sổ hiện ảnh.
Để thiết lập kích thước của cửa sổ hiện ảnh cho tất cả các chiều hình ảnh nhận
được từ macro “capGetStatus” trong cấu trúc CAPSTATUS ta sử dụng hàm
“SetWindowPos”.
Ví dụ:
CAPSTATUS CapStatus;
CapGetStatus (hWndC, &CapStatus, sizeof (CAPSTATUS) );
SetWindowPos (hWndC, NULL, 0, 0, CapStatus.uiImageWidth,
CapStatus.uiImageHeight, SWP_NOZORDER |SWP_NOMOVE);
1.2.4. Hiển thị các hộp thoại để thiết lập các thông số của hình ảnh.
Mỗi cửa sổ hiện ảnh có thể cung cấp 3 hộp thoại khác nhau dùng để điều khiển
các khía cạnh của quá trình số hóa hình ảnh và hiện ảnh. Trước khi hiển thị mỗi hộp
thoại cần gọi macro “capDriverGetCaps” và kiểm tra cấu trúc CAPDRIVERCAPS
khai báo xem cửa sổ hiện ảnh có hiện thị hộp thoại hay không.
Ví dụ:
CAPDRIVERCAPS CapDriverCaps;
CapDriverGetCaps (hWndC, & CapDrvCaps, sizeof (CAPDRIVERCAPS) );
// hiện thị hộp thoại nguồn hình ảnh.
If (CapDriverCaps.fHasDlgVideoSource)
CapĐlgVideoSource (hWndC);
// hiện thị hộp thoại khuôn dạng hình ảnh.
If (CapDriverCaps.fHasDlgVideoFormat)
{
CapĐlgVideoFormat (hWndC);
// Có các kích thước hình ảnh mới không?
CapGetStatus (hWndC, &CapStatus, sizeof (CAPSTATUS));
// nếu có báo cho cửa sổ tra về sự thay đổi kích thước.
}
// hiển thị hộp thoại hiển thị hình ảnh.
If (CapDriverCaps.fHasDlgVideoDisplay)
CapDgVideoDisplay (hWndC);
1.2.5. Lấy và thiết lập khuôn dạng hình ảnh.
Cấu trúc BITMAPINFO có chiều dài thay đổi để cung cấp các khuôn dạng dữ
liệu nén chuẩn. Vì chiều dài của cấu trúc là thay đổi, nên trong các ứng dụng luôn luôn
cần phải xác định kích cỡ và cấp phát bộ nhớ cho cấu trúc trước khi tìm kiếm khuôn
dạng hình ảnh. Marco “capGetVideoFormatSize” để xác định kích cỡ bộ đệm và hàm
“capGetVideoFormat” để xác định khuôn dạng hình ảnh hiện tại .
Ví dụ:
LPBITMAPINFO lpbi;
DWORD dwSize;
DwSize =capGetVideoFormatSize (hwndC);
lpbi= GlobalAllocPtr (GHND, dwSize);
capGetVideoFormat (hwndC, lpbi, dwSize);
Các ứng dụng có sử dụng marco “capSetVideoFormat” (hoặc thông báo WM
CAP SET VIDEOFORMAT) để gửi cấu trúc tiêu đề BITMAPINFO tới các cửa sổ bắt
ảnh. Vì các khuôn dạng hình ảnh ứng với thiết bị riêng nên trong ứng dụng cần kiểm
tra giá trị trả về để xác định khuôn dạng có được chấp nhận hay không.
1.2.6. Duyệt trước hình ảnh
Để thiết lập tốc độ hiển thị khung cho mode duyệt trước ta sử dụng macro
“capPreviewRate” và sử dụng macro “capPreview” để thay thế cửa sổ hiện ảnh
trong mode duyệt trước.
Ví dụ:
CapPreviewRate (hWndC, 66); // tốc độ hiển thị tính bằng ms
CapPreview (hWndC, TRUE); // bắt đầu duyệt
// Duyệt
capPreview (hWndC, FALSE); // Ngừng duyệt
1.2.7. Thay đổi thiết lập cho hình ảnh hiện.
Để thay đổi tốc độ hiện hình ảnh từ giá trị mặc định ta sử dụng các macro
“capPreviewGetSetup” và “capCaptureSetSetup”
Ví dụ:
CAPTUREPARMS CaptureParms;
Float FramesPerSec = 10,0;
CapCaptureGetSetup (hwndC, &CaptureParms, sizeof (CAPTUREPARMS));
CaptureParms.dwRequestMicroSecPerDFrame = (DWORD) (1.0e6/ FramesPerSec);
CapCaptureSetup (hWndC, & CaptureParms, sizeof (CAPTUREPARMS));
1.2.8. Thêm các hàm Callback cho một ứng dụng.
Một ứng dụng có thể đăng ký hàm gọi lại với cửa sổ hiện ảnh để nó thông báo ứng
dụng trong các tình huống sau:
• Thay đổi trạng thái
• Có lỗi xảy ra
• Các bộ đệm âm thanh và khung hình ảnh có thể sử dụng
• ứng dụng đang thực thi
Ví dụ tạo một cửa sổ hình ảnh và đăng ký các hàm Callback khung, chuỗi hình ảnh,
lỗi và trạng thái. Ví dụ cũng đưa vào một câu lệnh đơn giản để ngăn chặn hàm
Callback.
Ví dụ:
Case WM_CREATE:
{
char achDeviceName [80];
char achDeviceVersion [100];
char achBuffer [100];
WORD wDriverCount = 0;
WORD wIndex;
WORD wError;
HMENU hMenu;
// taọ cửa sổ hiện hình ảnh sử dụng macro “capCreateCaptureWIndow”.
GhWndCap = capCreateCaptureWindow ((LPSTR) “CaptureWindow”,
WS_CHILD | WS_VISIBLE, 0, 0,160, 120, (HWND) hWnd, (int) 0),
Đăng ký hàm callback lỗi sử dụng macro “capSetCallbackOnError”.
CapSetCallbackOnError (ghWndCap, fpErrorCallback);
// Đăng ký hàm Callback trạng thái sử dụng macro “capSetCallbackOnStatus”.
CapSetCallbackOnStatus (ghWndCap, fpStatusCallback);
// Đăng ký hàm Callback trạng thái sử dụng macro “ capSerCallbackOnStatus”.
CapSetCallbackOnFrame (ghWndCap, fpFrameCallback);
//Kết nối vưói thiết bị thu ảnh.
Break;
}
case WM_CLOSE
{
// Để ngừng callback khung sử dụng macro “capSetCallbackOnFrame”. Tương tự với
các hàm callback khác.
CapSetCallbackOnFrame (hWndC, NULL);
Break;}
CHƯƠNG 2: ĐIỀU KHIỂN CỔNG LPT TRÊN
WINDOWS NT/2000/XP
2.1 Đặt vấn đề
Viết chương trình giao tiếp với cổng song song của máy tính thật đơn giản với
Dos và cả với Win95/98.Chúng ta có thể sử dụng các hàm Inportb() và Outportb() hay
là _inp() và _outp() một cách trực tiếp và không mắc phải bất cứ vấn đề gì.Nhưng khi
làm việc với các hệ điều hành mới hơn như là WinNT4, Win2000 hay là WinXP, mọi
điểu tưởng như đơn giản đó không còn nữa. Khi chúng ta cố gắng chạy một chương
trình sử dụng các hàm thông thường như là inportb() , outportb() hay là _inport() và
_outp() trên hệ điều hành như Win2000, lập tức sẽ xuất hiện thông báo lỗi như sau :
"The exception privileged instruction occurred in the application at location ...."
Khi bắt đầu nhìn thấy thông báo trên, ta có thể nghĩ rằng “Mình đã mắc lỗi
ở đâu đó trong chương trinh ?” nhưng rõ ràng chương trình chạy tốt trên Win98
…vậy thì lỗi là do đâu ?Câu trả lời sẽ được giải đáp ở ngay sau đây.
Là một biện pháp bảo mật hệ thống , Windows NT hạn chế một số đặc
quyền của các loại ngôn ngữ lập trình khác chạy trên nó. Windows sắp xếp tất cả các
chương trình thành hai loại , đó là mode người dùng (user mode) và mode nhân(kenel
mode); chạy trên mode ring3() (với mode người dùng) và mode ring() với mode nhân.
Mode người dùng bị hạn chế sử dụng các hàm liên quan đến IN, OUT …Nên khi mà
hệ điều hành phát hiện chương trình ở mode người dùng đang cố gắng chạy các hàm
đó, Hệ điều hành sẽ lập tức dừng chương trình đó lại và đưa ra thông báo lỗi như ta
thấy.
Cuối cùng là các giao tiếp sẽ bị chặn đứng bởi hệ điều hành khi ta cố gắng
thực thi các lệnh đọc và viết thông qua cổng song song.Nhưng trong khi đó , đối với
các chương trình thực hiện ở mức nhân thì hệ điều hành không có cách nào để ngăn
chặn được.Các driver thiết bị có thể chạy ở mức nhân của hệ thống, Như vậy cách giải
quyết ở đây là chúng ta bắt đầu vấn đề với việc viết một chương trình dưới kernel
mode để đọc và viết dữ liệu qua cổng song song còn chương trình truyền dữ liệu tới đó
sẽ là ở mode người sử dụng.Điều này không hẳn là dễ dàng nhưng chúng ta đã có sự
hỗ trợ bởi các driver đã được cài đặt và tùy chỉnh.
2.2.Lời giải đáp cho bài toán trên:
Ở đây sẽ giới thiệu về inpout32.dll cho Win98/2000/NT/XP , dll này có những đặc
điểm sau:
1.Nó làm việc như nhau đối với tất cả các hệ điều hành Win98/2000/NT và XP.
2.Nó có thể điều khiển thiết bị ở mức nhân.
3.Không yêu cầu các phần mềm khác hay là thiết bị khác phải được cài đặt
4.Không cần các hàm đặc biệt API , chỉ cần hai hàm đó là Inp32 và Out32.
5.Driver sẽ được tự động cài đặt và tùy chỉnh khi mà dll này được load tới.
6.Có thể dễ dàng sử dụng với VC++ và VB.
7.Tài liệu sử dụng và mã nguồn miễn phí được cung cấp và hướng dẫn tại
2.3.Cách làm việc với inport32.dll:
Inpout32.dll có thể làm việc dưới tất cả các hệ điều hành mà không cần sửa đổi mã
chương trình cần soạn thảo. Khi bắt đầu làm việc, DLL này sẽ kiểm tra hệ điều hành
đang được sử dụng , nếu là 9X thì Dll se sử dụng các hàm _inp() và _outp() để đọc
cổng song song, còn nếu là WINNT hay 2000/XP , nó sẽ cài đặt driver ở mức nhân và
thông báo cho cổng song song biết driver đã được cài đặt.Thực tế thì mã sử dụng
không thể hiểu được đang chạy trên hệ điều hành gì? Dll này có thể sử dụng trên tất cả
các phiên bản Windows như nhau .Có thể minh họa các ý trên như sau:
Người dùng gọi các
hàm inp32() hoặc
out32()
Kiểm tra phiên bản hệ điều hành
Win9X WinNT
Y N
Y
N
Driver đọc hoặc ghi dữ liệu
từ cổng Song Song sử dụng
các hàm HAL
Kiểm tra hwinterface.sys
driver kernel mode đã
được load tới?
Cài đặt
driver
Cố gắng load tới driver
này thành công ?
Cho phép dữ liệu
được truyền nhờ
driver, sử dụng thư
viện API
Sử dụng thư viện các hàm
_inp() và _out() để truyền
dữ liệu
Kết thúc
Có hai khối quan trọng của chương trình là:
1. Driver dành cho thiết bị ở kernel mode dựa trên DLL trong mã nhị phân
2. DLL Inpout32 mà ta đang xét.
Kernel mode driver Hwinterface.sys
Mã nguồn của Hwinterface.sys được định vị bởi thư mục
“kernel_mode_drever_source”,tại đó thì “hwinterfacedrv.c” là file nguồn chính.Bao
gồm các chức năng sau :
1) ‘Driver Entry’: được gọi khi mà driver đã được load tới, nó tạo tới thiết bị một
liên kết tượng trưng.
2)’hwinterfaceUnload’,được gọi khi driver không còn được tham chiếu tới nữa.
3)’hwinterfaceDeviceControl’, điều khiển thông qua DeviceIOControl API, cho
phép đọc và viết qua cổng song song nhờ các mã thông thường.
DLL Inpout32
Các hàm trong thư viện DLL được độc lập cung cấp bởi hai file , đó là
“inpout32drv.cpp” và “osversion.cpp”.Oversion.cpp kiểm tra phiên bản hệ điều
hành.Còn “inpout32drv.cpp” có nhiệm vụ cài đặt driver cho mode kernel , dẫn tới đó,
viết/đọc cổng song song, …Hai chức năng được inpout32.dll support là:
1)’Inp32’, đọc dữ liệu từ cổng song song.
2)’Out32’, ghi dữ liệu ra cổng song song.
Các chức năng được cung cấp bởi Inpout32.dll là :
1)’DllMain’,được gọi khi dll được load tới hay không load tới.Khi dll này được load
tới,nó sẽ kiểm tra phiên bản của hệ điều hành và load tới hwinterface.sys nếu cần.
2)’Closedriver’,điều khiển driver đóng hay mở, được gọi trước khi gỡ bỏ driver ra.
3)’Opendriver’,mở một driver trong hwinterface.
4)’inst’,giải nén ‘hwinterface.sys’ từ mã nhị phân tới thư mục ‘systemroot\driver’ để
phục vụ, hàm này được gọi khi mà hàm ‘Opendriver ’ không thể thực thi trong
‘hwinterface’.
5)’Start’,khởi động dịch vụ hwinterface sử dụng Service Control Manager API.
6)’System Version’ kiểm tra phiên bản hệ điều hành, trả lại giá trị tương ứng.
* ngoài ra, còn có thể sử dụng hwinterface.ocx ActiveX control (cho cả VB và
VC++, nhưng tốt hơn là nên sử dụng với VB) giống như là hwinterface.dll
CHƯƠNG 3: MINH HỌA THUẬT TOÁN VÀ CHƯƠNG TRÌNH
Hình P2.3.1: Minh họa sản phẩm
Hình P2.3.2: Ảnh camera bắt được khi xử lý với một vật thể .
Trong ứng dụng thử nghiệm này, tôi chọn một lớp ứng dụng của window đó là
AVICap để thực hành bám đối tượng.AVICap là một lớp ứng dụng của Window cung
cấp các ứng dụng vô cùng thuận lợi cho việc viết các chưng trình giao tiếp đặc biệt là
truy nhập các thiết bị video như là camera đã được sử dụng trong chưng trình demo
này.
Kết hợp với lớp “inpout32drv.cpp” để có thể điều khiển cổng song song cho
chức năng điều khiển chuyển động của đế camera.
#include
Để có thể bám theo đối tượng từ dữ liệu nhận vào của một camera động, chúng
ta hiển nhiên cần thu thập và phân tích các khung ảnh (frame) riêng rẽ đang được thu
thập và xủ lý .Và để thu thập các frame này trước khi duyệt, ta sử dụng
capSetCallbackOnFrame macro.
BOOL capSetCallbackOnFrame(HWND hwnd, FrameCallback fpProc);
HWND hwnd: (Handle to the capture window )Điều khiển các cửa sổ ảnh .
FrameCallback fpProc: Con trỏ chỉ tới hàm duyệt được gọi lại sau mỗi frame
.Các giá trị NULL dành cho các tham số bên trong nếu như vô hiệu hoá các giá trị
được cài đặt tại hàm duyệt lại ngay trước đó.
typedef LRESULT (*FrameCallback)(HWND hWnd, LPVIDEOHDR lpVideoHdr);
Lớp LPVIDEOHDR được minh hoạ bởi:
typedef struct videohdr_tag {
LPBYTE lpData; /* Con trỏ đệm Pointer to buffer. */
DWORD dwBufferLength; /* Độ dài của bộ đệm Length of buffer. */
DWORD dwBytesUsed; /* Số byte thực tế đã sử dụng Bytes actually used. */
DWORD dwTimeCaptured; /* Thời gian bắt đầu nhận luồng frame nh Timefrom
start of stream. */
DWORD dwUser;
DWORD dwFlags; /*Các Cờ Flags. */
DWORD dwReserved[4];
}
#define VHDR_DONE 0x00000001
#define VHDR_PREPARED 0x00000002
#define VHDR_INQUEUE 0x00000004
#define VHDR_KEYFRAME 0x00000008
Mỗi một khung tiến trình gọi lại được kết hợp với cửa sổ chụp ảnh, Chúng ta sẽ
xét tất cả các khung để bắt đầu bám theo đối tượng.
Color Space
Trước khi bắt đầu tiến trình với các frame ảnh, quan trọng là chúng ta phải hiểu
được sự khác nhau giữa các không gian màu được video số hoá .Có nhiều không gian
màu có thể được sử dụng, mỗi một loại có cường độ và giới hạn khác nhau.Việc chọn
chính xác bảng màu sẽ làm đơn giản hoá những tính toán quan trọng và phức tạp.
Đặc trưng màu mà chúng ta sẽ tìm hiểu ở chưng trình demo này là độ sáng, và
chúng ta sẽ bám theo đối tượng dựa trên sự đánh giá về độ sáng .Một cách tiếp cận rất
đơn giản và chắc chắn đó là chia ra các thành phần của độ sáng .YUV là một không
gian màu rất cần thiết mà chúng ta cần tìm hiểu, tuy nhiên , YUV không phi là định
dạng có thể thu được từ một webcam.Vậy nên, có một sự thay thế khác đó là sự phụ
thuộc vào RGB24 là định dạng vào của một webcam tới YUV.
Mối quan hệ giữa RGB và YUV có thể minh hoạ bởi một mối quan hệ tuyến
tính sau:
[ Y ] [ 0.257 0.504 0.098 0.063 ][ R ]
[ U ] = [ -0.148 -0.291 0.439 0.500 ][ G ]
[ V ] [ 0.439 -0.368 -0.072 0.500 ][ B ]
[ 1 ] [ 0.000 0.000 0.000 1.000 ][ 1 ]
Ma trận kết qu này là c sở cho các phép biến đổi số học tuyến tính, mà ở trong
trường hợp này, giống như là phép biến đổi với hệ cơ sở bậc ba mới với các cơ sở
thành phần là R = G = B
Đặc trưng bám vật:
Bây giờ chúng ta sẽ truy nhập trực tiếp đến độ sáng của mỗi điểm ảnh.Có một
thuật toán đơn giản có thể làm được điều là bám theo vật và xem vật như là đn giản chỉ
là một đối tượng sáng .Thuật toán đó sẽ được giới thiệu ngay sau đây và xin tạm gọi
đó là “Thuật toán hình chữ nhật”.Thuật toán hình chữ nhật giữ và bám theo luôn luôn
tại bốn điểm tương đối của vật tại mỗi khung ảnh nhận được(frame), một điểm cao
nhất , một điểm thấp nhất , điểm trái nhất và điểm phải nhất nơi mà độ sáng vượt quá
một giá trị ngưỡng xác định nào đó.
Phải chắc chắn là đã sử dụng định dạng RGB24 cho lối vào của Webcam với
đoạn mã sau đây:
LRESULT CChildView::FrameCallbackProc(HWND hWnd, LPVIDEOHDR
lpVideoHdr)
{
...
...
for (int i=0; i<nHeight; ++i)
{
for (int j=0; j<nWidth; ++j)
{
/*Lấy. chỉ số bộ đệm thích hợp */
index = 3*(i*nWidth+j);
/* Tính toán các thành phần màu */
Y = floor(0.299*lpData[index+2] + 0.587*lpData[index+1] +
0.114*lpData[index] + 0.5);
/* Nếu độ sáng vượt quá giá trị ngưỡng cho phép*//
if (Y > bThreshold)
{
/*Khởi tạo con trỏ */
if (init)
{
if (pLeft.x > j) {
pLeft.x = j;
pLeft.y = i;
}
if (pRight.x < j) {
pRight.x = j;
pRight.y = i;
}
pBottom.x = j;
pBottom.y = i;
}
/* Luôn luôn bám theo bốn góc của đối tượng. */
else {
pTop.x = pBottom.x = pLeft.x = pRight.x = j;
pTop.y = pBottom.y = pLeft.y = pRight.y = i;
init = true;
}
}
}
}
...
...
}
Hình chữ nhật có thể được xây dung lên tử các điểm trên, cái đó cho ta biết đâu
là vị trí của vật sáng , Khung của hình chữ nhật sau đó được dễ dàng thay thế bởi một
màu được định nghĩa tử trước.
if (init) {
/*Thay thế khung với các điểm màu được xác định trước. */
for (int i=pLeft.x; i<=pRight.x; ++i) {
index = 3*((pTop.y)*nWidth + i); /* Trên */
lpData[index] = 0; /* B */
lpData[index+1] = 0; /* G */
lpData[index+2] = 255; /* R */
index = 3*((pBottom.y)*nWidth + i); /* Dưới */
lpData[index] = 0; /* B */
lpData[index+1] = 0; /* G */
lpData[index+2] = 255; /* R */
}
for (int i=pTop.y; i<=pBottom.y; ++i) {
index = 3*((i)*nWidth + pLeft.x); /* Trái */
lpData[index] = 0; /* B */
lpData[index+1] = 0; /* G */
lpData[index+2] = 255; /* R */
index = 3*((i)*nWidth + pRight.x); /* Phải */
lpData[index] = 0; /* B */
lpData[index+1] = 0; /* G */
lpData[index+2] = 255; /* R */
}
}
Thuật toán này rõ ràng còn chứa nhiều khuyết điểm:
i> Nó chỉ cho biết vị trí của vật trên màn hình.
ii> Nó không cho ta biết một chút thông tin gì về hình dạng của vật.
iii> Nó không cho ta biết đâu là trọng tâm của vật.
iv> Và quan trọng nhất, nó không bao giờ có thể bám nếu có nhiều đối tượng
chuyển động(Tuy nhiên , do tính thử nghiệm nên đề tài này sẽ sử dụng ngay thuật toán
này để áp dụng)
Một thuật toán cải tiến hơn:
Hình P3.2.3 :Ảnh camera bắt được nhiều vật
Thuật toán này phát hiện theo đối tượng bằng cách nhận dạng các đoạn phần
tử tạo nên đối tượng trên màn hình. Mỗi đoạn được tạo nên bởi tiêu đề và độ dài của
mỗi đoạn đó.Đối tượng được cấu trúc nên bởi các nhóm đoạn đó với nhau.
BYTE Y; int index;
/* --Biến sử dụng bởi thuật toán mới này. -- */
QSEG segment;
std::list object;
for (int i=0; i<nHeight; ++i) {
segment.length = 0;
for (int j=0; j<nWidth; ++j) {
index = 3*(i*nWidth+j);
Y = floor(0.299*lpData[index+2] + 0.587*lpData[index+1] +
0.114*lpData[index] + 0.5);
if (Y > bThreshold) {
if (segment.length == 0) {
segment.head.x = j;
segment.head.y = i;
}
++segment.length;
}
}
if (segment.length) {
object.push_back(segment);
}
}
/* --Vẽ nên hình dáng của đối tượng với màu được định trước. -- */
for (std::list::iterator i=object.begin(); i!=object.end(); ++i) {
index = 3*((*i).head.y*nWidth + (*i).head.x);
lpData[index] = 255;
lpData[index+1] = 0;
lpData[index+2] = 255;
index = 3*((*i).head.y*nWidth + (*i).head.x + (*i).length);
lpData[index] = 255;
lpData[index+1] = 0;
lpData[index+2] = 255;
}
Thuật toán mới này đã có những cải tiến tốt hơn sau:
i> Nó có thể theo dõi nhiều đối tượng.
ii> Nó có thể theo dõi được hình dáng của các đối tượng
iii> Số lượng các điểm ảnh tạo nên đối tượng có thể dễ dàng tính toán được.Với các
mẫu thông tin và cách tính toán khong cách thích hợp, toạ độ của đối tượng trong ba
chiều cũng có thể được xác định
• Phần Chương Trình :
// ChildView.cpp : implementation of the CChildView class
#include "stdafx.h"
#include "Tracker.h"
#include "MainFrm.h"
#include "ChildFrm.h"
#include "ChildView.h"
#include "TrackDlg.h"
#include
#include
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
typedef struct QSEG_ {
POINT head;
UINT length;
} QSEG, *LPQSEG;
// CChildView
BYTE CChildView::bThreshold = 250;
DWORD CChildView::dwRectangle = 0;
DWORD CChildView::dwSegment = 0;
CChildView::CChildView()
{
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_COMMAND(ID_DEVICE_REFRESH, OnDeviceRefresh)
ON_COMMAND_RANGE(ID_DEVICE_NAME,
ID_DEVICE_NAME+CVideoCapWnd::m_dwDeviceMax, OnDeviceName)
ON_COMMAND(ID_CAPTURE_SOURCE, OnCaptureSource)
ON_COMMAND(ID_CAPTURE_FORMAT, OnCaptureFormat)
ON_COMMAND(ID_CAPTURE_DISPLAY, OnCaptureDisplay)
ON_WM_SIZE()
ON_COMMAND_RANGE(ID_CAPTURE_100, ID_CAPTURE_200,
OnCaptureZoom)
ON_COMMAND(ID_TRACK_BRIGHTNESS, OnTrackBrightness)
ON_COMMAND(ID_TRACK_STOP, OnTrackStop)
ON_COMMAND(ID_CAPTURE_STOP, OnCaptureStop)
END_MESSAGE_MAP()
// CChildView message handlers
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass =
AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW),
reinterpret_cast(COLOR_WINDOW+1), NULL);
return TRUE;
}
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CWnd::OnPaint() for painting messages
}
void CChildView::OnDeviceRefresh()
{
/* -- Get device menu. --*/
CMenu *mDev = AfxGetMainWnd()->GetMenu()->GetSubMenu(3);
MENUITEMINFO miInfo;
do
{
/* -- Find position of separator. -- */
miInfo.cbSize = sizeof(MENUITEMINFO);
miInfo.fMask = MIIM_TYPE;
mDev->GetMenuItemInfo(0, &miInfo, TRUE);
/* -- Delete all entries before separator. -- */
if (miInfo.fType != MFT_SEPARATOR) {
mDev->DeleteMenu(0, MF_BYPOSITION);
}
} while (miInfo.fType != MFT_SEPARATOR);
/* -- Put device names before separator. -- */
CString strDevName, strDevVer;
for (DWORD i=0; i<m_theVideoCapWnd.m_dwDeviceMax; ++i) {
m_theVideoCapWnd.GetDriverDescription(i, strDevName, strDevVer);
if (strDevName.GetLength()) {
mDev->InsertMenu(0, MF_BYPOSITION, ID_DEVICE_NAME+i,
strDevName);
}
}
}
void CChildView::OnDeviceName(UINT nID)
{
/* -- Get device index by subtracting the offset. -- */
nID = nID - ID_DEVICE_NAME;
CString strErr;
/* -- Create the capture window if we haven't done do. -- */
if (m_theVideoCapWnd.m_hWnd == NULL) {
m_theVideoCapWnd.CreateCaptureWindow(CString(""), WS_CHILD |
WS_VISIBLE, CRect(0,0,0,0), this, 0);
if (m_theVideoCapWnd.m_hWnd == NULL) {
strErr.LoadString(IDS_ERR_CAPWND);
MessageBox(strErr);
return;
}
}
/* -- Attempt to connect to driver. -- */
if (m_theVideoCapWnd.DriverConnect(nID) == FALSE) {
strErr.LoadString(IDS_ERR_CONNECT);
MessageBox(strErr);
return;
}
/* -- Retrieve device parameters. -- */
CAPTUREPARMS capParms;
if (m_theVideoCapWnd.CaptureGetSetup(&capParms, sizeof(CAPTUREPARMS))
== FALSE) {
strErr.LoadString(IDS_ERR_GETSETUP);
MessageBox(strErr);
return;
}
/* -- Want separate thread. -- */
capParms.fYield = TRUE;
/* -- Do not abort when left mouse button is clicked. -- */
capParms.fAbortLeftMouse = FALSE;
/* -- Do not abort when right mouse button is clicked. -- */
capParms.fAbortRightMouse = FALSE;
/* -- Update device parameters. -- */
if (m_theVideoCapWnd.CaptureSetSetup(&capParms, sizeof(CAPTUREPARMS))
== FALSE) {
strErr.LoadString(IDS_ERR_SETSETUP);
MessageBox(strErr);
return;
}
/* -- Get current state of capture window. -- */
CAPSTATUS capStat;
if (m_theVideoCapWnd.GetStatus(&capStat, sizeof(CAPSTATUS)) == FALSE) {
strErr.LoadString(IDS_ERR_GETSTAT);
MessageBox(strErr);
return;
}
m_theVideoCapWnd.SetWindowPos(NULL, 0, 0, capStat.uiImageWidth,
capStat.uiImageHeight, SWP_NOMOVE | SWP_NOZORDER);
GetParentFrame()->SetWindowPos(NULL, 0, 0, capStat.uiImageWidth,
capStat.uiImageHeight, SWP_NOMOVE);
/* -- Set preview rate. -- */
if (m_theVideoCapWnd.PreviewRate(33) == FALSE) {
strErr.LoadString(IDS_ERR_PREVRATE);
MessageBox(strErr);
return;
}
/* -- Turn on scaling. -- */
if (m_theVideoCapWnd.PreviewScale(TRUE) == FALSE) {
strErr.LoadString(IDS_ERR_PREVSCALE);
MessageBox(strErr);
return;
}
/* -- Start preview. -- */
if (m_theVideoCapWnd.Preview(TRUE) == FALSE) {
strErr.LoadString(IDS_ERR_PREV);
MessageBox(strErr);
return;
}
}
void CChildView::OnCaptureSource()
{
CString strErr;
/* -- Retrieve device capabilities. -- */
CAPDRIVERCAPS capCap;
if (m_theVideoCapWnd.DriverGetCaps(&capCap, sizeof(CAPDRIVERCAPS)) ==
FALSE) {
strErr.LoadString(IDS_ERR_GETCAPS);
MessageBox(strErr);
return;
}
/* -- Check if device supports video source dialog. -- */
if (capCap.fHasDlgVideoSource) {
if (m_theVideoCapWnd.DlgVideoSource() == FALSE) {
strErr.LoadString(IDS_ERR_SOURCE);
MessageBox(strErr);
}
}
else {
strErr = "Device does not support video source dialog.";
MessageBox(strErr);
}
}
void CChildView::OnCaptureFormat()
{
CString strErr;
/* -- Retrieve device capabilities. -- */
CAPDRIVERCAPS capCap;
if (m_theVideoCapWnd.DriverGetCaps(&capCap, sizeof(CAPDRIVERCAPS)) ==
FALSE) {
strErr.LoadString(IDS_ERR_GETCAPS);
MessageBox(strErr);
return;
}
/* -- Check if device supports video format dialog. -- */
if (capCap.fHasDlgVideoFormat) {
if (m_theVideoCapWnd.DlgVideoFormat() == FALSE) {
strErr.LoadString(IDS_ERR_FORMAT);
MessageBox(strErr);
}
}
else {
strErr = "Device does not support video format dialog.";
MessageBox(strErr);
}
}
void CChildView::OnCaptureDisplay()
{
CString strErr;
/* -- Retrieve device capabilities. -- */
CAPDRIVERCAPS capCap;
if (m_theVideoCapWnd.DriverGetCaps(&capCap, sizeof(CAPDRIVERCAPS)) ==
FALSE) {
strErr.LoadString(IDS_ERR_GETCAPS);
MessageBox(strErr);
return;
}
/* -- Check if device supports video display dialog. -- */
if (capCap.fHasDlgVideoDisplay) {
if (m_theVideoCapWnd.DlgVideoDisplay() == FALSE) {
strErr.LoadString(IDS_ERR_DISPLAY);
MessageBox(strErr);
}
}
else {
strErr = "Device does not support video display dialog.";
MessageBox(strErr);
}
}
void CChildView::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
/* -- Centralize the video capture window. -- */
if (m_theVideoCapWnd.m_hWnd != NULL) {
CRect paRect, cpRect;
GetClientRect(&paRect);
m_theVideoCapWnd.GetClientRect(&cpRect);
m_theVideoCapWnd.SetWindowPos(NULL, 0, 0, paRect.Width(),
paRect.Height(), SWP_NOMOVE | SWP_NOZORDER);
}
else {
/* -- Resize the child window. -- */
GetParentFrame()->SetWindowPos(NULL, 0, 0, 200, 200, SWP_NOMOVE);
}
}
void CChildView::OnCaptureZoom(UINT nID)
{
if (m_theVideoCapWnd.m_hWnd != NULL) {
/* -- Get current state of capture window. -- */
CAPSTATUS capStat;
if (m_theVideoCapWnd.GetStatus(&capStat, sizeof(CAPSTATUS))) {
UINT nZoom = nID - ID_CAPTURE_100 + 1;
UINT nWidth = capStat.uiImageWidth * nZoom;
UINT nHeight = capStat.uiImageHeight * nZoom;
m_theVideoCapWnd.SetWindowPos(NULL, 0, 0, nWidth, nHeight,
SWP_NOMOVE | SWP_NOZORDER);
CMDIChildWnd *pChild = DYNAMIC_DOWNCAST(CMDIChildWnd,
GetParentFrame());
pChild->MDIRestore();
GetParentFrame()->SetWindowPos(NULL, 0, 0, nWidth, nHeight,
SWP_NOMOVE);
}
else {
CString strErr;
strErr.LoadString(IDS_ERR_GETSTAT);
MessageBox(strErr);
}
}
}
LRESULT CChildView::FrameCallbackProc(HWND hWnd, LPVIDEOHDR
lpVideoHdr)
{
CVideoCapWnd theVideoCapWnd;
CAPSTATUS capStat;
theVideoCapWnd.Attach(hWnd);
if (theVideoCapWnd.GetStatus(&capStat, sizeof(CAPSTATUS))) {
UINT nWidth = capStat.uiImageWidth;
UINT nHeight = capStat.uiImageHeight;
LPBYTE lpData = lpVideoHdr->lpData;
ASSERT(lpVideoHdr->dwBytesUsed == nWidth * nHeight * 3);
if (dwRectangle)
{
BYTE Y; int index; bool init = false;
/* -- Variables used by simple tracking algorithm. -- */
POINT pTop, pBottom, pLeft, pRight;
for (int i=0; i<nHeight; ++i) {
for (int j=0; j<nWidth; ++j) {
index = 3*(i*nWidth+j);
Y = floor(0.299*lpData[index+2] + 0.587*lpData[index+1] +
0.114*lpData[index] + 0.5);
if (Y > bThreshold) {
if (init) {
if (pLeft.x > j) {
pLeft.x = j;
pLeft.y = i;
}
if (pRight.x < j) {
pRight.x = j;
pRight.y = i;
}
pBottom.x = j;
pBottom.y = i;
}
else {
pTop.x = pBottom.x = pLeft.x = pRight.x = j;
pTop.y = pBottom.y = pLeft.y = pRight.y = i;
init = true;
}
}
}
}
/* -- Data regarding object being tracked stored, do something simple about it.
-- */
if (init) {
for (int i=pLeft.x; i<=pRight.x; ++i) {
// -- For pTop.y and pBottom.y --
index = 3*((pTop.y)*nWidth + i);
lpData[index] = 0;
lpData[index+1] = 0;
lpData[index+2] = 255;
index = 3*((pBottom.y)*nWidth + i);
lpData[index] = 0;
lpData[index+1] = 0;
lpData[index+2] = 255;
` }
for (int i=pTop.y; i<=pBottom.y; ++i) {
// -- For pLeft.x and pRight.x --
index = 3*((i)*nWidth + pLeft.x);
lpData[index] = 0;
lpData[index+1] = 0;
lpData[index+2] = 255;
index = 3*((i)*nWidth + pRight.x);
lpData[index] = 0;
lpData[index+1] = 0;
lpData[index+2] = 255;
}
}
/***********************************/
//control tracking object using motorstepper
//calculate center object(capture size = 352 X 288(default))
pCenter.x = (pRight.x + pLeft.x)/2;
pCenter.y = (pTop.y + pBottom.y)/2;
if((pcenter.x - 176)>0)
{TurnLeft();delay(200);} else {TurnRight();delay(200);}
}
else if (dwSegment)
{
BYTE Y; int index;
/* -- Variables used by the new tracking algorithm. -- */
QSEG segment;
std::list object;
for (int i=0; i<nHeight; ++i) {
segment.length = 0;
for (int j=0; j<nWidth; ++j) {
index = 3*(i*nWidth+j);
Y = floor(0.299*lpData[index+2] + 0.587*lpData[index+1] +
0.114*lpData[index] + 0.5);
if (Y > bThreshold) {
if (segment.length == 0) {
segment.head.x = j;
segment.head.y = i;
}
++segment.length;
}
}
if (segment.length) {
object.push_back(segment);
}
}
/* -- Data regarding object being tracked stored, do something simple about it.
-- */
for (std::list::iterator i=object.begin(); i!=object.end(); ++i) {
index = 3*((*i).head.y*nWidth + (*i).head.x);
lpData[index] = 255;
lpData[index+1] = 0;
lpData[index+2] = 255;
index = 3*((*i).head.y*nWidth + (*i).head.x + (*i).length);
lpData[index] = 255;
lpData[index+1] = 0;
lpData[index+2] = 255;
}
}
}
theVideoCapWnd.Detach();
return 0;
}
void CChildView::OnTrackBrightness()
{
// TODO: Add your command handler code here
CTrackDlg dlg;
if (dlg.DoModal()) {
bThreshold = atoi(dlg.m_strBrightness);
if (dlg.m_blRectangle == BST_CHECKED) {
dwRectangle = 1;
dwSegment = 0;
}
else if (dlg.m_blSegment == BST_CHECKED) {
dwRectangle = 0;
dwSegment = 1;
}
else {
dwRectangle = 0;
dwSegment = 0;
}
m_theVideoCapWnd.SetCallbackOnFrame(FrameCallbackProc);
}
}
void CChildView::OnTrackStop()
{
// TODO: Add your command handler code here
m_theVideoCapWnd.SetCallbackOnFrame((FrameCallback)(NULL));
}
void CChildView::OnCaptureStop()
{
// TODO: Add your command handler code here
m_theVideoCapWnd.DriverDisconnect();
}
• Phần Tài liệu tham khảo.
1. D. Ballard and C. Brown, Computer Vision, previously published by Prentice-
Halldaidb, 1982.
2. D. Phillips, Image Processing in C: Analyzing and Enhancing Digital Images,
previously published by RandD Publications, 1994.
3. D. Vernon; Machine Vision : Automated Visual Inspection and Robot Vision,
Prentice Hall, 1991, ISBN 0-13-543398-3.
4. Ngô Tiến Thành,Xác Định Tọa Độ Của Vật Chuyển Động Qua Cảm Biến Ảnh,
Khóa Luận Tốt Nghiệp Đại Học Công Nghệ , 2003.
Các file đính kèm theo tài liệu này:
- Luận văn- Xử lý ảnh và ứng dụng theo dõi đối tượng chuyển động.pdf