BOARD TINY6410: II.5.1.Giới thiệu OpenCV:

Một phần của tài liệu Khóa luận wifi robot board tiny 6410 (Trang 71 - 81)

II.5.1.Giới thiệu OpenCV:

a. Tổng quan:

OpenCV viết tắt của Open Source Computer Vision Library.

Nó chứa hơn 500 hàm sử dụng trong xử lý ảnh.

OpenCV là một thư viện mã nguồn mở (open source). Thư viện được viết bằng ngôn ngữ C và C++ có thể chạy trên các hệ điều hành Linux, Window và Mac OS X. OpenCV được thiết kế để nâng cao hiệu suất tính tốn và nhấn mạnh đến hệ thống thời gian thực. Một điều tuyệt vời của OpenCV là nó đưa ra một hệ thống đơn giản, dễ sử dụng giúp mọi người nhanh chóng xây dựng các ứng dụng trong thị giác máy, kể cả các hệ thống kiểm tra trong nhà máy, bức ảnh trong lĩnh vực y học, bảo mật, rô bốt học...

OpenCV chứa các lập trình xử lý ảnh rất đơn giản, kể cả thực thi các hàm bậc cao như dị tìm khn mặt, theo dõi khuôn mặt, nhận dạng khuôn mặt, lọc Kalman.

Kể từ khi được giới thiệu vào tháng 1 năm 1999, OpenCV đã được sử dụng trong rất nhiều ứng dụng, các sản phẩm và các nghiên cứu. Ví dụ trong lĩnh vực hàng không vũ trụ, bản đồ web, sử dụng giảm nhiễu trong y học, phân tích đối tượng, an ninh, hệ thống dị tìm, theo dõi tự động và hệ thống bảo mật, quản lý hệ thống sản xuất, xử lý camera, ứng dụng trong quân sự, hệ thống hàng không không người lái, trên mặt đất, các tàu ngầm. Ngồi ra, nó cịn được sử dụng trong nhận dạng âm thanh. OpenCV cịn là một chìa khá quan trọng trong các rơ bốt sử dụng xử lý ảnh như Stanford, Asimo.

Có rất nhiều công nghệ hiện đại và các công ty lớn sử dụng thư viện OpenCV trong ứng dụng của mình (điển hình như Intel, Microsoft, IBM, Siemens, Google v..v.) và các trung tâm nghiên cứu như (Stanford, MIT, CMU, Cambridge, INRIA…).

b. Những nét đặc trưng:

OpenCV có rất nhiều chức năng. Sau đây là những tóm tắt cơ bản về hệ thống các về chức năng của các hàm căn bản trong OpenCV 2.0, mà cụ thể ở đây là ver 2.0 ( phiên bản sử dụng cho Board Tiny6410).

• OpenCV cung cấp các hàm mà cho phép chúng ta tương tác trực tiếp với hệ điều hành, các file hệ thống, các phần cứng như Webcam. Các hàm này nằm trong thư viện HighGUI, HighGUI cho phép mở một window, hiển thị bức ảnh, đọc các file liên quan đến đồ hoạ (ảnh, video) các file ảnh như jpg, bmp v..v. các file video như avi, wma, mp4, dat v..v. Ngồi ra nó cịn xử lý các sự kiện chuột, bàn phím, OpenCV cịn cho phép chúng ta lựa chọn thuật toán linh động hơn bằng cách cung cấp các hàm tạo thanh trượt slider, switch v..v. Để làm việc với OpenCV trước hết phải học các hàm trong thư viện này.

• Thư viện HighGUI có thể chia thành 3 phần: phần cứng, phần file hệ thống và phần GUI (Graphical User Interface) chúng ta có thể xem xét các phần trong thư viện HighGUI như sau.

o Phần cứng: là phần thiết yếu nhất, liên quan đến hoạt động của Camera, trong phần lớn hệ điều hành việc tương tác với phần cứng rất khó khăn và thực sự rất khó nhưng OpenCV cung cấp hàm đơn giản để thực hiện việc tương tác này ví dụ: cvCaptureFromCAM().

o Phần file hệ thống: là khái niệm liên quan đến việc tải và lưu ảnh, một đặc điểm rất tuyệt vời trong thư viện HighGUI là cho phép chúng ta làm việc với ảnh tương tự khi làm việc với video. Vì vậy chúng ta có thể nhanh chóng tiếp cận với việc xử lý ảnh mà không mất nhiều thời gian cho việc tải, lưu ảnh, video.

o Phần GUI: là hệ thống cửa sổ (Window), thư viện cung cấp một số hàm đơn giản mà cho phép chúng ta mở một window hiển thị ảnh trên window này. Ngồi ra nó cịn cho phép chúng ta thực thi các sự kiện nhận được từ chuột và bàn phím.

Đầu tiên chúng ta cần học cách làm thế nào để đọc và viết các files ảnh, chụp video chuyển đổi giữa các định dạng màu, và truy cập dữ liệu điểm ảnh tất cả qua giao diện OpenCV.

• CXCORE bao gồm các dạng dữ liệu cơ bản là lõi của thư viện OPenCV. Ví dụ cấu trúc dự liệu về ảnh, điểm, hình chữ nhật được xác định trong file cxtypes.h. CXCORE chứa các phép tốn đại số tuyến tính và thống kê, các hàm lưu trữ lâu dài và các lỗi thao tác. • CV chứa đựng q trình xử lý ảnh và các phương pháp đánh giá sơ

bộ kích thước ảnh. Những hàm tính tốn hình học cũng được lưu trữ tại đây.

• CVAUX gồm các interfaces đơn giản nhất cho nhận dạng khuôn mặt được nằm trong modul này. Những mã nguồn nằm trong module này rất phù hợp cho việc nhận dạng mặt và chúng được sử dụng rộng rãi cho mục đích này.

• HIGHGUI chứa các interfaces ở mức cao như show hình ảnh, các chuyển đổi hình ảnh, thực thi lệnh từ bàn phím, chuột…

• Sơ đồ cấu trúc:

Hình 2.5.1: Cấu trúc thư viện OpenCV

d. Các header chính trong thư viện:

• Hầu hết chương trình OpenCV cần cv.h và highgui.h. Sau đó để nhận dạng mặt chúng ta cần thêm cvaux.h. Phần còn lại của file header được thêm vào bởi những header cao nhất ( high-level headers).

• Linker thư viện lẫn tên của thư viện tĩnh được sử dụng liên kết tới cxcore.lib, cv.lib và highgui.lib. Sau đó để phục vụ cho quá trình nhận dạng mặt cần liên kết tới cvaux.lib. Tất cả thư viện này đều nằm trong thư mục “lib” của OpenCV.

e. Một số chương trình cơ bản: • Đọc và ghi hình ảnh:

Việc đọc một file ảnh, ta gọi hàm cvLoadImage. OpenCV hỗ trợ hầu hết các định dạng phổ biến như JPEG, PNG và BMP. Ta không cần

cung cấp các thông tin định dạng cvLoadImage() nhận diện định dạng file bằng cách đọc file header.

Việc ghi một ảnh vào file ta gọi hàm cvSaveImage(). Hàm này quyết định định dạng file ta sử dụng tử file ban đầu. Trong ví dụ này, file ban đầu có định dạng “png”, vì vậy nó sẽ ghi dữ liệu ảnh dạng PNG.

Cả cvLoadImage() và cvSaveImage() đều nằm trong modul HighGUI. Khi chúng ta đã kết thúc quá trình nhập ảnh và sử dụng xong hàm cvLoadImage(), chúng ta cần gọi hàm cvReleaseImage() như dòng 29. Hàm này trả về địa chỉ của điểm khi mà ta nhập vào bởi vì nó đảm bảo an tồn dữ liệu. Nó trả tự do cho cấu trúc ảnh nếu nó là khơng rỗng. Sau khi giải phóng nó, nó tạo một điểm ảnh bằng 0 ( image pointer)

Code ví dụ:

IplImage* cvLoadImage(const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR)

int cvSaveImage(const char* filename, const CvArr* image)

Input Video:

Chụp ảnh từ một webcam hoặc từ một thiệt bị hình ảnh số khác thật dễ dàng giống như chạy từ một file. Nó được gọi ra bởi hàm cvCaptureFromCAM(). Hàm này trả về một điểm đến một cấu trúc cvCapture. Ta không thể truy nhập và cấu trúc này ngay được. Thay vào đó, ta sẽ lưu trữ điểm này thơng qua hàm cvQueryFrame().

Sau khi kết thúc quá trình nhập video, gọi hàm cvReleaseCapture() để giải phóng mã nguồn video. Giống như cvReleaseImage(), ta trả địa chỉ địa chỉ của điểm Cvcapture về hàm cvReleaseImage().

Code ví dụ:

VideoCapture cap(0); // open the default camera if(!cap.isOpened()) // check if we succeeded return -1;

• Truy nhập giá trị điểm ảnh:

Cách dễ nhất để đọc điểm ảnh đơn là dùng hàm cvGet2D().

CvScalar cvGet2D(const CvArr*, int row, int col);

Hàm này có 3 thơng số là :

- Một con trỏ chứa dữ liệu ( CvArr*)

- Một mảng được xếp theo hang và theo cột

Dữ liệu chứa đựng có thể có cấu trúc IplImage.Cái hàng cao nhất của điểm ảnh có row =0 và hàng thấp nhất có row = chiều cao – 1.

typedef struct CvScalar {

double val[4]; }

CvScalar;

Giá trị của mỗi điểm ảnh cho mỗi kênh được nằm trong val[i]. Với ảnh đen trắng, val[0] chứa độ sáng của điểm ảnh.Ba giá trị khác được đặt ở giá trị 0. Với ảnh BGR thì blue = val[0], green = val[1] và red = val[2].

Ta có hàm bổ sung cvSetd() cho phép bạn chỉnh sửa giá trị điểm ảnh. Nó được khai báo như sau:

void cvSet2D(CvArr*, int row, int col, CvScalar);

• Chuyển đổi màu:

Dùng để chuyển đổi các định dạng màu sắc hoặc để tách lấy các vùng đen, vùng xám khi hiển thị:

Code ví dụ:

IplImage* GetThresholdedImage(IplImage* img) {

// Convert the image into an HSV image

IplImage* imgHSV = cvCreateImage(cvGetSize(img), 8, 3); cvCvtColor(img, imgHSV, CV_BGR2HSV);

IplImage* imgThreshed = cvCreateImage(cvGetSize(img), 8, 1);

// Values 20,100,100 to 30,255,255 working perfect for yellow at around 6pm

cvInRangeS(imgHSV, cvScalar(60, 100, 100), cvScalar(255, 255, 255), imgThreshed);

cvReleaseImage(&imgHSV); return imgThreshed;

}

• Tách nền xám trên ảnh hiển thị:

Dùng các Vector để tách các định dạng màu sắc khác nhau như tách các hình màu đỏ, màu vàng trên nền khác nhau và hiển thị là ảnh màu trắng trên nền đen.

Code ví dụ:

IplImage* channelBlue = cvCreateImage(cvGetSize(img), 8, 1); cvThreshold(channelRed, channelRed, 20, 255,

CV_THRESH_BINARY);

f. Các bước trong xử lý ảnh với OpnenCV: • Chụp ảnh

- Kết nối Camera với máy tính. Camera được sử dụng ở đây là Webcam Logitech.

- Sử dụng một hàm trong thư viện OpenCV để thực hiện công việc chụp ảnh

- Sau khi chụp ảnh xong ta cũng sử dụng một hàm trong OpenCV để lưu ảnh

• Tiền xử lý dữ liệu ảnh

Quá trình tiền xử lý dữ liệu ảnh bao gồm hai công việc sau: + Phối cảnh cho ảnh

+ Chuyển về ảnh xám và xác định lược đồ xám

o Phối cảnh cho ảnh: Ảnh sau khi chụp sẽ có một góc nghiêng nhất định so với mặt phẳng do đó cần phải thực hiện một công việc phối cảnh cho ảnh nhằm “xoay” và “kéo” ảnh thành ảnh trong mặt phẳng 2D. Việc này sẽ làm cho tỷ lệ, kích thước của ảnh giống như trong thực tế.

o Chuyển về ảnh xám và xác định lược đồ xám: Với ảnh màu thu được ta không thể tiến hành nhận dạng được ngay mà trước hết cần phải chuyển ảnh đã cho về ảnh xám

o Mỗi một phần tử ảnh có một cường độ sáng nhất định, cường độ sáng này được số hoá thành các mức xám và dựa vào các mức xám này ta sẽ chuyển ảnh thành ảnh xám. Lược đồ xám là lược đồ cung cấp thông tin về phân bố mức xám của ảnh, xác định xem ảnh là sáng hay tối.

• Nhị phân ảnh:

o Ảnh nhị phân là ảnh mà giá trị của các điểm ảnh chỉ có hai giá trị là 0 và 1 (trắng và đen)

o Để chuyển từ ảnh xám về ảnh nhị phân ta đặt một ngưỡng thích hợp để so sánh. Mức xám của ảnh sẽ được dùng để so sánh với giá trị ngưỡng này. Việc chọn ngưỡng là rất quan trọng, nếu chọn ngưỡng hợp lý thì ta có thể phân biệt được vật thể với nền và ngược lại. • Phân vùng ảnh: Sau khi thực hiện nhị phân ảnh, ta thu được một ảnh

gồm hai màu đen và trắng. Giá trị của các điểm ảnh chỉ là 0 và 1. Bước tiếp theo ta cần thực hiện công việc phân vùng ảnh nhằm phân biệt vật thể với nền và ngược lại. Thuật toán phân vùng ảnh dựa trên kỹ thuật đánh nhãn liên tiếp. Với kỹ thuật đánh nhãn liên tiếp ta có thể sử dụng ma trận mặt nạ 3x3 để quét lần lượt tất cả các điểm ảnh. Có 2 kỹ thuật có thể sử dụng ở đây:

- Mặt nạ với bốn điểm lân cận và tám điểm lân cận Quy ước khi quét ảnh:

- Nếu điểm ảnh có giá trị là 0 thì gọi là điểm ảnh nền - Nếu điểm ảnh có giá trị là 1 thì gọi là điểm ảnh nổi Ta chỉ đánh nhãn các điểm ảnh nổi

Quá trình đánh nhãn ảnh được thực hiện theo các bước sau:

Bước 1: Tiến hành quét lần lượt tất cả các điểm ảnh từ trái sang phải, từ

trên xuống dưới. Nếu gặp điểm ảnh nền thì bỏ qua, nếu gặp điểm ảnh nổi thì tiến hành đánh nhãn. Trước khi đánh nhãn cho mỗi điểm ảnh nổi, ta cần quan tâm đến giá trị của điểm ảnh phía trên và điểm ảnh bên trái của điểm ảnh ta đang xét. Nếu các điểm ảnh này đã được đánh nhãn thì điểm ảnh đang xét được đánh nhãn trùng với điểm ảnh trên hoặc điểm ảnh bên trái đó. Nếu các điểm ảnh bên trên và điểm ảnh bên trái là các điểm ảnh nền thì ta đánh nhãn mới cho điểm ảnh đang xét.

Bước 2: Sau khi đánh nhãn tất cả các điểm ảnh nổi, ta cần nhóm các

điểm ảnh ở gần nhau nhưng lại được đánh nhãn khác nhau lại với nhau. Bước 3: Thực hiện quét lại và đánh nhãn mới cho các nhóm điểm ảnh vừa được nhóm lại ở trên.

• Nhận dạng mục tiêu: Là q trình xác định chính xác vật thể cần nhận dạng. Phương pháp được sử dụng ở đây là nhận dạng dựa vào đường biên vật thể. Từ biên dạng này ta sẽ xác định được các đỉnh, các cạnh và cả tâm của vật thể. Phương pháp phổ biến hiện nay là phương pháp Cany.

Nội dung phương pháp Cany như sau:

Bước 1: Làm trơn ảnh bằng bộ lọc Gauss để loại bỏ ảnh hưởng của

nhiễu

Bước 2: Tính gradient của các phần tử ảnh và hướng của gradient

• Xác định tâm vật thể: Sau khi đã nhận dạng được vật thể trong không gian làm việc, ta có thể kẻ các đường bao quanh vật và dễ dàng xác định được tâm của vật thể.

Code ví dụ:

// ThresholdingAdvanced.cpp : Defines the entry point for the console #include "stdafx.h"

#include <cv.h> #include <highgui.h>

int _tmain(int argc, _TCHAR* argv[]) {

IplImage* img = cvLoadImage("Thresholding.jpg");

IplImage* channelRed = cvCreateImage(cvGetSize(img), 8, 1);

IplImage* channelGreen = cvCreateImage(cvGetSize(img), 8, 1);

IplImage* channelBlue = cvCreateImage(cvGetSize(img), 8, 1);

cvSplit(img, channelBlue, channelGreen, channelRed, NULL);

cvAdd(channelBlue, channelGreen, channelGreen); cvSub(channelRed, channelGreen, channelRed); cvThreshold(channelRed, channelRed, 20, 255, CV_THRESH_BINARY); cvNamedWindow("original"); cvNamedWindow("red"); cvShowImage("original", img); cvShowImage("red", channelRed); cvWaitKey(0); return 0; }

II.5.2.Cài đặt OpenCV Board Tiny6410: a. Mã nguồn

Mã nguồn hồn tồn miễn phí Download tại:

http://sourceforge.net/projects/opencvlibrary/

b. Toolchain:

• X86: gcc,g++

• Arm: arm-linux-gcc, arm-linux-g++ c. Cài đặt và hiện thực trên OpenCV trên Linux:

X86:

• Visual Studio • Linux

• Mac OS ARM:

Để porting thư viện OpenCV cho board ARM Tiny6410 trước tiên hết ta phải build gói thư viện OpenCV2.0 đã được down về trên Website. Lưu ý là thư viện OpenCV2.0 hiện tại build khá dễ dàng và ít gặp lỗi. Sau khi build thành cơng thư viện sẽ nằm trong /usr/local—và gồm có 4 thư mục như sau: bin+lib+include+share. Sau đó ta có thể copy thư mục này xuống board thơng qua ftp, sdcard…

• u cầu hệ thống:

 Fedora 14, Linux Kernel 2.35 hoặc về sau nữa

 Một số thư viện khác như: zlib, libpng, libjpeg, libz • Các bước tiến hành:

 Đảm bảo rằng Fedora đã cài toolchain arm-linux-gcc

 Giải nén source code

 Thiết lập config build như sau: ./configure --host=arm-linux

--without-carbon --without-quicktime --without-1394libs --without-ffmpeg --without-python --without-swig --without-gtk --enable-static --enable-shared

 Command : make & make install

 Build khơng lỗi thì xem như đã thành cơng được phần tạo thư viện compile cho source code trên máy tính.

 Copy thư mục thư viện gồm 4 thư mục con như trên xuống board tương ứng với các thư mục trên máy tính.

 Tạo file source code để test chương trình như sau:

// CameraCapture.cpp : Defines the entry point for the console application.

//

#include <cv.h> #include <highgui.h> #include <stdio.h>

// A Simple Camera Capture Framework int main() {

printf("\nok1");

CvCapture* capture = cvCaptureFromCAM(0); printf("\nok1");

if ( !capture ) {

printf( "ERROR: capture is NULL \n" ); getchar(); return -1; } printf("\nok1"); int i=0; while ( i<50 ) {

// Get one frame

IplImage* frame = cvQueryFrame( capture );

if ( !frame ) {

printf( "ERROR: frame is null...\n" );

getchar(); break;

} i++; printf("\nok2"); cvReleaseCapture( &capture ); printf("\nok1\n"); return 0; }

 Dùng command build file CameraCapture.cpp như sau:

arm-linux-g++ CameraCapture.cpp -o CameraCapture-arm -I/usr/local/include/opencv /usr/local/lib/libhighgui.so \

/usr/local/lib/libcvaux.so /usr/local/lib/libcv.so

Một phần của tài liệu Khóa luận wifi robot board tiny 6410 (Trang 71 - 81)

Tải bản đầy đủ (DOCX)

(113 trang)
w