Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV - Pdf 29

Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 1
Ứng dụng xử lý ảnh trong thực thế với thư
viện OpenCV C/C++
Nguyễn Văn Long

Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 2
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 toá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à

ứng dụng thương mại của các k
ĩ sư, doanh nghi
ệp và những người quan tâm tới l
ĩnh v
ực.
Cuối cùng dù đã dành nhiều tâm huyết để hoàn thành cuốn sách nhưng chắc chắn cuốn
sách vẫn còn nhiều sai xót, tác giả mong được sự góp ý của bạn đọc. Xin gửi lời chúc tốt
tốt đẹp và lời cảm ơn sâu sắc tới độc giả
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 3
Hướng dẫn sử dụng sách
Cuốn sách được viết dựa trên những nghiên cứu và quá trình làm việc thực tế của tác giả,
với mỗi vấn đề nêu trong sách bạn đọc có thể đọc qua để nắm bắt được ý t
ư
ởng chính, sau
đó có thể tìm thêm tài liệu để nâng cao hơn vấn đề và có thể thực hành dựa vào mẫu
chương tr
ình, source code
đi
kèm.
Thư viện OpenCV được viết trong sách là bản OpenCV 2.4.3, đối với các bản OpenCV
khác thì bạn đọc 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 trong cuốn sách này đề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.
Có 10 chủ đề chính bao quát một số khía cạnh của l
ĩnh
vực xử lý ảnh được viết khá chi

4. Ảnh nhị phân, nhị phân hóa với ngưỡng động 19
5. Histogram, cân bằng histogram 23
6. Phóng to, thu nhỏ, xoay ảnh 27
7. Lọc số trong ảnh 30
8. Các phép toán hình thái học trong ảnh 37
9. Tìm biên ảnh với bộ lọc Canny 43
10.Chuyển đổi Hough, Phát hiện đường thẳng, đường tròn trong ảnh 46
Chương III. Lập trình xử lý ảnh với giao diện MFC
1. Giới thiệu về MFC 51
2. Khởi tạo project MFC 51
3. Làm việc với các điều khiển (Control) 54
4. Chuyển đổi các kiểu dữ liệu trong MFC 59
5. Chương tr
ình t
ải ảnh và hiển thị ảnh lên giao diện MFC 61
Chương IV. Một số ứng dụng trong thực tế
1. My Photo Editor, phần mềm chỉnh sửa ảnh đơn giản 64
2. Nhận dạng biển số xe 73
3. MyCam, một số hiệu ứng ảnh trong video 90
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 5
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

ợ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.
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 6
- 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 đ

- Thư viện OpenCV 1.x tuy chứa một lượng lớn hàm xử lý và thuật toá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.
3. Hướng dẫn sử dụng thư viện OpenCV trên Window
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 7
Trước hết ta cần download thư viện OpenCV về máy tính, tốt hơn là luôn download bản
mới nhất tại địa chỉ . Chọn bản đ
ã build s
ẵn
phù hợp với hệ điều hành đang dùng, bản OpenCV được sử dụng trong cuốn sách này là
bản 2.4.3 với lần update cuối cùng là vào ngày 25 tháng 12 năm 2012. Sau khi download
về máy, tiến hành cài đặt bình th
ư
ờng, ta để mặc định thư mục cài đặt là C:\ thư mục cài
đặt xong sẽ có dạng C:\opencv. Tiếp theo ta sẽ tiến hành tùy chỉnh để có thể làm việc với
OpenCV qua hai IDE thông dụng là Microsoft Visual Studio và Eclipse CDT
Trên Microsoft Visual Studio
Phiên bản Visual studio sử dụng ở đây là phiên bản Visual Studio 2010, các phiên bản

VC++ Directories, tương ứng bên phải, ta tìm mục Include Directories và Library
Directories. Ta sẽ chỉ đường dẫn hai thư mục này đến các phần tương ứng của thư viện
OpenCV.
Mục Include Directories, ta tùy chỉnh ở ô bên phải tới C:\opencv\build\include
Mục Library Directories trỏ đến thư mục C:\opencv\build\x86\vc10\lib nếu như ta sử
dụng hệ điều hành 32bit hoặc C:\opencv\build\x64\vc10\lib cho hệ điều hành 64bit.
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 9
Tiếp theo, trong hộp thoại opencv Property Pages -> Configuration Properties -> Linker
chọn Input, tương ứng ở ô bên phải, thêm vào các giá trị cho mục Additional
Dependencies là opencv_core243d.lib, opencv_imgproc243d.lib, opencv_highgui243d.lib.
Chú ý là
các lib thêm vào sẽ tương ứng với các
header ta khai báo trong chương tr
ình, và
tùy thuộc vào mục đích sử dụng mà ta có
thể thêm vào các lib các nhau, giả sử ta cần
sử dụng tới các hàm về video, khi đó ta
thêm header #include
<opencv2/video/video.hpp> thì trong phần
Additional Dependencies ta phải khai báo
thêm opencv_video243d.lib. Chữ d đứng
cuối các file trên thể hiện ta đang hoạt
động ở chế độ debug, ta có thể thêm các lib
không có chữ “d” ở cuối như
opencv_core243.lib … trong chế độ
release. Tuy nhiên khi đang c
òn h
ọc tập và cần nhiều chỉnh sửa ta nên để ở chế độ debug.

}
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 10
Với Eclipse CDT
Khởi động Eclipse, Từ cửa sổ Eclipse chọn New -> C++ Project , hộp thoại C++ Project
xuất hiện, trong hộp thoại ta chọn Project name là opencv, Project type là Hello World
C++ Project (Có thể chọn là Empty
Project), Toolchains là MinGW GCC,
Chọn Finish và ta có một Project mới.
Bây giờ tùy chỉnh cho project này hoạt
động được với OpenCV.
Trong cửa sổ của Eclipse chọn Project -
>Properties, cửa sổ Properties hiện ra.
Tron cửa sổ Properties chọn C/C++
Build->Settings. Trong tab Tool Settings.
Ở phần GCC C++ Compiller chọn
Include rồi dẫn đường dẫn tới mục
Include của OpenCV
là C:\opencv\build\include. Trong phần
MinGW C++ Linker chọn Library và
chọn các mục như sau: click vào dấu
cộng ở Library search path (-L) và dẫn
tới thư mục
lib: C:\opencv\build\x86\mingw\lib đối
với Windows 32 bit hoặc
C:\opencv\build\x64\mingw\lib đối với
Windows 64 bit. Tiếp đó click vào dấu "cộng" để thêm Library(-I) vào, các library cần
thêm lần lượt là: opencv_core243, opencv_highgui243, opencv_imgproc243 nói chung
là tùy vào nhu cầu sử dụng có thể thêm một hoặc nhiều lib vào.

{
cout<<"Chuong trinh dau tien"<<endl;
Mat img = imread("vietnam.jpg", CV_LOAD_IMAGE_COLOR);
namedWindow("Viet Nam", CV_WINDOW_AUTOSIZE);
imshow("Viet Nam", img);
waitKey(0);
return 0;
}
Như đ
ã nói
ở trên, trong Opencv với giao diện C++, tất cả các kiểu dữ liệu ảnh, ma trận
điều được lưu ở dạng cv::Mat. Hàm imread sẽ đọc ảnh đầu vào và lưu vào biến img.
Nguyên mẫu của hàm này như sau: cv::Mat imread(const std::string &filename, int flags)
trong đó, filename là đường dẫn tới file ảnh, nếu file ảnh không nằm trong thư mục làm
việc hiện hành thì ta phải chỉ ra đường dẫn tương đối dạng như D:\Anh\vietnam.jpg hoặc
D://Anh//Vietnam.jpg. Flags là tham số loại ảnh mà ta muốn load vào, cụ thể nếu nếu
muốn load ảnh mầu thì ta để CV_LOAD_IMAGE_COLOR, nếu là ảnh xám thì ta để
CV_LOAD_IMAGE_GRAYSCALE…
Sau khi đ
ã load
ảnh thành công, muốn hiển thị ảnh lên màn hình ta phải tạo ra một cửa sổ,
hàm namedWindow(const std::string &winname, int flags) sẽ tạo ra cửa sổ với tiêu đề cửa
sổ là một chuỗi string winname. Tham số flags sẽ chỉ ra kiểu cửa sổ muốn tạo: nếu tham
số CV_WINDOW_AUTOSIZE được sử dụng thì kích cỡ cửa sổ tạo ra sẽ được hiển thị
một cách tự động tùy thuộc vào kích thước của ảnh, nếu là tham số
CV_WINDOW_AUTOSIZE_FULLSCREEN kích thước cửa sổ sẽ khít với màn hình máy
tính …
Cuối cùng, hàm imshow(const std::string &winname, cv::InputArray Mat) sẽ hiển thị ảnh
ra cửa sổ đ
ã đư

khác.
Nếu như một ảnh số được mã hóa bằng 24bit, ngh
ĩa l
à 8bit cho kênh R, 8bi
t 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.
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 14
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 toà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.
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

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 toà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.
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

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.
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

ề 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.
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 = 0
0
V = M.

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.
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 = 0
0
V = M.
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 15
đi theo v
òng tròn t

ế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.
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 = 0
0
V = M.
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 16
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

0, ,
)
ế 2 ≤ <3
(
0, ,
)
ế 3≤ <4
(
,0,
)
ế 4 ≤ <5
,0, ) ế 5 ≤ <6
Chương tr
ình chuy
ển đổi các không gian màu
Trong OpenCV, các không gian màu được được chuyển đổi qua lại nhờ hàm cvtColor
(convert color), nguyên mẫu hàm này như sau:
cv::cvtColor(cv::InputArray src, cv::OutputArray dst, int code)
Trong đó, src, dst là ảnh gốc và ảnh thu được sau khi chuyển đổi không gian màu. code
mà mã chuyển đổi không gian màu. OpenCV định ngh
ĩa khá nhi
ều chuyển đổi giữa các
không gian màu chẳng hạn như code = CV_BGR2GRAY sẽ chuyển ảnh ở không gian màu
RGB sang ảnh xám, code = CV_HSV2BGR sẽ chuyển ảnh ở không gian màu HSV sang
không gian màu RGB …
#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;

Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 18
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

dung một kênh duy nhất để biểu diễn ảnh xám.
Chương tr
ình t
ăng, gi
ảm độ sáng và độ tương phản của một ảnh
Giả sử f là một hàm biểu diễn cho một ảnh nào đó, f(x,y) là giá trị của pixel trong ảnh ở vị
trí (x,y). Đặt g(x,y) = αf(x,y) + β. Khi đó, nếu α ≠ 1, th
ì ta nói
ảnh g(x,y) có độ tương phản
gấp α lần so với ảnh f(x,y). Nếu β ≠ 0ta n
ói đ
ộ sáng của ảnh g(x,y) đ
ã thay
đ
ổi một lượng

β. D
ựa vào công thức trên ta có chương tr
ình thay
đ
ổi độ sáng và tương phản của ảnh
như sau:
#include "stdafx.h"
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;
int main()
{

β = 30
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
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 20
Ả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_OTSU… 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 toá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ỗi
ngưỡ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

using namespace cv;
int main()
{
cout<<"Nhi phan anh voi nguong dong"<<endl;
Mat src = imread("Thap_But.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat dst;
adaptiveThreshold(src, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C,
CV_THRESH_BINARY, 35, 5);
imshow("Anh xam goc", src);
imshow("Anh nhi phan voi nguong dong", dst);
waitKey(0);
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 21
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 toá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 toá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.
Chương trình nhị phân hóa với ngưỡng động như sau
// Adaptive Threshold
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>

// Adaptive Threshold
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
cout<<"Nhi phan anh voi nguong dong"<<endl;
Mat src = imread("Thap_But.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat dst;
adaptiveThreshold(src, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C,
CV_THRESH_BINARY, 35, 5);
imshow("Anh xam goc", src);
imshow("Anh nhi phan voi nguong dong", dst);
waitKey(0);
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 22
return 1;
}
Trong chương tr
ình trên, hàm th
ực hiện việc nhị phân hóa với ảnh động là hàm
adaptiveThreshold, Nguyên mẫu của hàm như xau:
cv::adaptiveThreshold(cv::InputArray src, OutputArray dst, double maxValue,
int adaptiveMethod, int thresholdType, int blockSize, double C)
Trong đó, src là ảnh xám cần nhị phân, dst là ảnh kết quả thu được, maxValue là giá trị
lớn nhất trong ảnh xám (thông thường là 255), adaptiveMethod là cách thức nhị phân với

#include <iostream>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
std::cout<<"Tim histogram anh mau"<<std::endl;
Mat src = imread("buoi.jpg");
vector<Mat> img_rgb;
Mat img_r, img_g, img_b;
int w = 400, h = 400;
int size_hist = 255;
float range[] = {0, 255};
const float* hist_range = {range};
split(src, img_rgb);
calcHist(&img_rgb[0], 1, 0, Mat(), img_b, 1, &size_hist, &hist_range, true, false);
calcHist(&img_rgb[1], 1, 0, Mat(), img_g, 1, &size_hist, &hist_range, true, false);
calcHist(&img_rgb[2], 1, 0, Mat(), img_r, 1, &size_hist, &hist_range, true, false);
int bin = cvRound((double)w/size_hist);
Mat disp_r(w, h, CV_8UC3, Scalar( 255,255,255) );
Mat disp_g = disp_r.clone();
Mat disp_b = disp_r.clone();
normalize(img_b, img_r, 0, disp_b.rows, NORM_MINMAX, -1, Mat() );
normalize(img_g, img_g, 0, disp_g.rows, NORM_MINMAX, -1, Mat() );
normalize(img_r, img_b, 0, disp_r.rows, NORM_MINMAX, -1, Mat() );
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 24
for( int i = 1; i < 255; i++ )

histogram, bản OpenCV hiện tại hỗ trợ tính toán histogram với số chiều lên tới 32.
histSize là kích thước dãy histogram mỗi chiều, hai tham số cuối có thể để mặc định,
Sau đây là kết quả chương tr
ình
Nguyễn Văn Long
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV
Tác giả: Nguyễn Văn Long – Page 25
Đối với ảnh xám, ta có thể xem như nó là một kênh màu, do vậy để tính histogram của
ảnh xám ta cũng có thể làm hoàn toàn tương tự bằng cách gọi hàm caclHist()
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.
Để cân bằng histogram, ta dung hàm
equalizeHist(cv::InputArray src, cv::OuputArray dst)
trong đó, src là ảnh đầu vào một kênh màu (ảnh xám
chẳn hạn), dst là ảnh sau khi cân bằng. Ví dụ:
Mat src = imread("src.jpeg", CV_LOAD_IMAGE_GRAYSCALE); // Load anh xam
imshow("Anh xam goc", src);
Mat dst;
equalizeHist(src, dst);
imshow("anh xam sau khi can bang histogram", dst);
Ta có kết quả sau:


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status