Cấu trúc động

Một phần của tài liệu biên dịch tài liệu hướng dẫn sử dụng bộ thư viện nguồn mở opencv (Trang 59)

2. Kinh nghiệ m:

1.3 Cấu trúc động

CvMemStorage

Gia tăng bộ nhớ lưu trữ. typedef struct CvMemStorage {

struct CvMemBlock* top; * / * khối bộ nhớ hiện tại trên cùng của ngăn xếp * / struct CvMemStorage* parent; / * vay mới từ khối * /

int block\_size; / * kích thước khối * /

int free\_space; / * miễn phí không gian trong khối \ {đầu} texttt (theo byte) * / } CvMemStorage;

Bộ nhớ lưu trữ là một cấu trúc ở mức độ thấp được sử dụng để lưu trữ các cấu trúc dữ liệu dynamicly như trình tự, đường nét, đồ thị, phân khu, vv, được tổ chức như một danh sách của các khối bộ nhớ của bằng kích thước dưới cùng lĩnh vực là sự khởi đầu của danh sách các khối và các đầu khối hiện đang được sử dụng, nhưng không nhất thiết phải là khối cuối cùng của danh sách. Tất cả các khối từ phía dưới và phía trên, không bao gồm thứ hai, được coi là hoàn toàn bị chiếm đóng, tất cả các khối từ đầu và ngăn chặn cuối cùng, không bao gồm hàng đầu,

được coi là miễn phí và đầu tự nó là một phần ocupied - miễn phí không gian chứa số lượng byte miễn phí còn lại vào cuối hàng đầu.

Một bộ nhớ đệm mới có thể được phân bổ một cách rõ ràng theo Hàm cvMemStorageAlloc hoặc implicitly Hàm cấp cao hơn, chẳng hạn như cvSeqPush, cvGraphAddEdge, vv, luôn luôn bắt đầu kết thúc của khối hiện tại nếu nó phù hợp với có. Sau khi phân bổ, không gian miễn phí được giảm đi kích thước của bộđệm được phân bổ cộng với một số padding để giữ sự liên kết thích hợp. Khi được phân bổ bộ đệm không phù hợp với thành phần có sẵn của đầu, khối lưu trữ tiếp theo từ danh sách được thực hiện như không gian hàng đầu và miễn phí được thiết lập lại kích thước khối toàn bộ trước khi việc phân bổ.

Nếu không có các khối tự do hơn, một khối mới được giao (hoặc vay từ cha mẹ, xem ) cvCreateChildMemStorage và thêm vào cuối danh sách. Vì vậy, lưu trữ các hoạt động như một chồng phía dưới chỉ ra dưới cùng của ngăn xếp và một đôi (hàng đầu, không gian miễn phí) cho thấy đầu của stack. Đầu ngăn xếp có thểđược lưu thông qua cvSaveMemStoragePos, phục hồi thông qua cvRestoreMemStoragePos, hoặc thiết lập lại thông qua cvClearStorage.

CvMemBlock Bộ nhớ lưu trữ khối.

typedef struct CvMemBlock {

struct CvMemBlock* prev; struct CvMemBlock* next; } CvMemBlock;

CvMemBlock cấu trúc đại diện cho một khối duy nhất của bộ nhớ lưu trữ. Các dữ liệu thực tế

trong các khối bộ nhớ theo tiêu đề, đó là, byte thứ i của khối bộ nhớ có thểđược lấy ra với biểu thức ((char*)(mem_block_ptr+1))[i]. Tuy nhiên, có bình thường không cần phải truy cập vào các lĩnh vực cấu trúc lưu trữ trực tiếp.

CvMemStoragePos Bộ nhớ lưu trữ vị trí.

typedef struct CvMemStoragePos {

CvMemBlock* top; int free\_space; } CvMemStoragePos;

Cấu trúc mô tả ở trên các cửa hàng vị trí của đỉnh ngăn xếp có thể được lưu thông qua cvSaveMemStoragePos và phục hồi thông qua cvRestoreMemStoragePos.

CvSeq

Growable trình tự của các yếu tố. #define CV_SEQUENCE\_FIELDS() \ int flags; /* micsellaneous flags */ \

int header_size; /* size of sequence header */ \ struct CvSeq* h_prev; /* previous sequence */ \ struct CvSeq* h_next; /* next sequence */ \

struct CvSeq* v_prev; /* 2nd previous sequence */ \ struct CvSeq* v_next; /* 2nd next sequence */ \ int total; /* total number of elements */ \

int elem_size;/* size of sequence element in bytes */ \ char* block_max;/* maximal bound of the last block */ \ char* ptr; /* current write pointer */ \

int delta_elems; /* how many elements allocated when the sequence grows (sequence granularity) */ \

CvMemStorage* storage; /* where the seq is stored */ \ CvSeqBlock* free_blocks; /* free blocks list */ \

CvSeqBlock* first; /* pointer to the first sequence block */ typedef struct CvSeq

{

CV_SEQUENCE_FIELDS() } CvSeq;

CvSeq cấu trúc là cơ sở cho tất cả các của OpenCV cấu trúc dữ liệu động.

Một định nghĩa khác thường thông qua một macro trợ giúp đơn giản hóa phần mở rộng của CvSeq cấu trúc với các thông số bổ sung. Để mở rộng CvSeq người sử dụng có thểđịnh nghĩa một cấu trúc mới, đưa người sử dụng xác định các lĩnh vực sau khi tất cả các lĩnh vực CvSeq

được bao gồm thông qua các trình tự LĨNH VỰC vĩ mô CV ().

Có hai loại chuỗi - dày đặc và thưa thớt. Các loại cơ sở cho chuỗi dày đặc, CvSeq và trình tự

như vậy được sử dụng để đại diện cho mảng growable 1d - vectơ, ngăn xếp, hàng đợi, và deques. Họ không có khoảng trống ở giữa - nếu một phần tử được lấy ra từ giữa hay đưa vào giữa trình tự, các yếu tố từ khi kết thúc gần hơn được thay đổi. Thưa thớt trình tự có CvSet như

là một lớp cơ sở và họ sẽ được thảo luận chi tiết hơn. Họ là trình tự của các nút, mỗi có thể được hoặc chiếm hoặc miễn phí nhưđược chỉ ra bởi lá cờ nút. Như vậy trình tựđược sử dụng cho dữ liệu không có thứ tự các cấu trúc như bộ của các yếu tố, đồ thị, bảng băm và vv.

header size lĩnh vực có chứa các kích thước thực tế của tiêu đề trình tự và cần phải được lớn hơn hơn hoặc bằng sizeof(CvSeq).

Các h_prev, h_next, v_prev, v_next có thể được sử dụng để tạo ra các cấu trúc phân cấp từ

riêng biệt trình tự. Các trường h trước và h điểm tiếp theo đến trước đó và trình tự tiếp theo trên cùng một cấp độ thứ bậc, trong khi các lĩnh vực v trước và v tiếp theo điểm trước đó và trình tự tiếp theo trong hướng thẳng đứng, có nghĩa là, cha mẹ và đứa con đầu tiên của mình. Nhưng đây là những chỉ tên và các con trỏ có thểđược sử dụng theo một cách khác.

Trường đầu tiên first để khối thứ tựđầu tiên, có cấu trúc được mô tả dưới đây.

Trường total có số lượng thực tế của các yếu tố trình tự dày đặc và số lượng của phân bổ các nút trong một chuỗi thưa thớt.

Trường flags có chứa các loại chữ ký đặc biệt năng động (CV_SEQ_MAGIC_VAL dày đặc trình tự và CV_SET_MAGIC_VAL cho chuỗi thưa thớt) trong 16 bit cao nhất và miscella

neous thông tin về trình tự. Thấp nhất của CV_SEQ_ELTYPE_BITS bit chứa các ID của loại yếu tố. Hầu hết các Hàm xử lý chuỗi không sử dụng loại yếu tố mà là elem_size được lưu giữ

trong kích thước Elem. Nếu chuỗi có chứa các dữ liệu số một của CvMat loại sau đó các loại yếu tố phù hợp để loại yếu tố CvMat tương ứng, ví dụ như, CV_32SC2

có thể được sử dụng cho một chuỗi các điểm 2D, CV_32FC1 cho các chuỗi giá trị dấu chấm

động, v.v. CV_SEQ_ELTYPE (seq_header_ptr) vĩ mô lấy các loại của các yếu tố trình tự. Chế

biến Hàm làm việc với chuỗi số kiểm tra xem kích thước Elem bằng mà tính từ kích thước phần tử loại. Bên cạnh đó các loại CvMat tương thích, có rất ít loại yếu tố thêm quy định tại tiêu đề cvtypes.h:

Các loại tiêu chuẩn của các yếu tố trình tự

#define CV_SEQ_ELTYPE_POINT CV_32SC2 /* (x,y) */

#define CV_SEQ_ELTYPE_CODE CV_8UC1 /* freeman code: 0..7 */ #define CV_SEQ_ELTYPE_GENERIC 0 /* unspecified type of

sequence elements */

#define CV_SEQ_ELTYPE_PTR CV_USRTYPE1 /* =6 */

#define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /* &elem: pointer to element of other sequence */

#define CV_SEQ_ELTYPE_INDEX CV_32SC1 /* #elem: index of element of some other sequence */

#define CV_SEQ_ELTYPE_GRAPH_EDGE CV_SEQ_ELTYPE_GENERIC /* &next_o, &next_d, &vtx_o, &vtx_d */

#define CV_SEQ_ELTYPE_GRAPH_VERTEX CV_SEQ_ELTYPE_GENERIC /* first_edge,

&(x,y) */

#define CV_SEQ_ELTYPE_TRIAN_ATR CV_SEQ_ELTYPE_GENERIC /* vertex of the binary tree */

#define CV_SEQ_ELTYPE_CONNECTED_COMP CV_SEQ_ELTYPE_GENERIC /* connected

component */

#define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /* (x,y,z) */ CV_SEQ_KIND_BITS bit chỉđịnh các loại trình tự:

Các loại tiêu chuẩn của Sequences

/* Chung (không xác định) của chuỗi */#define CV_SEQ_KIND_GENERIC (0 << CV_SEQ_ELTYPE_BITS)

/* dense sequence suntypes */

#define CV_SEQ_KIND_CURVE (1 << CV_SEQ_ELTYPE_BITS) #define CV_SEQ_KIND_BIN_TREE (2 << CV_SEQ_ELTYPE_BITS) /* sparse sequence (or set) subtypes */

#define CV_SEQ_KIND_GRAPH (3 << CV_SEQ_ELTYPE_BITS) #define CV_SEQ_KIND_SUBDIV2D (4 << CV_SEQ_ELTYPE_BITS)

Các bit còn lại được sử dụng để xác định các tính năng khác nhau cụ thể với các loại trình tự

nhất định và

yếu tố loại. Ví dụ, các đường cong làm bằng điểm (CV SEQ HÌNH THỨC ĐƯỜNG CONG | CV SEQ ELTYPE POINT),

cùng với lá cờ CV SEQ FLAG CLOSED, thuộc về loại CV SEQ đa giác, hoặc nếu các lá cờ

được sử dụng, kiểu phụ của nó. Nhiều Hàm xử lý đường viền kiểm tra các loại của chuỗi đầu vào

và báo cáo một lỗi nếu họ không hỗ trợ kiểu này. Cvtypes.h tập tin lưu trữ danh sách đầy đủ

của

tất cả các loại hỗ trợ được xác định trước chuỗi và macro trợ giúp được thiết kế để có được những loại chuỗi

các tài sản khác. Định nghĩa của các khối xây dựng của các chuỗi có thể được tìm thấy dưới

đây.

CvSeqBlock

Khối chuỗi liên tục.

typedef struct CvSeqBlock {

struct CvSeqBlock* prev; /* previous sequence block */ struct CvSeqBlock* next; /* next sequence block */ int start_index; /* index of the first element in the block + sequence->first->start_index */

int count; /* number of elements in the block */

char* data; /* pointer to the first element of the block */ } CvSeqBlock;

Khối Trình tự lập một danh sách liên kết đôi tròn, vì vậy các con trỏ trước và tiếp theo là không bao giờ NULL và điểm trước đó và ngăn chặn các trình tự tiếp theo trong chuỗi. Nó có nghĩa là

tiếp theo của khối cuối cùng là khối đầu tiên và trước của khối đầu tiên là khối cuối cùng. Các trường

startIndex và đếm để theo dõi vị trí khối trong trình tự. Ví dụ, nếu

trình tự bao gồm 10 yếu tố và phân chia thành ba khối 3, 5, và 2 yếu tố, và khối đầu tiên có startIndex tham số = 2, sau đó cặp (startIndex, count) trình tự các khối (2,3), (5, 5), và (10, 2) tương ứng. StartIndex tham số của khối đầu tiên thường là 0, trừ khi một số yếu tốđã được đưa vào đầu của chuỗi.

CvSlice

Một lát trình tự. typedef struct CvSlice {

int start_index; int end_index; } CvSlice;

inline CvSlice cvSlice( int start, int end );

#define CV_WHOLE_SEQ_END_INDEX 0x3fffffff

#define CV_WHOLE_SEQ cvSlice(0, CV_WHOLE_SEQ_END_INDEX) /* calculates the sequence slice length */

int cvSliceLength( CvSlice slice, const CvSeq* seq );

Một số Hàm hoạt động trên các trình tự phải mất một tham số lát CvSlice là

mười thiết lập trình tự toàn bộ (CV TOÀN SEQ) theo mặc định. Một trong các startIndex endIndex có thểđược tiêu cực hoặc vượt quá độ dài chuỗi, startIndex bao gồm, và endIndex

là một ranh giới độc quyền. Nếu chúng bằng nhau, cắt miếng được coi là rỗng (tức là, không ele

ments). Bởi vì trình tựđang được coi là cấu trúc hình tròn, lát có thể lựa chọn một vài yếu tố

vào cuối của một chuỗi tiếp theo là một vài yếu tốởđầu của chuỗi. Đối với cũ

phong phú, cvSlice (-2, 3) trong trường hợp của một chuỗi 10-yếu tố sẽ chọn một slice 5 phần tử,

có tiền cuối cùng (8), (9), đầu tiên (0), thứ hai (1Th) và thứ ba (2) yếu tố.

Các Hàm bình thường hóa các đối số slice trong các cách sau: đầu tiên cvSliceLength, được gọi là

xác định độ dài của slice, sau đó, startIndex của slice được chuẩn hóa tương tự như các ar gument cvGetSeqElem (tức là, chỉ số tiêu cực được phép). Lát thực tếđể xử lý bắt đầu từ

startIndex bình thường và kéo dài các yếu tố cvSliceLength (một lần nữa, giả sử chuỗi là một cấu trúc tròn).

Nếu một Hàm không chấp nhận một đối số slice, nhưng bạn muốn quá trình chỉ là một phần của

trình tự, trình tự phụ có thểđược chiết xuất bằng cách sử dụng Hàm cvSeqSlice, hoặc được lưu trữ vào một

liên tục đệm với CvtSeqToArray (tùy chọn, theo sau bởi cvMakeSeqHeaderForArray).

CvSet

Bộ sưu tập của các nút. typedef struct CvSetElem {

int flags; /* it is negative if the node is free and zero or positive otherwise */ struct CvSetElem* next_free; /* if the node is free, the field is a

pointer to next free node */ }

CvSetElem;

#define CV_SET_FIELDS() \

CV_SEQUENCE_FIELDS() /* inherits from [#CvSeq CvSeq] */ \ struct CvSetElem* free_elems; /* list of free nodes */

typedef struct CvSet {

CV_SET_FIELDS() } CvSet;

CvSet cấu trúc là cơ sở cho cấu trúc dữ liệu OpenCV thưa thớt.

Như sau tuyên bố trên, CvSet thừa hưởng từ CvSeq và nó cho biết thêm elems miễn phí

lĩnh vực, mà là một danh sách các nút miễn phí, với nó. Mỗi nút thiết lập, cho dù miễn phí hay không, là một phần tử của

cơ bản trình tự. Trong khi có không hạn chế về các yếu tố của chuỗi dày đặc, các thiết lập (Và có nguồn gốc cấu trúc) các yếu tố phải bắt đầu với một trường số nguyên và có thể phù hợp với CvSetElem

cấu trúc, bởi vì hai lĩnh vực (một số nguyên theo sau bởi một con trỏ) được yêu cầu cho Orga nization của một nút thiết lập với danh sách của các nút tự do. Nếu một nút nào là miễn phí, lĩnh vực cờ là tiêu cực

(Bit quan trọng nhất, MSB, của lĩnh vực này được thiết lập), và miễn phí tới các điểm đến miễn phí tiếp theo

nút (nút đầu tiên được tham chiếu bởi trường elems miễn CvSet). Và nếu một nút là

chiếm, lĩnh vực cờ là tích cực và có chứa các chỉ số nút có thểđược lấy ra bằng cách sử dụng (thiết lập Elem-> cờ & CV SET Elem IDX MASK) các biểu thức, phần còn lại của nội dung nút

được xác định bởi người sử dụng. Đặc biệt, các nút bị chiếm đóng không liên kết với các nút miễn phí

được, vì vậy trường thứ hai có thểđược sử dụng cho liên kết như vậy cũng nhưđối với một số

mục đích khác nhau. Các

vĩ mô CV IS SET Elem (thiết lập Elem ptr) có thểđược sử dụng để xác định liệu các nút được chỉđịnh

là chiếm đóng hay không.

Ban đầu thiết lập và danh sách có sản phẩm nào. Khi một nút mới được yêu cầu từ thiết lập, nó

được thực hiện

từ danh sách của các nút, sau đó cập nhật. Nếu danh sách trống rỗng, một chuỗi mới

khối được cấp phát và tất cả các nút trong khối được tham gia vào danh sách các nút tự do. Như vậy,

tổng số lĩnh vực của bộ này là tổng số của các nút bị chiếm đóng và miễn phí. Khi một chiếm

đóng

nút được phát hành, nó được thêm vào danh sách các nút tự do. Các nút phát hành cuối cùng sẽ được chiếm đóng đầu tiên.

Trong CvSet OpenCV được sử dụng đểđại diện cho đồ thị (CvGraph), thưa thớt đa chiều mảng (CvSparseMat), và các phân khu phẳng CvSubdiv2D.

CvGraph

Định hướng đồ thị trọng unoriented.

#define CV_GRAPH_VERTEX_FIELDS() \ int flags; /* vertex flags */ \

struct CvGraphEdge* first; /* the first incident edge */ typedef struct CvGraphVtx

{

CV_GRAPH_VERTEX_FIELDS() }

CvGraphVtx;

#define CV_GRAPH_EDGE_FIELDS() \ int flags; /* edge flags */ \

float weight; /* edge weight */ \

struct CvGraphEdge* next[2]; /* the next edges in the incidence lists for staring (0) * /* and ending (1) vertices */ \

struct CvGraphVtx* vtx[2]; /* the starting (0) and ending (1) vertices */ typedef struct CvGraphEdge

{

CV_GRAPH_EDGE_FIELDS() }

CvGraphEdge;

CV_SET_FIELDS() /* set of vertices */ \ CvSet* edges; /* set of edges */

typedef struct CvGraph {

CV_GRAPH_FIELDS() }

CvGraph;

CvGraph cấu trúc là cơ sở cho các đồ thị được sử dụng trong OpenCV.

Cấu trúc đồ thị được thừa hưởng từ CvSet - trong đó mô tả các thuộc tính đồ thị thông thường và các đỉnh đồ thị, và có một thiết lập như là một thành viên - trong đó mô tả các cạnh đồ thị. Các đỉnh, cạnh, và các cấu trúc tiêu đề đồ thị được khai báo bằng cách sử dụng kỹ thuật tương tự như OpenCV khác thể mở rộng cấu trúc - thông qua các macro, đơn giản hóa việc mở rộng và tuỳ biến của các cấu trúc. Trong khi các cấu trúc đỉnh và cạnh không kế thừa từ CvSetElem một cách rõ ràng, đáp ứng cả hai điều kiện các yếu tố theo quy định: có một trường số nguyên trong đầu và phù hợp trong cấu trúc CvSetElem. Các lĩnh vực cờ được sử dụng để chỉ ra đỉnh chiếm đóng và cạnh cũng như cho các mục đích khác, ví dụ, đồ thị traversal (xem cvCreateGraphScanner et al.), do đó, nó là tốt hơn không sử dụng chúng trực tiếp.

Đồ thị được biểu diễn như là một tập hợp của các cạnh trong đó có một danh sách của các cạnh sự cố. Các

danh sách tới đối với các đỉnh khác nhau xen kẽđể tránh trùng lặp càng nhiều thông tin posssible.

Đồ thị có thể được định hướng hoặc unoriented. Trong trường hợp thứ hai không có distiction

Một phần của tài liệu biên dịch tài liệu hướng dẫn sử dụng bộ thư viện nguồn mở opencv (Trang 59)

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

(163 trang)