Tải bản đầy đủ (.docx) (31 trang)

Tiểu luận nhận diên và xử lí ảnh

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.17 MB, 31 trang )

TRƯỜNG ĐẠI HỌC QUẢNG BÌNH
KHOA KỸ THUẬT – CƠNG NGHỆ THÔNG TIN
----------------–&–----------------

ĐỀ TÀI
ỨNG DỤNG XỬ LÝ ẢNH TRONG THỰC TẾ
VỚI THƯ VIỆN OPENCV C/C++

Giảng viên hướng dẫn: TS. Hoàng Văn Thành
Người thực hiện: Nguyễn Tiến Dũng
Lớp: Đại học Công nghệ thông tin K61 (LT)

Đồng Hới, ngày 21 tháng 05 năm 2021
1


2


MỤC LỤC

MỤC LỤC....................................................................................................................... 2
LỜI MỞ ĐẦU.................................................................................................................3
PHẦN I: MỞ ĐẦU..........................................................................................................4
1. LÝ DO CHỌN ĐỀ TÀI.........................................................................................4
2. MỤC TIÊU CỦA ĐỀ TÀI......................................................................................4
3. ĐỐI TƯỢNG VÀ PHẠM VI NGHIÊN CỨU........................................................4
4. PHƯƠNG PHÁP NGHIÊN CỨU..........................................................................4
Chương I: Làm quen với thư viện OpenCV....................................................................5
1. Giới thiệu về thư viện OpenCV..............................................................................5
2. Phiên bản OpenCV 1 hay OpenCV 2?...................................................................5


Chương II: Các phép xử lý ảnh và ứng dụng cơ bản.......................................................7
1. Không gian màu, chuyển đổi giữa các không gian màu.........................................7
a. Không gian màu RGB........................................................................................................................7
b. Không gian màu CMYK....................................................................................................................7
c. Không gian màu HSV........................................................................................................................8

2. Chuyển đổi giữa các không gian màu....................................................................9
a. Chuyển đổi RGB sang CMYK và ngược lại.....................................................................................9
b. Chuyển đổi RGB sang HSV và ngược lại.........................................................................................9

3. Điều chỉnh độ sang và độ tương phản trong ảnh..................................................10
4. Ảnh nhị phân, nhị phân hóa với ngưỡng động.....................................................11
5. Histogram, cân bằng histogram trong ảnh............................................................13
6. Phóng to, thu nhỏ và xoay ảnh.............................................................................13
7. Lọc số trong ảnh...................................................................................................13
Chương III: Lập trình xử lý ảnh với giao diện MFC.....................................................16
1. Giới thiệu về MFC...............................................................................................16
2. Khởi tạo project MFC..........................................................................................16
3. Làm việc với các điều khiển (Control) của MFC.................................................19
4. Chuyển đổi các kiểu dữ liệu trong MFC..............................................................22
5. Chương trình tải ảnh và hiển thị ảnh trên giao diện MFC....................................23
PHẦN II: KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN.....................................................32
1. Đánh giá kết quả đạt được..................................................................................32
2. Hạn chế................................................................................................................32
3. Hướng phát triển..................................................................................................32


LỜI MỞ ĐẦU
Xử lý ảnh và thị giác máy là lĩnh vực mà ngày nay được phát triển và ứng
dụng rất rộng rãi trong nhiều lĩnh vực khác nhau nhờ vào sự phát triển ngày càng

mạnh mẽ của các hệ thống máy tính, các thuật tốn và cơng trình nghiên cứu khác
nhau của nhiều nhà khoa học trên thế giới.
Ở Việt Nam, các ứng dụng về xử ảnh đã bước đầu được triển khai trên một số
lĩnh vực như lắp đặt hệ thống nhận dạng biển biển số xe ở các bãi đổ xe, hệ thống
nhận dạng vân tay chấm công ở các công sở… môn học xử lý ảnh ở các trường đại
học được xem là môn học bắt buộc ở một số ngành như công nghệ thông tin, điện
tử viễn thơng… Tuy nhiên nhìn một cách khách quan thì số lượng các ứng dụng
được triển khai trên thực tế là q ít ỏi, lĩnh vực này sẽ cịn phát triển mạnh mẽ
trong tương lai nếu như được quan tâm một cách nghiêm túc.
Xuất phát từ thực tế rằng môn học xử lý ảnh ở các trường đại học là một mơn
học mang nặng tính học thuật, khơ khan, các vấn đề được mơ tả dưới dạng tốn
học, thêm vào đó số lượng tài liệu về chuyên ngành này bằng tiếng Việt là không
nhiều, cho nên tôi đã làm về đề tài “Ứng dụng xử lý ảnh trong thực tế với thư viện
OpenCV”.
Đề tài đề cập tới một số phần của lĩnh vực xử lý ảnh và thị giác máy, thơng
qua sự diễn giải trực quan, có được cái nhìn tổng quát, hiểu được khái niệm và hơn
nữa biết được những vấn đề đó ứng dụng vào thực tế như thế nào. Các chủ đề trong
cuôn sách này đều đi kèm với một chương trình mơ phỏng được viết bằng ngôn
ngữ C++ với sự giúp đỡ của thư viện OpenCV, một thư viện mã nguông mở được
đánh giá là mạnh mẽ về tốc độ xử lý đáp ứng được các ứng dụng trong thời gian
thực.
Tài liệu được chia thành bốn phần, phần đầu giới thiệu về thư viện OpenCV,
phần thứ hai nói về một số vấn đề chọn lọc thường gặp trong xử lý ảnh như không
gian màu, các bộ lọc, cách phát hiện đường thẳng đường tròn trong ảnh …, phần
thứ ba nói về một số thủ thuật để lập trình với thư viện MFC và phần cuối cùng nói
về một số ứng dụng thực tế như bài toán nhận dạng biển số xe …
Thư viện OpenCV là bản OpenCV 2.4.3, đối với các bản OpenCV khác thì có
thể tùy chỉnh lại một chút tuy nhiên về bản chất của vấn đề là tương đối giống
nhau. Ngôn ngữ lập trình cho các ví dụ là C/C++, IDE sử dụng là Visual Studio
2010. Tuy nhiên đa số chương trình đều được tách biệt phần xử lý chính ra vào một

file *.cpp nào đó nên ta có thể lấy nó để áp dụng vào các trình dịch khác.


PHẦN I: MỞ ĐẦU
1. LÝ DO CHỌN ĐỀ TÀI
Cùng với sự phát triển khoa học kỹ thuật, nhu cầu của con người ngày càng
tăng, việc để tạo ra một bức ảnh đẹp thỏa mãn cho mọi người và lưu giữ lại những
kỉ niệm là điều không thể thiếu với mong muốn:
+ Chất lượng hình ảnh cao.
+ Tính tiện lợi, dễ lưu trữ.
Với việc phát triển công nghệ thông tin, các dữ liệu đa phương tiện ngày một
tăng. Việc có một phần mềm xử lý ảnh phục vụ cho nhu cầu của mọi người là điều
tất yếu.
2. MỤC TIÊU CỦA ĐỀ TÀI
+ Tìm hiểu về ngơn ngữ lập trình C/C++ .
+ Tìm hiểu quá trình nhận dạng và xử lý ảnh.
+ Tìm hiểu về thư viện OpenCV qua đó ứng dụng nó trong việc tạo ra một
phần mềm xử lý ảnh
3. ĐỐI TƯỢNG VÀ PHẠM VI NGHIÊN CỨU
Đối tượng nghiên cứu:
+ Thư viện OpenCV và q trình xử lý ảnh.
+ Ngơn ngữ lập trình C/C++
Phạm vi nghiên cứu:
+ Ứng dụng quá trình xử lý ảnh với MFC (Microsoft Foundation Classes).
4. PHƯƠNG PHÁP NGHIÊN CỨU
Phương pháp tham khảo tài liệu
+ Thu thập, đọc hiểu, phân tích thơng tin, dữ liệu từ các tài liệu, giáo trình,
sách liên quan đến nhận dạng xử lý ảnh.
+ Các tài liệu liên quan đến nhận dạng và xử lý ảnh.
Phương pháp thực hành:

+ Tìm hiểu giải thuật nhận dạng và xử lý ảnh, sử dụng thư viện Opencv trong
ngơn ngữ lập trình C/C++ để lập trình xử lý ảnh với phần mềm MFC (Microsoft
Foundation Classes).


Chương I: Làm quen với thư viện OpenCV
1. Giới thiệu về thư viện OpenCV
OpenCV (Open Source Computer Vision) là một thư viện mã nguồn mở về thị
giác máy với hơn 500 hàm và hơn 2500 các thuật toán đã đư ợc tối ưu về xử lý ảnh,
và các vấn đề liên quan tới thị giác máy. OpenCV được thiết kế một cách tối ưu, sử
dụng tối đa sức mạnh của các dòng chip đa lõi… để thực hiện các phép tính tốn
trong thời gian thực, nghĩa là tốc độ đáp ứng của nó có thể đủ nhanh cho các ứng
dụng thông thường. OpenCV là thư viện được thiết kế để chạy trên nhiều nền tảng
khác nhau (cross-patform), nghĩa là nó có thể chạy trên hệ điều hành Window,
Linux, Mac, iOS … Việc sử dụng thư viện OpenCV tuân theo các quy định về sử
dụng phần mềm mã nguồn mở BSD do đó bạn có thể sử dụng thư viện này một
cách miễn phí cho cả mục đích phi thương mại lẫn thương mại.
Dự án về OpenCV được khởi động từ những năm 1999, đến năm 2000 nó
được giới thiệu trong một hội nghị của IEEE về các vấn đề trong thị giác máy và
nhận dạng, tuy nhiên bản OpenCV 1.0 mãi tới tận năm 2006 mới chính thức được
cơng bố và năm 2008 bản 1.1 (pre-release) mới được ra đời. Tháng 10 năm 2009,
bản OpenCV thế hệ thứ hai ra đời (thường gọi là phiên bản 2.x), phiên bản này có
giao diện của C++ (khác với phiên bản trước có giao diện của C) và có khá nhiều
điểm khác biệt so với phiện bản thứ nhất.
Thư viện OpenCV ban đầu được sự hỗ trợ từ Intel, sau đó được hỗ trợ bở
Willow Garage, một phịng thí nghiệm chun nghiên cứu về công nghệ robot. Cho
đến nay, OpenCV vẫn là thư viện mở, được phát triển bởi nguồn quỹ không lợi
nhuận (none -profit foundation) và được sự hưởng ứng rất lớn của cộng đồng.
2. Phiên bản OpenCV 1 hay OpenCV 2?
Cho tới nay, trải qua hơn 6 năm từ lúc phiên bản OpenCV đầu tiên được cơng

bố, đã có lần lượt nhiều phiên bản OpenCV ra đời, tuy nhiên có thể chia thư viện
này thành hai bản chính dựa trên những đặc điểm khác biệt lớn nhất của chúng:
phiên bản OpenCV thế hệ thứ nhất (hay còn gọi là phiên bản OpenCV 1.x) và phiên
bản OpenCV thứ hai (hay còn gọi là phiên bản OpenCV 2.x). Sau đây ta sẽ chỉ ra
một số điểm khác biệt cơ bản giữa hai phiên bản này.
OpenCV 1.x (bao gồm bản 1.0 và bản pre-release 1.1) dựa trên giao diện C,
cấu trúc của một ảnh số dựa trên cấu trúc của IplImage, trong khi thư OpenCV 2.x
dựa trên giao diện C++, cấu trúc của ảnh số, ma trận dựa trên cấu trúc của cv::Mat.


Trong OpenCV 1.x, người sử dụng phải hoàn toàn quản lý bộ nhớ của các đối
tượng, nghĩa là khi một đối tượng mới được tạo ra, ta phải luôn chú ý để giải phóng
nó khi khơng cịn sử dụng nữa (trong nhiều trường hợp có thể sẽ bị tràn bộ nhớ nếu
không chú ý đều này), trong khi thư viện OpenCV 2.x việc quản lý bộ nhớ trở nên
dễ dàng hơn nhờ các hàm hủy các các lớp đối tượng trong OpenCV 2.x đã thực
hiện điều này khi một đối tượng khơng cịn được sử dụng nữa. Việc viết các dòng
lệnh để thực hiện cùng một chức năng trong OpenCV 2.x là dễ dàng hơn nhiều so
với OpenCV 1.x, một phần là là giao diện C++ có phần dễ hiểu hơn so với C, một
phần là các hàm trong OpenCV 2.x đã được tối ưu hóa nhiều bước trung gian
khơng cần thiết về mặt giao diện người sử dụng.
Thư viện OpenCV 1.x tuy chứa một lượng lớn hàm xử lý và thuật tốn, tuy
nhiên nó vẫn ở dạng sơ khai. Thư viện OpenCV 2.x đã được bổ xung khá nhiều
hàm, thuật toán và được tối ưu khá nhiều đặc biệt trong các khía cạnh về phát hiện
đối tượng (detection), nhận dạng đối tượng (partten regconition) và theo dỗi đối
tượng (tracking). Hơn thế nữa, tuy có giao diện là C++ nhưng OpenCV 2.x vẫn dữ
một phần giao diện C để tương thích với các phiên bản của OpenCV 1.x …
Từ một số đặc điểm trên ta có thể thấy rằng thư viện OpenCV phiên bản 2.x là
có nhiều điểm nổi trội hơn so với phiên bản 1.x, Tuy nhiên trong một số trường hợp
như ở các hệ thống nhúng khi mà trình dịch chỉ đơn thuần chấp nhận ngơn ngữ C
thì phiển bản 1.x vẫn còn giá trị. Trong cuốn sách này, các nội dung cài đặt, thuật

toán, ứng dụng … chỉ dành cho OpenCV phiên bản 2.x trên nền tảng hệ điều hành
Window.


Chương II: Các phép xử lý ảnh và ứng dụng cơ bản
1. Không gian màu, chuyển đổi giữa các không gian màu
Khơng gian màu là một mơ hình tốn học dùng để mô tả các màu sắc trong
thực tế được biểu diễn dưới dạng số học. Trên thực tế có rất nhiều khơng gian màu
khác nhau được mơ hình để sử dụng vào những mục đích khác nhau. Trong bài này
ta sẽ tìm hiểu qua về ba khơng gian màu cơ bản hay được nhắc tới và ứng dụng
nhiều, đó là hệ không gian màu RGB, HSV và CMYK.
a. Không gian màu RGB
RGB là không gian màu rất phổ biến được dùng trong đồ họa máy tính và
nhiều thiết bị kĩ thuật số khác. Ý tưởng chính của khơng gian màu này là sự kết hợp
của 3 màu sắc cơ bản: màu đỏ (R, Red), xanh lục (G, Green) và xanh lơ (B, Blue)
để mô tả tất cả các màu sắc khác.
Nếu như một ảnh số được mã hóa bằng 24bit, nghĩa là 8bit cho kênh R, 8bit
cho kênh G, 8bit cho kênh B, thì mỗ kênh này màu này sẽ nhận giá trị từ 0-255.
Với mỗi giá trị khác nhau của các kênh màu kết hợp với nhau ta sẽ được một màu
khác nhau, như vậy ta sẽ có tổng cộng 255x255x255 = 1.66 triệu màu sắc.
Ví dụ: màu đen là sự kết hợp của các kênh màu
(R, G, B) với giá trị tương ứng (0, 0, 0) màu trắng
có giá trị (255, 255, 255), màu vàng có giá trị (255,
255, 0), màu tím đậm có giá trị (64, 0, 128) ...Nếu ta
dùng 16bit để mã hóa một kênh màu (48bit cho tồn
bộ 3 kênh màu) thì dãi màu sẽ trãi rộng lên tới
3*2^16 = ... Một con số rất lớn.

b. Không gian màu CMYK
CMYK là không gian màu được sử dụng phổ biến trong ngành công nghiệp in

ấn.Ý tưởng cơ bản của hệ không gian này là dùng 4 màu sắc cơ bản để phục vụ cho
việc pha trộn mực in. Trên thực tế, người ta dùng 3 màu là C=Cyan: xanh lơ,
M=Magenta: hồng xẫm, và Y=Yellow: vàng để biểu diễn các màu sắc khác nhau.
Nếu lấy màu hồng xẫm cộng với vàng sẽ ra màu đỏ, màu xẫm kết hợp với xanh lơ
sẽ cho xanh lam ... Sự kết hợp của 3 màu trên sẽ cho ra màu đen, tuy nhiên màu


đen ở đây khôn phải là đen tuyệt đối và thường có độ tương phản lớn, nên trong
ngành in, để tiết kiệm mực in người ta thêm vào màu đen để in những chi tiết có
màu đen thay vì phải kết hợp 3 màu sắc trên. Và như vậy ta có hệ màu CMYK. chữ
K ở đây là để kí hiệu màu đen (Black), có nhẽ chữ B đã được dùng để biểu diễn
màu Blue nên người ta lấy chữ cái cuối K để biểu diễn màu đen?
Nguyên lý làm việc của hệ màu này như sau :
Trên một nền giấy trắng, khi mỗi màu này được in lên
sẽ loại bỏ dần đi thành phần màu trắng. 3 màu C, M, Y
khác nhau in theo những tỉ lệ khác nhau sẽ loại bỏ đi
thành phần đó một cách khác nhau và cuối cùng cho ta
màu sắc cần in. Khi cần in màu đen, thay vì phải in cả
3 màu người ta dùng màu đen để in lên. Nguyên lý
này khác với nguyên lý làm việc của hệ RGB ở chỗ hệ
RGB là sự kết hợp của các thành phần màu, còn hệ
CMYK là sự loại bỏ lẫn nhau của các thành phần màu.
c. Không gian màu HSV
HSV và cũng gần tương tự như HSL là không gian màu được dùng nhiều
trong việc chỉnh sữa ảnh, phân tích ảnh và một phần của lĩnh vực thị giác máy tính.
Hệ khơng gian này dựa vào
3 thông số sau để mô tả màu sắc.
H = Hue: màu sắc, S = Saturation: độ đậm đặc, sự bảo hòa, V = value: giá trị
cường độ sáng. Không gian màu này thường được biểu diễn dưới dạng hình trụ
hoặc hình nón . Theo đó, đi theo vòng tròn từ 0 -360 độ là trường biểu diễn màu

sắc(Hue). Trường này bắt đầu từ màu đỏ đầu tiên (red primary) tới màu xanh lục
đầu tiên (green primary) nằm trong khoảng 0-120 độ, từ 120 - 240 độ là màu xanh
lục tới xanh lơ (green primary – blue primary). Từ 240 - 360 là từ màu đen tới lại
màu đỏ.

Khơng gian màu HSV

Hình trịn biểu diễn màu sắc (HUE)

2. Chuyển đổi giữa các không gian màu


a. Chuyển đổi RGB sang CMYK và ngược lại
Như đã nói ở trên, thành phần K là thành phần phụ dùng để in cho những điểm
màu có màu đen trong hệ CYMK, do vậy để chuyển không gian màu từ RGB sang
CMYK trước hết ta chuyển RGB sang CMY sau đó tìm thành phần K cịn lại. Cơ
ng thức chuyển từ RGB sang CMY:
(C', M', Y') = ((255 - R), (255 - G), (255 - B)).
Việc tính giá trị của K lại là một vấn đề khác vì nó liên quan tới nhà sản xuất
công nghệ in, tuy nhiên về mặt lý thuyết có thể chấp nhận rằng K = min {C'/2,55,
M'/2,55, Y'/2,55} , như vậy 0<= K <=100.
Nếu K = 100, thì C = M = Y =0 (trương hợp in màu đen)
Nếu 0< K < 100: C = (C'/2.55 - K) * 100 /(100 - K), M = (M'/2.55 - K) * 100 /
(100 - K),
Y = (Y'/2.55 - K) *100 /(100 - K) và K = K. Trong đó, C, M, Y, K được làm
trịn tới để lấy chỉ số nguyên.
b. Chuyển đổi RGB sang HSV và ngược lại
Giả sử ta có một điểm màu có giá trị trong hệ RGB là (R, G, B). ta chuyển
sang không gian HSV như sau: Đặt M = Max(R, G, B), m = Min(R, G, B) và C =
M - m.

Nếu M = R, H' = (G - B)/C mod 6. Nếu M = G, H' = (B - R)/C + 2. Nếu M =
B, H' = (R - G)/C + 4. Và H = H'x60. Trong trường hợp C = 0, H = 00
V = M.
S = C/V. Trong trường hợp V hoặc C bằng 0, S = 0. Để chuyển từ HSV sang
RGB ta làm như sau: Giả sử ta có khơng gian màu HSV với H = [0, 360], S = [0,
1], V = [0, 1]. Khi đó, ta tính C = VxS. H' = H/60.


X = C(1 - |H' mod2 -1|). Ta biểu diễn hệ (R1, G1, B1) như sau:
(0, 0, 0) nếu H chưa được xác định
(C,X, 0) nếu 0 ≤ H < 1
(X,C,0) nếu 1 ≤ H < 2
R1, G1, B1) =

(0,C,X) nếu 2≤ H < 3
(0,X,C) nếu 3 ≤ H < 4
(X,0,C) nếu 4 ≤ H < 5
(C, 0,X) nếu 5 ≤ H < 6

3. Điều chỉnh độ sang và độ tương phản trong ảnh
Một ảnh số được lưu trữ trên máy tính là một ma trận các điểm ảnh (hay
pixel). Trong OpenCV nó được biểu diễn dưới dạng cv::Mat. Ta xét một kiểu ảnh
thơng thường nhất, đó là ảnh RGB. Với ảnh này, mỗi pixel ảnh quan sát được là sự
kết hợp của các thành phần màu R (Red), Green (Green) và Blue (Blue). Sự kết hợp
này theo những tỉ lệ R, G, B khác nhau sẽ tạo ra vô số các màu sắc khác nhau. Giả
sử ảnh được mã hóa bằng 8 bit với từng kênh màu, khi đó mỗi giá trị của R, G, B sẽ
nằm trong khoảng [0, 255]. Như vậy ta có thể biểu diễn tới 255*255*255 ~ 1.6
triệu màu sắc từ ba màu cơ bản trên. Ta có thể xem cách biểu diễn ảnh trong
OpenCV qua hình ảnh sau:
Cột 0


Cột 1

Cột m

Hàng 0

0, 0

0, 0

0, 0

0, 1

0, 1

0, 1

0, m

0, m

0, m

Hàng 1

1, 0

1, 0


1, 0

1, 1

1, 1

1, 1

1, m

1, m

1, m

Hàng 2

2, 0

2, 0

2, 0

2, 1

2, 1

2, 1

2, m


2, m

2, m

Hàng n

n, 0

n, 0

n, 0

N, 1

n, 1

n, 1

n, m

n, m

n, m

Như vậy, mỗi ảnh sẽ có n hàng và m cột, m gọi là chiều dài của ảnh (width) và
n gọi là chiều cao của ảnh (heigh). Mỗi pixel ở vị trí (i,j) trong ảnh sẽ tương ứng
với 3 kênh màu kết hợp trong nó.
Trong đó, i ,j là pixel ở hàng thứ i và cột thứ j, img là ảnh mà ta cần truy xuất
tới các pixel của nó. cv::Vec3b là kiểu vector uchar 3 thành phần, dung để biểu thị



3 kênh màu tương ứng. k là kênh màu thứ k, k = 0, 1, 2 tương ứng với kênh màu B,
G, R. Chú ý là trong OpenCV, hệ màu RGB được biểu diễn theo thứ tự chữ cái là
BGR.
Sau đây ta sẽ áp dụng kiến thức trên để làm tăng, giảm độ sang và tương phản
của một ảnh màu, việc làm này cũng hoàn toàn tương tự đối với ảnh xám, chỉ khác
biệt là ảnh ta dung một kênh duy nhất để biểu diễn ảnh xám.
4. Ảnh nhị phân, nhị phân hóa với ngưỡng động
Ảnh nhị phân là ảnh mà giá trị của các điểm ảnh chỉ được biểu diễn bằng hai
giá trị 0 hoặc 255 tương ứng với hai màu đen hoặc trắng. Nhị phân hóa một ảnh là
quá trình biến một ảnh xám thành ảnh nhị phân. Gọi f(x,y) là giá trị cường độ sáng
của một điểm ảnh ở vị trí (x,y), T là ngưỡng nhị nhị phân. Khi đó, ảnh xám f sẽ
được chuyển thành ảnh nhị phân dựa vào công thức f(x,y) = 0 nếu f(x,y) ≤ T và
f(x,y) = 255 nếu f(x,y) > T
Hình sau mô tả một ảnh nhị phân với ngưỡng nhị phân T = 100

Ảnh xám

Ảnh nhị phân

Hàm để chuyển nhị phân hóa ảnh trong OpenCV là hàm threshold(). Nguyên mẫu
hàm như sau:
threshold(cv::InputArray src, cv::OutputArray dst, double thresh, int maxval, int
type) Trong đó, src là ảnh đầu vào một kênh màu (ảnh xám …), dst là ảnh sau
khi được nhị phân hóa, thresh là ngưỡng nhị phân, maxval là giá trị lớn nhất
trong ảnh maxval = 255 đối với ảnh xám), type là kiểu nhị phân có thể là


CV_THRESH_BINARY, CV_THRESH_BINARY_INV, CV_THRESH_OTS lần

lượt là nhị phân hóa thơng thường, nhị phân hóa ngược và nhị phân hóa theo
thuật tốn Otsu…
Kết quả của việc nhị phân hóa một ảnh phụ thuộc vào ngưỡng T, có nghĩa là với
mỗingưỡng T khác nhau thì ta có những ảnh nhị phân khác nhau. Hình sau mơ tả 3
ảnh nhị phân tương ứng với ngưỡng T = 50, T = 100 và T = 150.

T = 50

T = 100

T = 150

Để thu được một ảnh nhị phân tốt mà không cần phải quan tâm tới các điều
kiện ánh sáng khác nhau (không cần quan tâm tới ngưỡng T), người ta dùng một kĩ
thuật sao cho với mọi ngưỡng xám khác nhau ta luôn thu được một ảnh nhi phân
tốt. Kĩ thuật đó gọi là kĩ thuật nhị phân hóa với ngưỡng động (Dymamic threshold)
hay nhị phân thích nghi (Adaptive threshold)
Có nhiều phương pháp khác khác nhau để thực hiện việc này, tuy nhiên chúng
đều dựa trên ý tưởng chính là chia ảnh ra thành những vùng nhỏ, với mỗi vùng áp

dụng việc nhị phân cho vùng đó với những ngưỡng nhị phân khác nhau. Các
ngưỡng nhị phân ở các vùng được tính tốn dựa trên độ lớn mức xám của chính các
pixel trên vùng đó. Giả sử ta tính tốn ngưỡng cho một vùng nào đó dựa trên độ


trung bình của các pixel trong vùng đó (ta có thể xem một vùng là một cửa sổ). Ta
xét quá trình nhị phân với ngưỡng động trong một vùng cửa sổ 5x5:
Vùng ảnh nhị phân thu được ở trên là vùng ảnh được nhị phân với ngưỡng là
trung bình cộng của tất cả các ô trong cửa sổ T = (55 + 10 + 100 + …)/25 = 65,6.
5. Histogram, cân bằng histogram trong ảnh

Histogram của một ảnh là một biểu đồ nói
lên mối quan hệ giữa các giá trị của pixel ảnh
(điểm ảnh) và tần suất xuất hiện của chúng.
Nhìn vào biểu đồ histogram ta có thể đốn
được một ảnh sáng tối như thế nào.
Nếu một ảnh có histogram lệch về phía
phải biểu đồ, ta nói ảnh đó thừa sáng. Nếu lệch
về phía trái thì ảnh đó thiếu sáng. Hình bên mơ
tả histogram của một ảnh xám, ảnh này có
histogram lệch về phía trái của biểu đồ và do
đó ảnh này là khá tối. Đối với ảnh màu, ta có
thể tính tốn histogram cho từng kênh màu
một.
Cân bằng histogram
Cân bằng histogram (histogram equalization)
là phương pháp làm cho biểu đồ histogram của
ảnh được phân bố một cách đồng đều. Đây là một
biến đổi khá quan trọng giúp nâng cao chất lượng
ảnh, thông thường đây là bước tiền xử lý của một
ảnh đầu vào cho các bước tiếp theo.
6. Phóng to, thu nhỏ và xoay ảnh
Như đã nói ở trên, ảnh số thực chất là một ma trận các điểm ảnh, do đó để có
thể phóng to, thu nhỏ hay xoay một tấm ảnh ta có thể sử dụng các thuật toán tương
ứng trên ma trận.
7. Lọc số trong ảnh
Lọc số trong ảnh có ý nghĩa quan trọng trong việc tạo ra các hiệu ứng trong
ảnh, một số hiệu ứng nhờ sử dụng các bộ lọc như làm mờ ảnh(Blur), làm trơn


ảnh(Smooth) … Nguyên tắc chung của phương pháp lọc ảnh là cho ảnh nhân chập

với một ma trận lọc,
Idst = M*Isrc
Isrc, Idst là ảnh gốc và ảnh sau khi thực hiện phép lọc ảnh bằng cách nhân với
ma trận lọc
M. Ma trận M đơi khi cịn gọi là mặt nạ (mask), nhân (kernel). Với mỗi phép
lọc ta có những ma trận lọc M khác nhau, khơng có quy định cụ thể nào cho việc
xác định M, tuy nhiên ma trận này có một số đặc điểm như sau:
Kích thước của ma trận thường là một số lẻ chẳng hạn 3x3, 5x5 … Khi đó,
tâm của ma trận sẽ nằm ở giao của hai đường chéo và là điểm áp đặt lên ảnh mà ta
cần tính nhân chập.
Tổng các phần tử trong ma trận thông thường bằng 1. Nếu tổng này lớn hơn 1,
ảnh qua phép lọc sẽ có độ sáng lớn hơn ảnh ban đầu. Ngược lại ảnh thu được sẽ tối
hơn ảnh ban đầu.
Trong đó, ta đang tính phép nhân chập cho điểm ảnh có tọa độ (x,y) và vì ta
lấy tâm của ma trận lọc là điểm gốc nên u chạy từ -n (điểm bên trái) và v chạy từ -n
(điểm phía trên) đến n, với n = (kích thước mặt nạ - 1)/2. Để dễ hiểu hơn ta xét một
ví dụ về việc làm trơn nhờ sử dụng một ma trận lọc như sau:

100 100 100 100 100
Nhân chập pixel100
(2,2) 100 100
Nhân chập
Nhânpixel
chập (2,3)

100 100

1/9 1/9 1/9

100 200 205 203 100


100 144 205

203 100

1/9 1/9 1/9

100 195 200 200 100
Group Box
100 200 205 195 100
Picture
100 100 100 100 100
control
Label

100 195 200

200 100

100 200 205

195 100

100 100 100

100 100

1/9 1/9 1/9

Button


*
= ==**


100 100 100 100 100

100

100 100

100 100

1/9 1/9 1/9

100 200 205 203 100

100

144 167

203 100

1/9 1/9 1/9

100 195 200 200 100

100

195 200


200 100

1/9 1/9 1/9

100

200 205 195 100

100

200 205

195 100

100

100 100 100 100

100

100 100

100 100

Và kết quả cuối cùng ta có:
100 100 100 100 100

100 100 100 100 100


1/9 1/9 1/9

100 200 205 203 100

100 144 167 145 100

1/9 1/9 1/9

100 195 200 200 100

100 167 200 168 100

1/9 1/9 1/9

100 200 205 195 100

100 144 166 144 100

100 100 100 100 100

100 100 100 100 100

Ta thấy rằng, ảnh ban đầu với là ảnh có độ tương phản khá lớn (các giá trị độ
lớn pixel chênh lệch lớn: 100, 200, …), sau phép lọc ảnh có độ tương phản giản đi
hay bị làm mờ đi(lúc này độ chênh lệch giá trị giữa các pixel giảm đi: 100, 144,
167 …). Sau đây ta sẽ xem xét một số bộ lọc trong OpenCV.


Chương III: Lập trình xử lý ảnh với giao diện MFC
1. Giới thiệu về MFC

MFC (Microsoft Foundation Classes) là bộ thư viện được Microsoft phát triển
phục vụ cho việc lập trình trên Window. Bản chất của thư viện này là cung cấp cho
ta các lớp, các công để làm việc với các hàm API của Window, do vậy việc lập trình
trở nên đơn giản hơn rất nhiều.
Trong phần này và phần sau, các ví dụ và ứng dụng sẽ được tạo ra nhờ vào
giao diện Dialog của MFC. Việc nghiên cứu một cách đầy đủ và bài bản về MFC là
một việc cần đầu tư về thời gian và công sức. Trong khuôn khổ cuốn sách này, ta
chỉ đi xem xét một phần nhỏ và các thủ thuật để làm việc nhanh nhất được với
MFC.
2. Khởi tạo project MFC
Khởi động Visual Studio, từ menu chọn File -> New - > Project (hoặc nhấn
Ctrl + Shift + N). Hộp thoại New Project hiện ra, họn Visual C++ (có thể sẽ phải
chọn mục Other langguge trước khi hiển ra Visual C++) sau đó chọn MFC
Application. Ta đặt tên cho project trong trường Name (giả sử tên là xyz) sau đó
click OK để đến bước tiếp theo. Ở bước tiếp theo, tiếp tục chọn Next ta được hộp
thoại sau


Application type chọn Dialog based, Project type chọn MFC standard… Chú ý
rằng việc tick vào chọn Use Unicode libraries sẽ có những ý nghĩa và cách dùng
khác nhau, ta sẽ xét trường hợp này sau. Ta nhấn next để đi tới hộp thoại tiếp theo,
hộp thoại này cho phép ta tùy chỉnh một số chức năng của cửa sổ như có thêm nút
phóng to, thu nhỏ, menu… có thể để mặc định và chọn next


Ta nhấn Next để đi tới tùy chỉnh tiếp một số tùy chọn nâng cao, nếu chưa hiểu
rõ ta có thể để mặc định và nhấn Next. Hộp thoại cuối cùng xuất hiện yêu cầu ta
chọn để MFC khởi tạo lớp. Ta chọn là CxyzDlg và nhấn Finish

Đến đây ta đã khởi tạo xong một project MFC có dựa trên nền Dialog, Dialog

hiện ra mặc đinh có một button OK, button Cancel và một label, ta có thể để sử
dụng hoặc xóa đi và thiết kế theo ý riêng của mình.
3. Làm việc với các điều khiển (Control) của MFC
Đặt tên biến cho các control
Khi muốn sử dụng một Control nào, ta
kéo control đó từ Toolbox và cho vào
dialog. Để làm việc với các control một
cách dễ dàng, ta nê đặt tên biến cho các
control.
Để đặt tên biến cho một control, ta
click chuột phải vào control, sau đó chọn
Add Variable. Một hộp thoại Add Member


Variable Wizard hiện ra và trong mục variable name ta đặt tên cho control đó. Chú
ý là đối với các control mà ID của nó có dạng IDC_STATIC (như Static Text) thì ta
chỉ có thể đặt tên biến được khi đổi
ID của nó, chẳng hạn như đổi thành IDC_STATIC1, IDC_LABEL …

Ta có thể tùy chỉnh để trình dịch build theo chế độ Unicode hoặc Multibyte bằng cách vào Project -> Properties (hoặc nhấn Alt + F7), hộp thoại
Properties hiện ra, chọn Configuration Properties -> General và tùy chỉnh ở
mục Character Set.
Lấy giá trị lựa chọn từ Combo Box
Combo box cho phép ta lựa chọn,
chuyển đổi giữa các lựa chọn một cách nhanh
chóng. Để thêm các lựa chọn vào Combo Box
ta có thể điển trực tiếp vào mục Data trong
properties của nó. Để xem lựa chọn nào đang
được chọn, ta dùng hàm GetCurSel().
Dialog mở file và lưu file

Mục đích của loại dialog này là tạo ra
một hộp thoại cho phép người dùng chọn đến
đường dẫn để mở file và lưu file. Kết quả cuối
cùng mà ta quan tâm nhất là lấy được đường
dẫn mà người dùng lựa chọn.


Filter sẽ lọc và chỉ hiển thị những file tương ứng mà ta cần quan tâm, trong
trường hợp trên ta đang xét mở hoặc lưu một file ảnh do đó ta để file mở rộng là
bmp hoặc jpg. Nếu muốn hiển thị tất cả các loại file ta chỉ việc để filter là *.*, hộp
thoại mở file và lưu file chỉ khác nhau ở thông số đầu tiên khi tạo đối tượng dlg,
nếu là mở file ta đặt là TRUE, lưu file ta đặt là FALSE.
Xử lý sự kiện khi click chuột vào button
Hầu hết các control trong MFC đều có một hoặc nhiều sự kiện khi người dùng
tương tác với nó, chẳng hạn sự kiện click chuột vào button, sự kiện kéo thanh trượt
của slider control … Để xử lý các sự kiện cho các control, trong mục properties của
control tương ứng ta chọn vào icon sự kiện sau đó chọn các sựkiện cần xử lý.
Thêm menu vào chương trình, xử lý sự kiện khi click vào menu
Menu trong MFC được xem là resource của chương trình. Việc thêm menu
vào dialog địi hỏi ta phải thêm nó vào resource
của chương trình. Trước hết ta hiển thị cửa sổ
xem các resource của chương trình bằng cách từ
menu của Visual Studio chọn View -> Resource
View (hoặc nhận tổ hợp phìm Ctrl + Shift + E).
Cửa sổ Resource View hiện ra, ta click chuột
phải vào đó, chọn Add->Resource… Cửa sổ
Add Resource hiện ra, ta chọn Menu và click
vào button New. Ngay sau đó ta sẽ có một resource chứa menu chống, ta tiến hành
điền tên các menu mà ta muốn chương trình thực hiện. Hình bên ta điền 3 menu
chưc năng nhỏ là Open, Save và Exit… Khi đã tạo xong menu, nó vẫn chỉ nằm ở

trong resource của chương trình, muốn menu này được gắn vào dialog khi chạy, ta
vào properties của dilog, trong mục Menu chọn IDR_MENU1, với IDR_MENU1
chính là ID của menu ta vừa tạo ra.


Để xử lý sự kiện click chuột của menu nào, ta click chuột phải vào mune ấy và
chọn Add Event Handler…

Ở hộp thoại Event Handler Wizard ta chọn lớp mà ta muốn thêm menu vào
sau đó click vào button Add and Edit để đi tới hàm xử lý sự kiện khi click vào
menu, ví dụ sau là ta gọi hàm OnCancel() để thốt khỏi chương trình
Ngồi một số điều khiển thơng dụng đã nhắc tới ở trên, MFC cịn cung cấp rất
nhiều các điều khiển khác giúp cho việc tạo ra giao diện một cách dễ dàng và đẹp
mắt hơn. Bạn đọc tham khảo thêm các tài liệu khác về phần này.
4. Chuyển đổi các kiểu dữ liệu trong MFC
Các kiểu dữ liệu của MFC về cơ bản là giống với các kiểu dữ liệu trong C, tuy
nhiên có một số trường hợp ta phải chuyển đổi qua lại giữa các kiểu dữ liệu để phù
hợp với đầu vào, đầu ra của một việc nào đó, chẳng hạn khi ta dùng CFileDialog để
mở một đường dẫn sau đó đọc ảnh từ đường dẫn này, kết quả trả về đường dẫn của
CFileDialog là một chuỗi CString tuy nhiên hàm cv::imread lại đọc ảnh từ một
chuỗi string, do đó ta phải chuyển đổi từ CString sang string. Một số chuyển đổi
sau đây là hữu ích cho việc hiển thị giao diện, và lấy dữ liệu từ giao diện người
dùng.


5. Chương trình tải ảnh và hiển thị ảnh trên giao diện MFC
Ta tạo một mới một project, đặt tên project là HienThiThongTinAnh và thiết
kế giao diện như hình sau:
Trong hàm trên, đầu tiên ta kiểm tra xem ảnh đã được tải ở bước trên hay
chưa, nếu chưa thì hiện ra thông báo chưa tải được ảnh, nếu đã tải được ảnh rồi thì

tính tốn chiều dài, chiều rộng, kênh màu của ảnh … sau đó hiển thị thơng tin này
lên các label tương ứng. Để hiện lên label hoặc bất kì một điều khiển nào của MFC
ta dùng thuộc tính
SetWindowText(). Tuy nhiên đối số đầu vào của hàm này lại có định dạng
CString, do vậy các giá trị như int, float, double .. muốn hiển thị được trên các điều
khiển của MFC ta phải chuyển đổi kiểu dữ liệu như đã nói ở trên.
Ở button Thoat, khi click vào vào chương trình sẽ thốt ra, việc thốt khỏi
chương trình là rất đơn giản, có thể đạt được bằng cách gọi hàm OnCancel().


Kết quả chạy chương trình như sau:hoặc hơn nữa) thì ta cần phải tối ưu hóa
phép xử lý tới mức có thể để video có thể chạy được trong thời gian thực (khơng bị
giật cục, tắc hình).
Thư viện OpenCV đối với xử lý video. Thư viện OpenCV chỉ hỗ trợ ta các
hàm để bắt ảnh từ một thiết bị như webcam, camera…, ghi các frame ảnh thành file
video, còn việc làm xử lý video ta có thể sử dụng các hàm xử lý ảnh mà thư viện
cung cấp để xử lý các frame video. Tuy nhiên, thư viện OpenCV là một thư viện
chuyên về xử lý ảnh, nên nó chỉ hỗ trợ track video trong cấu trúc của file video nói
trên, nghĩa là khi thu video, ghi video ta chỉ có phẩn hình (video stream) mà khơng
thể nghe được phần tiếng. Một hạn chế nữa là ban đầu OpenCV chỉ hỗ trợ để làm
việc trên các video avi không nén, điều đó sẽ làm cho việc kích thước của việc lưu
trữ file tăng lên rất nhiều, giả sử ta cần ghi một đoạn video avi không nén trong thời
gian là một phút với tốc độ là 25 hình/giây và ảnh thu từ webcam có kích thức
640x480 (ảnh màu, mỗi kênh màu của một pixel là 8 bit) khi đó kích thước của một
file cần phải có là 1*60*25*640*480*3*8 = 11059200000 bit tức khoảng 1Gb. Tuy
nhiên, hiện tại ta có thể làm việc được trên nhiều dạng file avi nén, file mpeg, flv…
miễn máy có cài các bộ codec tương ứng.


Tạo chương trình MyCam

Chương trình được tạo ra dựa trên nền Dialog của MFC, cùng các hàm xử lý
ảnh trong OpenCV đã biết như trên. Ta chia chương trình làm hai phần, một phần
chứa các hàm xử lý ảnh và một phần thuộc về giao diện MFC. Phần chứa các hàm
xử lý ảnh được đặt tên là lớp MyCamCore, nó bao gồm một file header định nghĩa
giao diện hàm mycamcore.h và một file cài đặt mycamcore.cpp. Cấu trúc của hai
file này có dạng như sau:
Mycamcore.h:
#pragma once
#include <opencv2\core\core.hpp>
class MyCamCore
{
public:
MyCamCore(void);
~MyCamCore(void);
void Gray(cv::Mat&, cv::Mat&);
void
Invert(cv::Mat&,
cv::Mat&);
void
ToHSV(cv::Mat&,
cv::Mat&);
void
Blur(cv::Mat&,
cv::Mat&);


};
Và mycamcore.cpp:
#include "MyCamCore.h"
#include

<opencv2\core\core.hpp>
#include


×