Ảnh lối vào và biểu diễn kết quả sau khi tách đƣờng bao

Một phần của tài liệu (LUẬN văn THẠC sĩ) thuật toán phát hiện chuyển động (Trang 67 - 72)

Ở đây, ta biểu diễn các đƣờng bao bằng các kí hiệu cX và hX. Trong đó, “c” nghĩa là các đƣờng bao, “h” nghĩa là các lỗ trống và X đại diện cho số hiệu của đƣờng bao hay lỗ trống đó. Một số đƣờng bao đƣợc biểu diễn bằng đƣờng đứt nét là bao ngoài của vùng trắng (vùng có giá trị khác 0). Chú ý là OpenCV và cvFindContours() phân biệt giữa đƣờng bao ngoài và các đƣờng bao trong (các đƣờng chấm chấm) biểu diễn cho các lỗ trống (các vùng giá trị 0). Khái niệm đƣợc đề cập ở đây rất quan trọng trong nhiều ứng dụng. Chính vì lý do này mà OpenCV đã mã hóa mối liên hệ liên quan thông qua cấu trúc cây đƣờng bao.

Ứng với ví dụ trên thì cây đƣờng bao sẽ có 1 đƣờng bao – nút- gốc là c0 cùng với 2 lỗ trống con là h00 và h01. int cvFindContours( IplImage* img, CvMemStorage* storage, CvSeq** firstContour,

int headerSize = sizeof(CvContour),

CvContourRetrievalMode mode = CV_RETR_LIST, CvChainApproxMethod method

= CV_CHAIN_APPROX_SIMPLE );

Hàm xác định đƣờng bao với ảnh lối vào 8 bit đơn kênh sẽ đƣợc chuyển thành nhị phận để xử lý. Chú ý là nếu muốn sử dụng ảnh gốc cho các mục đích khác thì nên sao chép ảnh đó rồi truyền bản sao đó vào hàm tìm đƣờng bao để đảm bảo không bị thay đổi nội dung. Tham số thứ 2 là không gian nhớ dùng để lƣu trữ đƣờng bao, đƣợc cấp phát bởi hàm cvCreateMemStorage(). Tham số tiếp theo là con trỏ trả về phần tử đầu tiên của điểm thuộc đƣờng bao kết quả tìm đƣợc. Phần tử này nên đƣợc cấp phát bởi cvFindContours() nên ta sử dụng cách truyền vào hàm nhƣ sau:

CvSeq* firstContour = NULL;

cvFindContours( …, &firstContour, … );

Tham số headerSize giúp cvFindContours() xác định đối tƣợng sẽ đƣợc cấp phát bộ nhớ và thƣờng đƣợc đặt là sizeof(CvContour) hoặc sizeof(CvChain). Cuối cùng là tham số mode và method xác định chính xác các hàm sẽ tính và xây dựng đƣờng bao. Giá trị mode có thể là CV_RETR_EXTERNAL, CV_RETR_LIST, CV_RETR_CCOMP, hoặc CV_RETR_TREE.

Một điều chúng ta cần phải nhớ là đƣờng bao là một trƣờng hợp đặc biệt của dãy. Nó là một dãy các điểm biểu diễn một dạng nào đó trong không gian ảnh. Việc xử lý với chuỗi các điểm ảnh này đƣợc thực hiện bởi các hàm sau:

CvArr* image,

CvMemStorage* storage, CvSeq** first_contour,

int header_size = sizeof(CvContour), int mode = CV_RETR_LIST,

int method = CV_CHAIN_APPROX_SIMPLE, CvPoint offset = cvPoint(0,0)

);

CvContourScanner cvStartFindContours( CvArr* image,

CvMemStorage* storage,

int header_size = sizeof(CvContour), int mode = CV_RETR_LIST,

int method = CV_CHAIN_APPROX_SIMPLE, CvPoint offset = cvPoint(0,0)

); CvSeq* cvFindNextContour( CvContourScanner scanner ); void cvSubstituteContour( CvContourScanner scanner, CvSeq* new_contour ); CvSeq* cvEndFindContour(

CvContourScanner* scanner );

CvSeq* cvApproxChains( CvSeq* src_seq,

CvMemStorage* storage,

int method = CV_CHAIN_APPROX_SIMPLE, double parameter = 0,

int minimal_perimeter = 0, int recursive = 0

);

Đầu tiên là hàm cvFindContours() đã đƣợc đề cập ở phần trên. Hàm thứ hai đƣợc nói tới là cvStartFindContours(). Hàm này khá giống với cvFindContours() ngoại trừ việc thay vì tìm và biểu diễn tất cả các đƣờng bao vào một cấu trúc phân cấp thì nó tìm lần lƣợt các đƣờng bao từng lƣợt một. Lời gọi cvStartFindContours() sẽ trả về CvSequenceScanner chứa các thông tin trạng thái về các phần đã và chƣa đƣợc đọc ra. Chúng ta có thể gọi cvFindNextContour() để tiếp tục quét đƣờng bao cho đến hết thì sẽ trả về giá trị NULL. cvSubstituteContour() cho phép đƣờng bao đang đƣợc trỏ bởi CvSequenceScanner có thể đƣợc thay thế bởi một đƣờng bao khác. Hàm này có thể đƣợc sử dụng để xóa bỏ đƣờng bao nếu new_contour thiết lập bằng NULL. Cuối cùng là cvEndFindContour() để thiết lập giá trị hoàn tất việc tìm đƣờng bao. Giá trị con trỏ cvEndFindContour() trả về chính là phần tử đầu tiên của dãy – các điểm thuộc đƣờng bao.

Ta có thể dễ dàng biểu diễn đƣờng bao trên ảnh “img” bằng lời gọi: void cvDrawContours(

CvArr* img, CvSeq* contour,

int max_level, int thickness = 1, int line_type = 8,

CvPoint offset = cvPoint(0,0) );

2.3.4 Theo dõi chuyển động

Phƣơng pháp sử dụng các mẫu trong theo dõi chuyển động đã đƣợc phát triển trong phòng thí nghiệm MIT Media bởi Bobick và Davis. Đây là một phƣơng pháp hiệu quả để theo dõi các chuyển động thông thƣờng và thƣờng đƣợc sử dụng trong các ứng dụng nhận dạng chuyển động, cử chỉ. Phƣơng pháp này yêu cầu một một vệt ảnh tạo ra bởi đối tƣợng để lấy thông tin về chuyển động của nó. Vệt ảnh này có thể thực hiện bằng một số cách nhƣ sau:

 Sử dụng cách máy quay tĩnh đặc ở vị trí thích hợp sau đó lấy sai khác giữa các khung hình. Cách này sẽ đem lại cho chúng ta cạnh của các đối tƣợng chuyển động.

 Sử dụng đặc tính sắc độ. Ví dụ: nếu chúng ta biết màu nền là xanh lá cây sáng thì việc lấy vật thể chỉ đơn giản là tất cả các phần khác màu nền đó.  Sử dụng các kĩ thuật tạo vệt tích cực. Ví dụ tạo ra một bức tƣờng đƣợc

chiếu ánh sáng hồng ngoại. Khi đó mọi vật thể chuyển động qua đều là vệt.

 Sử dụng mô hình nền: Đây cũng chính là phƣơng pháp đã đƣợc đề cập ở phần 1 và đƣợc ứng dụng trong xây dựng ứng dụng thuật toán liên quan ở phần 3.

Giả sử sau quá trình tách nền chúng ta đã có một đối tƣợng cần theo dõi đƣợc biểu diễn bằng khối hình chữ nhật trắng. Chúng ta sẽ sử dụng màu trắng để mô tả tất cả các điểm ảnh nhận giá trị thực của đối tƣợng tại hiện tại. Khi hình chữ nhật chuyển động, một vệt mới đƣợc ghi nhận tại vị trí mới. Hình chữ nhật cũ sẽ đƣợc biểu diễn bằng hình chữ nhật tối hơn. Nhƣ vậy sau một thời gian quan sát ta sẽ có một chuỗi các vệt ghi lại chuyển động của vật thể đƣợc hiểu nhƣ là ảnh lịch sử chuyển động của nó.

Một phần của tài liệu (LUẬN văn THẠC sĩ) thuật toán phát hiện chuyển động (Trang 67 - 72)

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

(86 trang)