Giáo trình Ứng dụng xử lý ảnh trong thực thế với thư viện OpenCV C/C++

Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
Ứng dụng xử lý ảnh trong thực thế với thư  
viện OpenCV C/C++  
Nguyễn Văn Long  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 1  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
Mở đầu  
ĩnh v  
Xử lý ảnh và thị giác máy là l  
ự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.  
ư
ã b  
Ở Việt Nam, các ứng dụng về xử ảnh đ  
ĩnh v  
ớc đầu được triển khai trên một số l  
ự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à  
ĩnh v  
quá ít ỏi, l  
ự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 toán học, sinh viên nắm  
bắt môn học một cách chung chung mà không đi vào bản chất vấn đề, ứng dụng thực tiễn  
của mô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  
ã c  
nhiều, bằng quá trình nghiên cứu nghiêm túc, kinh nghiệm thực tế tác giả đ ố gắng cho  
ra đời cuốn sách Ứng dụng xử lý ảnh trong thưc tế với thư viện OpenCV.  
Cuốn đề 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, không xa vào những công thức toán học trừu tượng, phức tạp nhưng vẫn  
làm nổi bật nên được vấn đề, giúp người đọc 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ủ  
ình mô ph  
đề trong cuôn sách này đều đi kèm với một chương tr  
ỏ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.  
Cuốn sách đượ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 …  
Cuốn sách không chỉ là tài liệu tham khảo bổ ích trong quá trình học tập của các bạn sinh  
viên, quá trình làm luận văn, đồ án … mà còn là công cụ tốt hỗ trợ cho việc triển khai các  
ĩ sư, doanh nghi  
ứng dụng thương mại của các k  
ĩnh v  
ệp và những người quan tâm tới l  
ự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ả  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 2  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
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  
đi  
ình, source code  
chương tr  
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.  
ĩnh  
Có 10 chủ đề chính bao quát một số khía cạnh của l  
vực xử lý ảnh được viết khá chi  
tiết và giải thích đầy đủ, 3 project được tác giả mô tả chung chung hơn. Do đó bạn đọc  
nếu chưa thực sự quen với thư viện OpenCV nên đọc theo thứ tự từ đầu tới cuối  
ĩ thu  
Trong cuốn sách có nhiều vấn đề liên quan tới k  
ưng do ph  
ật lập trình nh  
ạm vi giới  
hạn, tác giả chỉ có thể nói qua được một số khía cạnh, trên thực tế có nhiều cách khác  
õ có th  
nhau để giải quyết cùng một công việc, với những vấn đề lập trình bạn đọc chưa r  
tham khảo thêm tài ở các nguồn khác nhau hoặc giải quyết theo hướng mà bạn đọc cảm  
thấy là thỏa đáng nhất  
ể
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 3  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
Mục Lục  
Chương I. Làm quen với thư viện OpenCV  
1. Giới thiệu về thư viện OpenCV  
2. Phiên bản OpenCV 1 hay OpenCV 2  
3. Hướng dẫn sử dụng OpenCV trên Window  
5
5
6
Chương II. Các phép xử lý đơn giản trong OpenCV  
đ
1. Chương trình ầu tiên  
12  
13  
17  
19  
23  
27  
30  
37  
43  
46  
2. Không gian màu, chuyển đổi không gian màu  
3. Điều chỉnh độ sang, độ tương phản  
4. Ảnh nhị phân, nhị phân hóa với ngưỡng động  
5. Histogram, cân bằng histogram  
6. Phóng to, thu nhỏ, xoay ảnh  
7. Lọc số trong ảnh  
8. Các phép toán hình thái học trong ảnh  
9. Tìm biên ảnh với bộ lọc Canny  
10. Chuyển đổi Hough, Phát hiện đường thẳng, đường tròn trong ảnh  
Chương III. Lập trình xử lý ảnh với giao diện MFC  
1. Giới thiệu về MFC  
2. Khởi tạo project MFC  
3. Làm việc với các điều khiển (Control)  
4. Chuyển đổi các kiểu dữ liệu trong MFC  
51  
51  
54  
59  
61  
ình t  
5. Chương tr  
ải ảnh và hiển thị ảnh lên giao diện MFC  
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  
2. Nhận dạng biển số xe  
3. MyCam, một số hiệu ứng ảnh trong video  
64  
73  
90  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 4  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
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  
đa lõi… đ  
mạnh của các dòng chip  
ể thực hiện các phép tính toá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.  
ện Open  
ầu được sự hỗ trợ từ Intel, sau đó được hỗ trợ bở Willow Garage  
CV ban đ  
Thư vi  
,
ột phòng thí nghiệm chuyên nghiên cứu về công nghệ robot.  
m
ến nay, OpenCV vẫn  
Cho đ  
ện mở, được phát triển bởi nguồn quỹ không lợi nhuận (none  
là thư vi  
-profit foundation)  
ợc sự hư  
và đư  
ởng ứng rất lớn của cộng đồng.  
2. Phiên bản OpenCV 1 hay OpenCV 2?  
ã có  
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ố, đ  
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  
ĩa là khi m  
tượng, ngh  
ộ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.  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 5  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
- 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. Chẳng hạn ta hãy  
xét ví dụ về việc phát hiện đường tròn trong ảnh mầu dựa vào thuật toán Hough,  
các bước để thực hiện là load một ảnh mầu, chuyển sang ảnh nhị phân, tìm biên  
dựa trên bộ lọc canny và phát hiện đường tròn dựa trên thuật toán Hough. OpenCV  
1.x thực hiện như sau:  
// Phát hiện đường tròn trong ảnh OpenCV 1.x  
IplImage*  
src = cvLoadImage(“image.jpg”);  
cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);  
IplImage* gray  
=
cvCvtColor(src, gray, CV_BGR2GRAY);  
cvCanny(gray, gray, 10, 30, 3);  
CvMemStorage* storage = cvCreateMemStorage(0);  
CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1,  
50, 100, 50);  
Trong khi đó, OpenCV 2.x thực hiện như sau:  
// Phát hiện đường tròn trong ảnh OpenCV 1.x  
Mat src = imread(“image.jpg”);  
Mat gray;  
CvtColor(src, gray, CV_BGR2GRAY);  
Canny(gray, gray, 10, 30, 3);  
Vector<Vec3f> circles;  
HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, 50, 100, 50);  
Ta thấy rằng đối tượng ảnh gray trong OpenCV 2.x không cần phải khởi tạo, đối  
ĩa v  
ũng  
tượng storage (đối tượng trung gian, không có ý ngh  
ề mặt sử dụng) c  
không cần phải khởi tạo (và do đó không cần giải phóng).  
- 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  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 6  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
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  
ã build s  
mới nhất tại địa chỉ http://sourceforge.net/projects/opencvlibrary/ . Chọn bản đ  
ẵ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  
trước ta hoàn toàn có thể cấu hình một cách tương tự.  
Tạo một project mới: New > Project, trong cửa sổ New Project chọn Visual C++, Win32  
console application. Đặt tên project là opencv  
Chọn OK, sau đó nhấn Next, hộp thoại tiếp theo xuất hiện, ở hộp thoại này ta chọn  
Application type là Console application và Additional option là Empty project, nhấn  
Finish để kết thúc quá trình khởi tạo  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 7  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
Project mới được tạo ra là project hoàn toàn trống, ta phải thêm vào đó ít nhất một file  
ình có th  
nguồn để chương tr  
ể chạy  
được, trong Solution Explorer ta  
click chuột phải vào Source Files,  
chọn Add -> New Item… Hộp thoại  
Add New Item hiện ra, ta chọn kiểu  
cần thêm vào là C++ File(.cpp) đồng  
thời trong ô Name ta đặt tên cho file  
thêm vào, giả sử là FirstApp.cpp.  
Bây giở trong file này ta có thể thêm  
vào các #include và gọi hàm main()  
ình.  
để chạy chương tr  
ình có th  
Để chương tr  
ể chạy được  
với thư viện OpenCV ta cần tùy chỉnh lại một sô thuộc tính của project như sau  
Vào Project -> Properties (hoặc nhấn tổ hợp phím Alt + F7) để mở hộp thoại Properties.  
Hộp thoại opencv Property Pages hiện ra, trong mục Configuration Properties chọ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.  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 8  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
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ế độ  
òn h  
release. Tuy nhiên khi đang c  
ọc tập và cần nhiều chỉnh sửa ta nên để ở chế độ debug.  
ình, đ  
Cuối cùng, khi dịch xong một chương tr  
ể nó có thể chạy được ta cần chú ý tới các  
file *.dll. Cách đơn giản nhất là ta copy các file *.dll tương ứng (như  
opencv_core243d.dll, opencv_imgproc243d.dll) vào thư mục chứa file chạy của chương  
trình (file *.exe). Các file *.dll này nằm trong mục C:\opencv\build\x86\bin với win 32 bit  
ũ hơn, t  
hoặc C:\opencv\build\x64\bin với win 64 bit. Với các phiên bản OpenCV c  
a cần  
copy luôn file tbb_debug.dll (trong chế độ debug) hoặc tbb.dll (trong chế độ release) vào  
thư mục chứa file *.exe. tbb.dll (Thread building block) là file khá quan trọng, thiếu nó  
chương trình sẽ báo lỗi.  
Sau khi đã hoàn tất việc chỉ dẫn thư mục chứa header, library và link tới các library tương  
ứng, ta có thể include các header của opencv vào chương trình và có thể gọi các hàm làm  
việc của OpenCV.  
#include <opencv2/core/core.hpp>  
#include <opencv2/imgproc/imgproc.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <iostream>  
using namespace std;  
using namespace cv;  
void main()  
{
...  
}
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 9  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
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  
lib: C:\opencv\build\x86\mingw\lib đối  
với Windows 32 bit hoặc  
thư  
mụ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.  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 10  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
ũng c  
Ta c  
ần phải copy các *.dll tương ứng vào thư mục chứa file chạy *.execủa chương  
ình  
đ
trình ể chương tr  
có thể chạy thành công.  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 11  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
Chương II. Các phép xử lý ảnh và ứng dụng cơ bản  
ình đ  
1. Chương tr  
ầu tiên  
ình  
Trong bài này ta sẽ tìm hiểu một ví dụ đầu tiên như một chương tr  
Hello world để load  
ình như sau:  
và hiển thị một ảnh. Chương tr  
#include "stdafx.h"  
#include <iostream>  
#include <opencv2\highgui\highgui.hpp>  
#include <opencv2\core\core.hpp>  
using namespace std;  
using namespace cv;  
int main()  
{
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;  
}
ã nói  
Như đ  
ở 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…  
ã load  
Sau khi đ  
ả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ổ đ  
ợc tạo ra trước đó.  
Hàm waitKey(int delay) sẽ đợi cho đến khi có một phím được bấm vào trong khoảng thời  
ương trình sau khi ch  
gian là delay. Chú ý là nếu không có hàm này thì ch  
ạy sẽ không  
dừng lại màn hình và kết thúc luôn, ta dung hàm này mục đích là để dừng màn hình lại  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 12  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
trong một khoảng thời gian bằng tham số delay (tính theo đơn vị millisecond). Nếu muốn  
đ
dừng màn hình lại mãi mãi ta ặt tham số delay bằng 0.  
ình chay:  
Và sau đây là kết quả chương tr  
2. Không gian màu, chuyển đổi giữa các không gian màu  
Khôn gian màu là một mô hình toá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.  
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.  
à 8bit cho kênh R, 8bi  
Nếu như một ảnh số được mã hóa bằng 24bit, nghĩa l  
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.  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 13  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
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  
ì ph  
có màu đen thay v  
ả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  
ì ph  
màu đen, thay v  
ả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.  
ũng gần tương tự như HSL là không gian màu được dùng nhiều trong việc ch  
HSV và c  
ỉnh  
ữ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  
s
ố
s
sau  
để  
mô  
tả  
màu  
sắc  
vào  
3
thông  
ắc, S = Saturation: độ đậm đặc, sự bảo hòa, V = value: giá trị cường độ  
H = Hue: màu s  
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 đó,  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 14  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
òng tròn t  
đi theo v  
ừ 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 đỏ.  
ểu diễn màu sắc (HUE)  
Hình tròn bi  
Không gian màu HSV  
Chuyển đổi giữa các không gian màu.  
ển ổi RGB sang CMYK và ngược lại.  
Chuy  
đ
ã 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ó  
Như đ  
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)).  
ệ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ệ  
Vi  
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} ,  
ậy 0<= K <=100.  
như v  
ếu K = 100, th  
ì C = M = Y =0 (trương hợp in màu đen)  
ếu 0< K < 100: C = (C'/2.55  
N
N
- K) * 100 /(100 - K), M = (M'/2.55 - K) * 100 /(100 - K),  
ợc làm tròn tới ể  
Y = (Y'/2.55 - K) *100 /(100 - K) và K = K. Trong đó, C, M, Y, K đư  
lấy chỉ số nguyên.  
đ
ển đổi RGB sang HSV và ngược lại  
Chuy  
àu có giá trị trong hệ RGB là (R, G, B). ta chuyển sang không  
ả sử ta có một điểm m  
Gi  
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 -  
ờng hợp C = 0, H = 00  
G)/C + 4. Và H = H'x60. Trong trư  
V = M.  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 15  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
ờng hợp V hoặc C bằng 0, S = 0.  
S = C/V. Trong trư  
ể chuyển từ HSV sang RGB ta làm như sau:  
Đ
ả sử ta có không gian màu HSV với H = [0, 360], S = [0,  
Gi  
1], V = [0, 1]. Khi đó, ta tính  
C = VxS. H' = H/60.  
ểu diễn hệ (R
X = C(1 - |H' mod2 -1|). Ta bi  
(
0, 0, 0 
⎧
(
⎪
⎪
(
(
(
(
=  
≤  
≤  
⎨
⎪
⎪
⎩
≤  
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  
ĩa khá nhi  
mà mã chuyển đổi không gian màu. OpenCV định ngh  
ề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;  
void main()  
{
Mat src = imread("LucBinh.jpg", CV_LOAD_IMAGE_COLOR);  
Mat gray, hsv, ycrcb;  
cvtColor(src, gray, CV_BGR2GRAY);  
cvtColor(src, hsv, CV_BGR2HSV);  
cvtColor(src, ycrcb, CV_BGR2YCrCb);  
imshow("src", src);  
imshow("gray", gray);  
imshow("hsv", hsv);  
imshow("ycrcb", ycrcb);  
waitKey(0);  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 16  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
}
ình  
Sau đây là h  
ảnh khi chuyển đổi các không gian màu trên  
3. Điều chỉnh độ sang và độ tương phản trong ảnh  
Trong bài này ta sẽ tìm hiểu về cấu trúc của một bức ảnh, cách tiếp cận và điều chỉnh tới  
từng điểm ả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 ở định dạng cv::Mat qua hình ảnh sau:  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 17  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
Cột 0  
0, 0  
1, 0  
2, 0  
n, 0  
Cột 1  
0, 1  
1, 1  
2, 1  
n, 1  
Cột m  
0, m  
1, m  
2, m  
n, m  
Hàng 0  
Hàng 1  
Hàng 2  
Hàng n  
0, 0  
1, 0  
2, 0  
n, 0  
0, 1  
1, 1  
2, 1  
N, 1  
0, 1  
1, 1  
2, 1  
n, 1  
0, m  
1, m  
2, m  
n, m  
0, m  
1, m  
2, m  
n, m  
0, 0  
1, 0  
2, 0  
n, 0  
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ó. Để truy xuất tới từng pixel ảnh với những kênh màu riêng rẽ ta sử dụng  
mẫu sau:  
img.at<cv::Vec3b>(i,j)[k]  
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  
àn toàn tương t  
ũng ho  
ảnh màu, việc làm này c  
dung một kênh duy nhất để biểu diễn ảnh xám.  
ăng, gi  
ự đối với ảnh xám, chỉ khác biệt là ảnh ta  
ình t  
Chương tr  
ả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ị  
ì ta nói  
ộ sáng của ảnh g(x,y) đ  
trí (x,y). Đặt g(x,y) = αf(x,y) + β. Khi đó, nếu α ≠ 1, th  
ảnh g(x,y) có độ tương phản  
đ
ã thay  
ổi một lượng  
ói đ  
gấp α lần so với ảnh f(x,y). Nếu β ≠ 0ta n  
đ
ình thay  
ổi độ sáng và tương phản của ảnh  
β. D  
là  
ựa vào công thức trên ta có chương tr  
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()  
{
cout<<"Chuong trinh dieu chinh do sang va tuong phan"<<endl;  
Mat src = imread("hoa_huong_duong.jpg", 1);  
Mat dst = src.clone();  
double alpha = 2.0;  
int beta = 30;  
for(int i = 0; i < src.rows; i++)  
for(int j = 0; j < src.cols; j++)  
for(int k = 0; k < 3; k++)  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 18  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
dst.at<Vec3b>(i,j)[k] = saturate_cast<uchar>(  
alpha*(src.at<Vec3b>(i,j)[k] ) + beta);  
imshow("anh goc", src);  
imshow("anh co sau khi chinh do tuong phan va do sang", dst);  
waitKey(0);  
return 0;  
}
ình trên, hàm  
Trong chương tr  
clone() sẽ sao chép một ảnh giống hệt như ảnd gốc cho vào  
ảnh đích (dst = src.clone()). Giá trị của các pixel ảnh f(x,y) và g(x,y) ở đây phải nằm trong  
khoảng [0, 255], trong khi phép biến đổi g(x,y) = αf(x,y) + β có thể khiến cho giá trị của  
g(x,y) vượt qua ngưỡng đó. Để tránh tình trạng tràn số hoặc kiểu dữ liệu không tương  
thích, ta dùng thêm hàm saturate_cast<uchar>(type). Hàm này sẽ biến kiểu dữ liệu  
type nếu không phải là uchar thành kiểu dữ liệu uchar  
β = 30  
à
ới giá trị α = 2.0 v  
ình v  
Sau đây là kết quả chương tr  
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  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 19  
Ứng dụng xử lý ảnh trong thực tế với thư viện OpenCV  
Ả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 …  
à v  
ĩa l  
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  
ớ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  
ĩ thu  
khác nhau (không cần quan tâm tới ngưỡng T), người ta dùng một k  
ật sao cho với  
ĩ thu  
ĩ
mọi ngưỡng xám khác nhau ta luôn thu được một ảnh nhi phân tốt. K  
ật đó gọi là k  
Tác giả: Nguyễn Văn Long – long.06clc@gmail.com  
Page 20  
Tải về để xem bản đầy đủ
pdf 103 trang yennguyen 27662 Free
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Ứng dụng xử lý ảnh trong thực thế với thư viện OpenCV C/C++", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdfgiao_trinh_ung_dung_xu_ly_anh_trong_thuc_the_voi_thu_vien_op.pdf