ỨNG DỤNG XỬ LÝ ẢNH NHẬN DẠNG BIỂN SỐ XE SỬ DỤNG THUẬT TOÁN SVM - Pdf 36

Mục lục

MỤC LỤC
DANH MỤC CÁC TỪ VIẾT TẮT
MỞ ĐẦU
CHƯƠNG 1 : LÀM QUEN VỚI THƯ VIỆN OPENCV
1.1 Giới thiệu chương
1.2 So sánh phiên bản OpenCV 1 và OpenCV 2
1.3 Hướng dẫn sử dụng thư viện Open CV trên Window
1.4 Kết luận chương
CHƯƠNG 2 : CÁC PHÉP XỬ LÝ ẢNH ĐƠN GIẢN TRONG OPENCV
2.1 Giới thiệu chương
2.2 Chương trình đầu tiên
2.3 Ảnh nhị phân, nhị phân hóa với ngưỡng động
2.4 Các phép toán hình thái học trong ảnh
2.4.1 Phép toán giãn nở (dialation)
2.4.2 Phép toán co (erosion)
2.4.3 Phép toán đóng và mở (closing & opening)
2.5 Kết luận chương
CHƯƠNG 3 : LẬP TRÌNH XỬ LÝ ẢNH VỚI GIAO DIỆN MFC
3.1 Giới thiệu chương
3.2 Khởi tạo project MFC
3.3 Làm việc với các điều khiển (Control) của MFC
3.3.1 Đặt tên biến cho các control
3.3.2 Lấy giá trị nhập vào từ một Edit Control
3.3.3 Hiển thị các test lên các control
3.3.4 Hiển thị ảnh lên một control
3.3.5 Enable, disnable một control
3.3.6 Lấy giá trị từ thanh trược (Slider control)
3.3.7 Lấy giá trị lựa chọn từ Combo Box
3.3.8 Dialog mở file và lưu file


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

API

Application Programming Interface

BSD

Berkeley Software Distribution

IDE

Integrated Development Environment

IEEE

Institute of Electrical and Electronics Engineers

LPR

License Plate Recognition

MFC

Microsoft Foundation Classes

OpenCV

Open Source Computer Vision

Nội dung đồ án bao gồm:
Chương 1 : Làm quen với thư viện OpenCV
Chương 2 : Các phép xử lý ảnh đơn giản trong OpenCV
Chương 3 : Lập trình xử lý ảnh với giao diện MFC
Chương 4 : Nhận dạng biển số xe bằng thuật toán SVM
Tuy em đã cố gắng tìm tòi và nỗ lực hết sức để thực hiện đồ án nhưng hẳn sẽ có
không ít sai sót, vì vậy kính mong các thầy cô góp ý và chỉ bảo thêm, giúp em nắm
vững hơn vốn kiến thức của mình.
Em xin chân thành cảm ơn.

4


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

CHƯƠNG 1 : LÀM QUEN VỚI THƯ VIỆN OPENCV
1.1 Giới thiệu chương
Chương này giới thiệu về OpenCV (Open Source Computer Vision), 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 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 đó 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

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 khi 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”);
IplImage* gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
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:

6


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

// Phát hiện đường tròn trong ảnh OpenCV 2.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);

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

Hình 1.1
Chọn OK, sau đó nhấn Next, hộp thoại tiếp theo xuất hiện, ở hộp thoại này 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.

8


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

Hình 1.2

Project mới được tạo ra là project hoàn toàn trống, chúng ta phải thêm vào đó ít
nhất một file nguồn để chương trình
có thể chạy được,

trong

Solution

click

chuột

Explorer

FirstApp.cpp.

9

cho


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

Hình 1.3
Bây giờ trong file này chúng ta có thể thêm vào các #include và gọi hàm main() để
chạy chương trình.
Để chương trình có thể chạy được với thư viện OpenCV thì 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, tìm mục Include Directories và LibraryDirectories.
Chúng ta sẽ chỉ đường dẫn hai thư mục này đến các phần tương ứng của thư
việnOpenCV.
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ư sử dụng hệ điều hành 32bit hoặc C:\opencv\build\x64\vc10\lib cho hệ điều hành
64bit.
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
AdditionalDependencies
làopencv_core243d.lib,opencv_imgproc243d.lib,opencv_highgui243d.lib.

Hình 1.4


chương trình và các phiên bản ra đời của OpenCV. Qua đó giúp hỗ trợ cho việc xử
lý ảnh thuận tiện hơn.

11


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

CHƯƠNG 2 : CÁC PHÉP XỬ LÝ ẢNH ĐƠN GIẢN TRONG OPENCV
2.1 Giới thiệu chương
Chương 2 sẽ giới thiệu các chương trình đơn giản để xử lý một bức ảnh. Trong
chương này em giới thiệu 3 chương trình chính đó là: chương trình để load và hiển
thị một ảnh, chương trình nhị phân hóa với ngững động, chương trình về các phép
toán hình thái học về việc giản nỡ và nối liền biên ảnh để tìm biển số xe ô tô.
2.2 Chương trình đầu tiên
Trong ví dụ này, em sẽ viết một chương trình Hello world để load và hiển thị
một ảnh.
Chương trình như sau :
#include "stdafx.h"
#include <iostream>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\core.hpp>
using namespace std;
using namespace cv;
int main()
{
cout

thì

để

CV_LOAD_IMAGE_GRAYSCALE…Sau khi đã load ảnh thành công, muốn hiển thị
ảnh lên màn hình cần 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 gian là delay. Chú ý là nếu không có hàm này thì chương trình sau khi
chạy sẽ không dừng lại màn hình và kết thúc luôn, ta dùng hàm này mục đích là để
dừng màn hình lại 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.
Và sau đây là kết quả của chương trình chạy:

13


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

Hình 2.1
2.3 Ả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à


Hình 2.3
Để 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 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 đó (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:

16


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

Hình 2.4
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>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>
using namespace std;


Hình 2.5

18


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

2.4 Các phép toán hình thái học trong ảnh
Các phép toán hình thái học là những phép toán liên quan tới cấu trúc hình học
(hay topo) của các đối tượng trong ảnh. Các phép toán hình thái học tiêu biểu bao
gồm phép giãn nở (dialation), phép co (erosion), phép mở (opening) và phép đóng
(closing).
2.4.1 Phép toán giãn nở (dialation)
Phép toán giãn nở được định nghĩa A B = với x trong đó, A là đối tượng trong
ảnh, B là một cấu trúc phần tử ảnh. Phép toán này có tác dụng làm cho đối tượng
ban đầu trong ảnh tăng lên về kích thước (giãn nở ra).
Cấu trúc phần tử ảnh (image structuring element) là một hình khối được định
nghĩa sẵn nhằm tương tác với ảnh xem nó có thỏa mãn một số tính chất nào đó
không, một số cấu trúc phần tử hay gặp là cấu trúc theo khối hình vuông và hình
chữ thập.

Hình 2.6
Xét một ảnh với đối tượng trong ảnh được biểu diễn bằng màu nền nâu, sau đó
dùng cấu trúc phần tử hình vuông (màu đỏ) để làm giãn nở ảnh, kết quả là ảnh được
giãn nở ra, chúng ta đánh dấu là dấu x.

19



lấp đầy các khoảng trống trên biên và loại bỏ những hố nhỏ (một số pixel đứng
thành cụm độc lập)
Trong OpenCV, các phép toán hình thái học trong ảnh được cài đặt trong hàm
cv::morphologyEx, riêng phép giãn nở và phép co có thể gọi trực tiếp từ hàm
cv::dilate và cv::erode: morphologyEx(const Mat& src, Mat& dst, int op, const
Mat& element, Point anchor, int iterations, int borderType, const Scalar&
borderValue)
Trong đó src, dst là ảnh đầu vào và ảnh sau phép xử lý hình thái học. op là kiểu
lựa chọn phép hình thái học, chẳng hạn như phép giãn nở là MORPH_DILATE,
phép đóng là MORPH_OPEN… element là cấu trúc phần tử ảnh, có ba cấu trúc cơ
bản là theo khối hình vuông, hình chữ thập và hình elip. Để tạo ra các cấu trúc này
ta có thể tự định nghĩa một ma trận với các hình khối tương ứng hoặc sử dụng hàm
getStructuringElement, hàm này có cấu trúc như sau: getStructuringElement(int
shape, Size ksize, Point anchor), với shape là kiểu hình khối (một trong 3 hình khối
trên), ksize là kích thước của hình khối và là kích thước của hai số nguyên lẻ,
anchor là điểm neo và thông thường nhận giá trị là((ksize.width – 1)/2, (ksize.height
– 1)/2). Thông số tiếp theo anchor cũng có ý nghĩa tương tự. iterations là số lần lặp

21


Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

lại của phép toán hình thái và hai thông số cuối cùng là về giới hạn biên của những
điểm ảnh nằm ngoài kích thước ảnh trong quá trình tính toán.
Phép toán về giản nở và co có thể được gọi từ hàm cv::morphologyEx thông
qua hai đối số op là MORPH_DILATE và MORPH_ERODE hoặc chúng có thể
được gọi trực tiếp từ hàm cv::dilate và cv::erode, Cấu trúc của hai hàm này là
tương tự nhau và các tham số hoàn toàn giống với tham số trong hàm
morphologyEx:

#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
void main()
{
Mat src1 = imread("BienSo.jpg", CV_LOAD_IMAGE_COLOR);
Mat src2 = src1.clone(); // copy anh
Mat gray, binary;
cvtColor(src1, gray, CV_BGR2GRAY);
threshold(gray, binary, 100, 255, CV_THRESH_BINARY);
imshow("Anh nhi phan goc", binary);
Mat morpho;
Mat element = getStructuringElement(MORPH_CROSS, Size(3,3),
Point(1,1));
erode(binary, morpho, element, Point(-1,-1), 3);
imshow("Anh sau khi thuc hien phep gian no", morpho);
vector 3.5f && r.width/(double)r.height
Chương 2: Các phép xử lý ảnh đơn giản trong Opencv

Hình 2.9
Nhận thấy rằng, điểm đứt trong ảnh được nối liền nhờ sự giãn nở của biển cạnh
biển số (sự co lại của nền ảnh) nên ta tìm được một hình bao khép kín quanh biển
số, tuy nhiên ta cũng nhận thấy rằng khi các đối tượng vật thể trong ảnh giãn nở ra,
các kí tự sẽ có xu hướng dính vào nhau và việc tách các kí tự ra là khó khăn, chẳng
hạn trên hình do có đinh vít ở giữa mà số 2 và số 9 gần như nối liền. Đây là lúc cần
phải thực hiện việc co lại của các đối tượng (sự giãn nở của nền ảnh), và do đó
chúng ta hoàn toàn có thể cài đặt để tách ra các kí tự này.
2.5 Kết luận chương
Đây là công đoạn đầu tiên mang tính quyết định đối với quá trình xử lý ảnh.
Ảnh đầu vào sẽ được thu nhận qua các thiết bị camera, máy scanner…và sau đó tín
hiệu này sẽ được số hóa và qua các công đoạn xử lý như trên với mục đích nâng cao
chất lượng ảnh để chuẩn bị cho các bước xử lý phức tạp hơn về sau.

25



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