3.2.1 Webcam
Webcam Logitech C600 được sử dụng nhằm thực hiện chụp ảnh để tạo ảnh đầu vào cho bộ nhận dạng biển báo giao thông.
Hình 3.2 : Webcam logitech C600
Một số tính năng chủ yếu của webcam Logitech C600 : Độ phân giải 2 Mega pixel với kích thước ảnh 1600x1200
Tốc độ chụp ảnh 2M pixel với tốc độ 30 ảnh/giây
phù hợp với USB 2.0
có khả năng tương thích với hệ điều hành linux do dựa trên chuẩn UVC (Usb Video
Class)
Việc lựa chọn webcam (camera) sử dụng ngoài việc cần thỏa các yêu cầu về chất lượng, cũng như tốc độ chụp ảnh thì yếu tố quan trọng nhất đối với luận văn này đó là webcam đó phải phù hợp với chuẩn UVC mà được hỗ trợ trong tập thư viện V4l2 (video for linux 2) đã được tích hợp sẵn trong mọi linux kernel 2.6.29 trở lên.
3.3 HỆ THỐNG PHẦN MỀM LIÊN QUAN
Luận văn này được thực hiện với mong muốn phát triển hệ thống dựa trên mã nguồn
mở (Open Source) nhằm hạn chế các vi phạm về quyền sở hữu trí tuệ trong việc sử
dụng không hợp pháp các phần mềm bản quyền. Do đó xuyên suốt quá trình thực hiện,
luận văn được phát triển trên hệ điều hành Unix Fedora 12 kết hợp với thư viện mã nguồn mở về thị giác máy tính OpenCV 2.1.0
3.3.1 Hệ điều hành Fedora 12
Hệ điều hành Fedora là một bản phân phối Linux được phát triển dựa trên cộng đồng theo dự án Fedora và được bảo trợ bởi Red Hat. Dự án Fedora nhằm mục đích
tạo ra một hệ điều hành mã nguồn mở hoàn chỉnh để sử dụng cho các mục đích tổng
quát. Sở dĩ các hệ điều hành Linux đạt được những thành công một cách nhanh chóng
là nhờ vào các đặc tính nổi bật so với các hệ thống khác: chi phí phần cứng thấp, tốc độ cao (khi so sánh với các phiên bản Unix độc quyền) và khả năng bảo mật tốt, độ
tin cậy cao (khi so sánh với Windows) cũng như là các đặc điểm về giá thành rẻ,
không bị phụ thuộc vào nhà cung cấp. Một đặc tính nổi trội của nó là được phát triển
bởi một mô hình phát triển phần mềm nguồn mở hiệu quả và hỗ trợ tối đa không chỉ cho người phát triển phần mềm mà còn cho cả người dùng cá nhân với hàng nghìn
Hình 3.4 : Màn hình desktop của hệ điều hành Fedora 12
Tuy nhiên, hiện tại số lượng phần cứng được hỗ trợ bởi Linux vẫn còn rất khiêm tốn so với Windows vì các trình điều khiển thiết bị tương thích với Windows nhiều hơn là Linux. Nhưng trong tương lai số lượng phần cứng được hỗ trợ cho Linux sẽ tăng lên.
3.3.2 Thư viện mã nguồn mở về thị giác máy tính OpenCV
OpenCV là một thư viện các hàm lập trình nhằm mục đích hỗ trợ vấn đề thị giác
máy tính trong thời gian thực. OpenCV được phát triển từ Intel và hiện đang được hỗ
trợ bởi tổ chức Willow Garage. Nó được phát hành miễn phí dựa trên giấy phép mã nguồn mở BSD. Thư viện OpenCV có khả năng thực hiện đa nền tảng trên các hệ điều hành khác nhau (Windows, Linux, Mac) và tập trung chủ yếu vào các hàm xử lý ảnh từ cơ bản đến phức tạp. OpenCV có trên 500 hàm xử lý ảnh được phân thành các nhóm : các hàm xử lý ảnh tổng quát, phân mảnh, các phép biến đổi hình học, phát
Hình 3.5 : Giới thiệu OpenCV
Do đó thư viện OpenCV sẽ hỗ trợ giải quyết các vấn đề cơ bản về xử lý ảnh giúp
cho người phát triển tập trung vào giải thuật, phương pháp chính để giải quyết vấn đề.
§ Giới thiệu một số hàm trong thư viện OpenCV thông dụng được sử dụng trong luật văn này :
Hàm định dạng lại kích thước ảnh
void cvResize(const CvArr* src, CvArr* dst,
int interpolation=CV_INTER_LINEAR)
trong đó giải thuật nội suy được sử dụng là CV_INTER_NN (giải thuật giá trị điểm lân cận đã được giới thiệu trong mục 2.2.4)
Hàm biến đổi không gian màu từ không gian RGB không gian HSV
với code = CV_RGB2HSV, hàm thực hiện biến đổi một ảnh đầu vào src
được biểu diễn dưới dạng không gian màu RGB thành ảnh kết quả dstđược thể
hiện bằng không gian màu HSV bởi công thức chuyển đổi sau:
max( , , ) V R G B min( , , ) 0 0 0 V R G B khi V S V V (3.1) 60( ) / 120 60( ) / 240 60 G B S if V R H B R S if V G if V B Nếu H0 thì HH360
Hàm biến đổi khoảng cách (distance transform)
void cvDistTransform(const CvArr* src, CvArr* dst,
int distance_type=CV_DIST_L2, int mask_size=3, const float* mask=NULL,CvArr* labels=NULL)
Hàm trả về ảnh kết quả dst từ ảnh đầu vào src qua phép biến đổi khoảng
cách với phương pháp là distance_type (mặc định là CV_DIST_L2) như ví dụ
sau:
Hình 3.6 : Ví dụ về phép biến đổi khoảnh cách với distance_type = CV_DIST_C2
Hàm giới hạn ngưỡng cực đại cho từng điểm ảnh
double cvThreshold(const CvArr* src, CvArr* dst, double threshold, double maxValue, int thresholdType)
Hàm được sử dụng để giới hạn ngưỡng giá trị của ảnh đầu vào src thành ảnh đầu ra dst với ngưỡng giới hạn là threshold và tùy loại biến đổi thresholdType
mà sẽ có giá trị đầu ra khác nhau như sau:
Hàm thiết lập vùng ảnh con quan tâm trên một ảnh lớn
void cvSetImageROI(IplImage* image, CvRect rect)
Thiết lập vùng ảnh quan tâm ROI (region of interest) được xác định bởi hình chữ nhật rect trên ảnh image, các phép toán xử lý ảnh sau này sẽ chỉ ảnh hưởng, tác động tới vùng quan tâm ROI mà thôi.
Hàm vẽ đường bao hình chữ nhật
void cvRectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int lineType=8, int shift=0)
Hàm được sử dụng để vẽ một hình chữ nhật được xác định bởi các đỉnh pt1, pt2 lên ảnh img với các tùy chọn về màu sắc, nét vẽ,…
Hàm tìm đường bao của đối tượng
int cvFindContours(CvArr* image, CvMemStorage* storage,
CvSeq** first_contour, int header_size=sizeof(CvContour), intmode=CV_RETR_LIST,
int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0, 0))
Hàm này được sử dụng để tìm đường bao của đối tượng thể hiện trong ảnh nhị
phân image. Kết quả tạo ra được tập các đường bao ngoài và bao trong được
chứa trong cấu trúc CvSeq là first_contour với cách thức sắp xếp quy định
bởi mode.
Hình 3.7 : một ảnh đầu vào (hình trên) được đưa vào hàm cvFindContours thì ta thu được kết
quả như hình dưới, các đường bao tìm thấy sẽ được chia thành 2 dạng là đường bao ngoài (ký hiệu c...) và các đường bao trong ( được xem là lỗ, ký hiệu h....)
Ví dụ hình 3.7 mô tả tính năng tìm kiếm đường bao của hàm cvFindContours. Các đường bao sau khi được xác định sẽ được sắp xếp theo một trật tự nhất định quy đình bởi mode và có các giá trị sau :
Hàm thể hiện ảnh ra giao diện người dùng
void cvShowImage(const char* name, const CvArr* image)
Hàm này dùng để xuất ảnh image ra cửa sổ người dùng được xác định bởi tên cửa sổ name. Hàm này chỉ được sử dụng trong môi trường hỗ trợ giao diện
KDE.
…………..
3.3.3 Thực thi chương trình và giải thuật
3.3.3.1 Giải thuật và chương trình huấn luyện ảnh mẫu
Giải thuật được thực hiện trên ngôn ngữ lập trình C++ kết hợp với một số hàm xử lý ảnh cơ bản của thư viện mở về thị giác máy tính OpenCV 2.1.0 và được tóm tắt như được mô tả ở hình 3.8
Hình 3.8 : Khái quát giải thuật huấn luyện tập ảnh mẫu để tìm vùng ảnh đặc trưng cùng trọng số tương ứng cho từng ảnh mẫu
Một phần đọan chương trình chính thực hiện việc tìm vùng ảnh đặc trưng và trọng số tương ứng từ các ảnh mẫu biển báo giao thông
for (int i=0; i<numberofsign; i++){ cvSetZero(wk); cvSetZero(im_dist); for(int j=0;j<numberofsign;j++){ if (j==i) continue; timdk(distimageset_b[i],distimageset_b[j],im_dist); Resize(im_dist,rk); timwk(rk,5.0,wk); } Unresize(wk,im_dist); wmat_b[i]= cvCloneImage(im_dist); normalizemax(im_dist,im_dist); cvConvertImage(im_dist,im_dist8u1); wmat8u1_b[i]=cvCloneImage(im_dist8u1); }
Bảng 3.1 :một phần đoạn chương trình chính thực hiện việc tìm vùng ảnh đặc trưng và tập
trọng số tương ứng từ các ảnh biển báo giao thông mẫu
Từ chương trình tìm vùng ảnh đặc trưng trên sau khi thực thi ta được kết quả là tập các
vùng ảnh đặc trưng của từng biển báo giao thông quan tâm như sau;
Hình 3.9 : Một số kết quả từ việc tìm kiếm vùng điểm ảnh đặc trưng cho từng biển báo giao thông mẫu
Các ảnh thể hiện vùng đặc trưng thu được từ giải thuật tìm kiếm trên sẽ được chuẩn hóa để các giá trị số thực [0; 1] sẽ có giá trị nguyên nằm trong khoảng [0; 255].
thời tránh việc phải thực thi các phép toán sử dụng dấu chấm động (floating point) làm cho quá trình xử lý tốn nhiều thời gian không hiệu quả.
Cuối cùng kết quả thu được từ chương trình trên sẽ được ghi vào tập tin cấu hình lưu
lại các đặc điểm đã được huấn luyện dưới dạng cấu trúc XML
<?xml version="1.0"?> <opencv_storage>
<name>r1_103a,r1_103b,r1_103c,r1_104……….</name> <nameofsign>"CAM O TO,CAM O TO RE PHAI,CAM O TO RE TRAI,………"</nameofsign>
<br1_103a type_id="opencv-image">
<width>60</width> <height>60</height> <origin>top-left</origin> <layout>interleaved</layout>
<dt>u</dt> <data>
255 255 255 255 255 255 255 255 255 ……..</data>
<w_br1_103a type_id="opencv-image">
<width>60</width> <height>60</height> <origin>top-left</origin> <layout>interleaved</layout>
<dt>u</dt> <data>
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ………</data> ………..
3.3.3.2 Giải thuật và chương trình nhận dạng biển báo giao thông
Chương trình chính bao gồm các chức năng chính sau:
Hình 3.10 : Sơ đồ khối chức năng của chương trình chính
Từ các yêu cầu của chương trình chính mà học viên đề nghị giải thuật hình 3.11 để giải
quyết các vấn đề đặt ra của bài toán nhận dạng biển báo giao thông.
Các bước hoạt động của chương trình được trình bày tóm tắt như sau (xem chương
trình có ghi kèm trong đĩa CD để thêm thông tin chi tiết)
Thu thập ảnh đầu vào :
Sử dụng thư viện OpenCV
IplImage*image=cvLoadImage(“img.jpg”,CV_LOAD_IMAGE_COLOR); //load từ file
hoặc
CvCapture capture = cvCaptureFromCAM(0); // load ảnh từ Webcam
IplImage* image8u3=cvQueryFrame(capture);
Sử dụng thư viện V4l2 mặc định trong Linux kernel
OpenCam(&sizeimage); // (Các hàm đã được học viên điều chỉnh)
Tách màu quan tâm :
Thuật toán tách màu được thực hiện trên phương pháp lượng tử hóa các màu đã được
trình bày trong mục 2.2.1.1. Chương trình cụ thể như sau
cvCvtColor(image,imageHSV,CV_BGR2HSV);
quantization(imageHSV,image_quan); // lượng tử hóa màu
quancolor (image_quan,image_red,8,12); // tách màu đỏ
với hàm lượng tử hóa màu quantization( ) và xác định màu quancolor( ) được viết như
sau :
void quantization(IplImage* imHSV, IplImage* dst) { int h = 0, s=0, v=0;
int Hue =0, Sat = 0, Val = 0; for(int i=0; i<imHSV->height; i++){ for(int j=0; j<imHSV->width; j++){
h =((uchar*)(imHSV->imageData+ i*imHSV->widthStep))[j*imHSV->nChannels+ 0]; s =((uchar*)(imHSV->imageData+ i*imHSV->widthStep))[j*imHSV->nChannels+ 1]; v =((uchar*)(imHSV->imageData+ i*imHSV->widthStep))[j*imHSV->nChannels+ 2]; if (v<85) { ((uchar *)(dst->imageData + i*dst->widthStep))[j] = 0; continue;} if((v<210)&&(s<75)) {
((uchar *)(dst->imageData + i*dst->widthStep))[j]=cvRound((v-85)*10/255)+1; continue;}
if ((v>=210)&&(s<75)) {
((uchar *)(dst->imageData + i*dst->widthStep))[j] = 7; continue;} else{ if ((h>165)||(h<=11)) Hue = 0; if ((11<h)&&(h<=22)) Hue = 1; if ((22<h)&&(h<=35)) Hue = 2; if ((35<h)&&(h<=78)) Hue = 3; if ((78<h)&&(h<=93)) Hue = 4; if ((93<h)&&(h<=139)) Hue = 5; if ((139<h)&&(h<=165))Hue = 6; if (s< 167) {Sat = 0;} else {Sat = 1;} if (v<180) {Val =0;} else {Val = 1;}
((uchar*)(dst->imageData+i*dst->widthStep))[j]=4*Hue +2*Sat+Val+8; } }
} }
void quancolor(IplImage *im8u1, IplImage * dst, int min=0, int max = 1 ){ int val =0;
for (int i=0; i<image->height;i++){ for (int j=0; j<image->width;j++){
val = ((uchar *)(im8u1->imageData + i*im8u1->widthStep))[j];
if((min<=val)&&(val<max)){((uchar*)(dst->imageData+i*dst->widthStep))[j]=0;} else {((uchar *)(dst->imageData + i*dst->widthStep))[j] = 255;}
} } }
Tìm độ khác biệt giữa đối tượng biển báo giao thông khả nghi và tập ảnh biển báo giao thông mẫu đã được huấn luyện
Đoạn chương trình sau được phát triển dựa trên công thức tính độ khác biệt từ giải
1 , 1 ( , ) ˆ ( , ) k S k r k S W S k k w d I J d I J w (3.1)
với wk là trọng số của từng vùng điểm ảnh con có được sau giai đoạn học huấn luyện
bằng giải thuật lựa chọn vùng điểm ảnh đặc trưng nổi bật đã được trình bày ở trên. và 2 2 1 1 ( , ) ( , , ) k m r CDT t t d I J I J p m (3.2)
là độ khác biệt cùa từng vùng điểm ảnh con khi so sánh với nhau cũng dựa trên giá trị khác biệt CDT( , ,I J pt)của từng điểm ảnh (pixel) giữa hình ảnh đối tượng và hình ảnh biến đổi khoảng cách ảnh màu CDT của ảnh mẫu được xác định bởi :
( ) ( ) 0 ( , , ) 0 ( ) 0 t t CDT t J p if I p I J pt if I p (3.3)
Đoạn chương trình xác định ảnh biển báo giao thông mẫu ít có sự khác biệt nhất với đối tượng biển báo giao thông khả nghi :
for(int i=0, sum1=0; i<numberofsign; i++){
if(strncmp(signname[i],bestborder,2)!=0) continue;
sum=0;
sum1 =0;
sum = timsumwkdk(sc_distimageset_w[i], im_dist_w, sc_weightset_w[i], &sum1);
total =sum1;
sum = timsumwkdk(sc_distimageset_b[i], im_dist_b, sc_weightset_b[i],&sum1);
total +=sum1; // tong khac biet mau DEN va mau TRANG
mindiff = min(total,mindiff); if(mindiff == total) imax = i;
}
Hàm timsumwkdk( ) trong đoạn chương trình trên được khai báo như sau :
int timsumwkdk(IplImage* img8u1, IplImage* tpl8u1, IplImage* wk8u1,int* sum1=NULL){ int sumwkdk=0, sumwk=0, diff = 0;
int height = (cvGetSize(img8u1)).height; int width = (cvGetSize(img8u1)).width; for(int i =0; i<height; i++) {
for (int j=0; j<width;j++) {
if (((uchar*)(img8u1->imageData + i*img8u1->widthStep))[j]==0) { sumwkdk +=(uchar*)(tpl8u1->imageData+ i*tpl8u1->widthStep))[j]*((uchar*)(wk8u1->imageData + i*wk8u1->widthStep))[j]; sumwk +=((uchar*)(wk8u1->imageData + i*wk8u1->widthStep))[j]; } } }
if(sum1!=NULL) *sum1 = sumwkdk/1000; if(sumwk !=0) diff = (int) sumwkdk/sumwk;
return diff; }
Tạo ảnh kết quả xuất ra bên ngoài
Ảnh kết quả sẽ được tạo thành bằng cách vẽ các đường bao hình chữ nhật các biển báo
giao thông nhận dạng đường cùng kèm với tên gọi của biển báo giao thông. Chương
trình được thực hiện như sau:
void outputimage(int sobienbao, char name[20][30],IplImage* image, IplImage* dst){ CvFont font; char text[20]=""; cvSetZero(dst); cvSetImageROI(dst,cvRect(0,0,image->width,image->height)); cvResize(image,dst); cvResetImageROI(dst); for (int i = 0; i<sobienbao;i++){
cvSetImageROI(dst,cvRect(image->width,100*i,100,100)); cvResize(cvLoadImage(name[i],CV_LOAD_IMAGE_COLOR),dst); cvResetImageROI(dst); if ((100*(i+3))>(image->height)) break; } cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 2, 2, 0, 2, 4); cvPutText(dst,strcat("Sign:",""),cvPoint(image->width, image->height -50),&font,CVX_GREEN); sprintf(text,"%d",sobienbao); cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 3, 3, 0, 4, 8); cvPutText(dst,text,cvPoint(image->width+ 20, image->height -10),&font,CVX_RED); }
CHƯƠNG 4
KẾT QUẢ - NHẬN XÉT VÀ
PHÂN TÍCH
4.1 KẾT QUẢ
4.1.1 Xây dựng tập dữ liệu hình ảnh mẫu
Các hình ảnh biển báo giao thông mẫu sử dụng trong luận văn này được học viên scan từ các tài liệu học tập thi giấy phép lái xe môtô, ô tô và một số hình ảnh trên mạng mà học viên tìm kiếm được. Sau đây là tập mẫu mà học viên sử dụng (>70 ảnh
biển báo mẫu) như hình 4.1. Trong tập mẫu này có một số biển báo giao thông được
thể hiện bằng 2, 3,.. ảnh mẫu bởi vì có sự khác nhau về ký hiệu và kiểu dáng tuy cùng thể hiện một nội dung. Các ảnh mẫu này được tiền xử lý thành các ảnh con có kích thước 60x60 và sau đó được đưa vào bộ huấn luyện để tìm các vùng điểm ảnh đặc trưng.
Sau quá trình huấn luyện mẫu thì ta có được 2 tập tin chứa các đặc trưng của việc
nhận dạng:
tập tin “khung.xml” chứa các đặc trưng sử dụng cho việc nhận dạng các đường bao ngoài
tập tin “sign.xml” chứa các đặc trưng sử dụng cho việc nhận dạng các ký
hiệu, hình mô tả của từng loại biển báo giao thông mà qua đó sẽ nhận
dạng, phân loại được biển báo giao thông
4.2.2 Thực hiện thí nghiệm để đánh giá kết quả 4.2.2.1 Thử nghiệm mô hình trên các ảnh mẫu
Chương trình được thử nghiệm trên máy tính để kiểm chứng kết quả đạt được
a) Kết quả thử nghiệm trên các biển báo cấm
b) Kết quả thử nghiệm trên các biển nguy hiểm
Nhận xét : ta thấy rằng khả năng nhận dạng các hình biển báo giao thông từ các ảnh
mẫu là tương đối chính xác và có khả năng nhận nhiều ảnh với thời gian xử lý nhanh
(khoảng 200ms).
4.2.2.2 Thử nghiệm trên các ảnh chụp thực tế
Các ảnh thu thập bằng việc chụp từ các biển báo giao thông thực tế trên đường bộ
Nhận xét :
- Kết quả nhận dạng tốt đối với một số biển báo giao thông mà hình ảnh
thực tế với hình ảnh huấn luyện lấy từ trong các giáo trình quy định biển