Although edge detection algorithms, such as the former, can detect the pixels at the contour boundary based on differences between pixels, they do not regard the contour as a whole, therefore, this chapter will learn how to assemble these pixels into outlines. Memory storage and sequence data structures are involved. Memory storage is the technology used to access the memory when opencv creates dynamic objects, the sequence is required for contour processing, so you must be familiar with these two things.
1. The underlying implementation is a two-way linked list consisting of many memory blocks of the same size.
Create a memory block
Cvmemstorage * cvcreatememstorage (INT block_size = 0 );
The size of the storage block is measured in bytes. If the size is 0 bytes, set the block to the default value-the current default size is 64 KB.
The cvcreatememstorage function creates a memory block and returns a pointer to the first part of the block. At first, the storage block is empty. All the domain values of the header (that is, header) are 0, except for block_size.
Release memory blocks
Void cvreleasememstorage (cvmemstorage ** storage );
Pointer to the released storage Block
The cvreleasememstorage function releases all storage (memory) blocks or returns them to their respective parents (if needed ). Next, release the header block (that is, release the block pointed to by the header pointer head = free (head) and clear the pointer pointing to the block (that is, head = NULL ). Clear the child blocks before releasing them as parent blocks.
Clear memory block
Void cvclearmemstorage (cvmemstorage * storage );
The function cvclearmemstorage places the top of the block to the header of the block (Note: Clear the content stored in the block ). This function does not release the memory (only clears the memory ). If the memory block has a parent memory block (I .e., a memory block has a parent-child relationship with it), the function returns all the blocks to its parent.(It only returns the released memory to the memory instead of the system)
Allocate to memory buffer in the storage Block
Void * cvmemstoragealloc (cvmemstorage * storage, size_t size );
The buffer size.
The cvmemstoragealloc function allocates a memory buffer in the storage block. The size of the buffer cannot exceed the size of the memory block. Otherwise, a running error occurs. The buffer address is changed to the cv_struct_align byte (currently sizeof (double )).
1. The sequence is implemented as a dual-end queue deque at the underlying layer, which enables fast random access and quick deletion of top elements.
2. Structure Definition
The element sequence can be dynamically increased (opencv_1.0 has changed, see cxtypes. h) growable sequence of Elements
# 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
Structure cvseq is the basis of all opencv dynamic data structures. In Version 1.0, the first six members are stripped out to define a macro. The extension of the cvseq structure with additional parameters is simplified through the unusual macro definition. To extend cvseq, you can define a new data structure or put the cvseq fields included in the macro cv_sequence_fields () into your custom domain.
There are two types of sequences: dense sequence and sparse sequence. Dense sequences are derived from cvseq, which are used to represent scalable one-dimensional arrays-vectors, stacks, queues, and dual-end queues. There is no gap between data (I .e. continuous storage) -- if an element is deleted from the middle of the sequence or new elements are inserted into the sequence (not both ends ), then the related elements behind this element will be moved. Sparse sequences are derived from cvset, which will be discussed in detail later. They are a sequence composed of nodes. Each node is either occupied space or empty and specified by the flag. These sequences are used as unordered data structures, such as point sets, graphs, and hash tables.
The header_size (structure size) field contains the actual size of the sequence header node, which is greater than or equal to sizeof (cvseq ). when this macro is used in a sequence, it should be equivalent to sizeof (cvseq). If this macro is used in another structure, such as cvcontour, the size of the structure should be greater than sizeof (cvseq); The h_prev, h_next, v_prev and v_next can be used to create hierarchies of different sequences. Domain h_prev and h_next point to the previous and next sequences of the same hierarchy, while domain v_prev and v_next point to the previous and next sequences in the vertical direction, that is, father and child.
Domain first points to the first sequence, and the block structure is described later.
The total field contains the total number of elements of the dense sequence and the number of nodes allocated by the sparse sequence.
The high 16-bit description of the flags domain (including) specific dynamic structure types (cv_seq_magic_val indicates dense sequences, and cv_set_magic_val indicates sparse sequences). It also contains various information.
The lower cv_seq_eltype_bits BIT contains the ID (identifier) of the element type ). Most processing functions do not use the element type, but use the element size stored in elem_size. If the sequence contains data in cvmat, the element type matches that in cvmat. For example, cv_32sc2 can be used as a point sequence in two-dimensional space, cv_32fc1 is a sequence composed of floating-point numbers. Use the macro cv_seq_eltype (seq_header_ptr) to obtain the type of elements in the sequence. Function judgment for processing numeric sequences: ELEM. size is equivalent to the size of sequence elements. Besides
Additionally, there are several additional types defined in Header cvtypes. h.
Create a sequence
Cvseq * cvcreateseq (INT seq_flags, int header_size,
Int elem_size, cvmemstorage * storage );
Symbol of the sequence. If the sequence is not passed to any function that uses a specific sequence, set it to 0. Otherwise, select an appropriate type from the predefined sequence type.
The size of the sequence header; it must be greater than or equal to sizeof (cvseq). If a type or its extension is specified, this type must be suitable for the header size of the base class.
The size of the element, in bytes. The size must be consistent with the sequence type. For example, for a sequence of points, element type cv_seq_eltype_point should be specified. The elem_size parameter must be equivalent to sizeof (cvpoint ).
The cvcreateseq function creates a sequence and returns a pointer to the sequence. The function allocates the sequence header in the storage block as a continuous body, and sets the flags field, elem_size field, header_size field, and Storage Field Values of the structure as the passed values, set delta_elems to the default value (you can use the cvsetseqblocksize function to assign a value to it again) to clear other header fields, including the space of the first sizeof (cvseq) bytes.
Void cvclearseq (cvseq * SEQ );
Function cvclearseq deletes all elements in the sequence. The function does not return the memory to the memory. When a new element is added to the sequence, the memory can be reused. The time complexity of the function is O (1 ).
Returns the index of the element in the sequence.
Int cvseqelemidx (const cvseq * seq, const void * element, cvseqblock ** block = NULL );
Pointer to the element in the sequence
Optional. If it is not null, the address of the block containing the element is stored.
The cvseqelemidx function returns the index of an element. If the element does not exist in this sequence, a negative number is returned.
Data in slice, copy, and move sequences can be understood by referring to the operation methods of containers such as vector, which is relatively simple.
You can write a simple routine.
Create a header for each sequence fragment
Cvseq * cvseqslice (const cvseq * seq, cvslice slice,
Cvmemstorage * storage = NULL, int copy_data = 0 );
Part Sequence Blocks
Destination storage space for storing new sequences and copying data (if needed. If it is null, the function uses a bucket that contains the input data.
Indicates whether to copy the element. If copy_data! If copy_data = 0, you do not need to copy it.
The cvseqslice function creates a sequence that represents a specific part of the input sequence (slice ),. The new sequence either shares an element with the original sequence or has its own copy. Therefore, if someone needs to process this sequence, but the function does not have the slice parameter, use this function to obtain the sequence ..