⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asequence.cpp

📁 微软的基于HMM的人脸识别原代码, 非常经典的说
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    if( seq->first )
    {
        CvSeqBlock* block = seq->first;
        CvSeqBlock* prev_block = block->prev;
        
        int delta_idx = seq->first->start_index;

        for( ;; )
        {
            CHECK_CONDITION( sum == block->start_index - delta_idx &&
                             block->count > 0 && block->prev == prev_block &&
                             prev_block->next == block,
                             "Sequence blocks are inconsistent" );
            sum += block->count;                
            prev_block = block;
            block = block->next;
            if( block == seq->first ) break;
        }

        CHECK_CONDITION( block->prev->count * seq->elem_size +
                         block->prev->data <= seq->block_max,
                         "block->data or block_max pointer are incorrect" );
    }

    CHECK_CONDITION( seq->total == sum && sum == total, "total number is undefined" );

test_exit:

    *msg = message_string;
    return code;
}


static int  check_get_seq_elem( CvSeq* seq, simple_seq* sseq,
                                AtsRandState* rng_state, int iters,
                                const char** msg, CvStatus * _result )
{
    const char* message_string = *msg;
    CvStatus  result = *_result;
    int i = 0, code = TRS_OK;
    assert( seq->total == sseq->count );
    atsRandSetBounds( rng_state, -sseq->count*3/2, sseq->count*3/2 );

    for( i = 0; i < iters; i++ )
    {
        CvSeqBlock* block = 0;
        CvSeqBlock* block1 = 0;
        int idx = atsRand32s( rng_state );
        int idx0 = (unsigned)idx < (unsigned)(sseq->count) ? idx : idx < 0 ?
                   idx + sseq->count : idx - sseq->count;
        int flag = atsRand32s(rng_state) & 1;
        int bad_range = (unsigned)idx0 >= (unsigned)(sseq->count);
        char* elem = cvGetSeqElem( seq, idx, flag ? &block : 0 );

        if( bad_range )
        {
            CHECK_CONDITION( elem == 0,
                             "cvGetSeqElem doesn't "
                             "handle \"out of range\" properly" );
        }
        else
        {
            CHECK_CONDITION( elem != 0 &&
                             !memcmp( elem, simple_seq_elem( sseq, idx0), elem_size ) &&
                             (!flag || block != 0 &&
                            (unsigned)(idx0 - block->start_index +
                            seq->first->start_index) <= (unsigned)(block->count)),
                            "cvGetSeqElem is incorrect" );

            flag = atsRand32s(rng_state) & 1;
            idx = cvSeqElemIdx(seq, elem, flag ? &block1 : 0 );

            CHECK_CONDITION( idx >= 0 && idx == idx0 &&
                             (!flag || block1 != 0 && (!block || block1 == block)),
                            "cvSeqElemIdx is incorrect" );
        }
    }

test_exit:
    *msg = message_string;
    *_result = result;
    return code;
}



static int  check_get_seq_reading( CvSeq* seq, simple_seq* sseq,
                                   AtsRandState* rng_state, int iters,
                                   const char** msg, CvStatus * _result )
{
    const int max_val = 3*5 + 2;
    const char* message_string = *msg;
    CvStatus  result = *_result;
    int i = 0, code = TRS_OK, pos;
    int total = seq->total;
    CvSeqReader  reader;
    char* elem;
    elem_type el;

    elem = (char*)icvAlloc( sseq->elem_size );

    assert( total == sseq->count );

    atsRandSetBounds( rng_state, 0, 2 );
    pos = atsRand32s( rng_state ); 

    if( total == 0 )
    {
        cvStartReadSeq( seq, &reader, pos );
        /*CHECK_CONDITION( cvStartReadSeq( seq, &reader, pos ) < 0,
                         "start reading doesn't fail on empty seq" );*/
        goto test_exit;
    }

    cvStartReadSeq( seq, &reader, pos );
    DO_CV_ACTION( cvStartReadSeq, ( seq, &reader, pos ) );
    pos = pos ? seq->total - 1 : 0;

    CHECK_CONDITION( pos == cvGetSeqReaderPos(&reader),
                     "initial position of reader is wrong" );

    for( i = 0; i < iters; i++ )
    {
        int op;

        atsRandSetBounds( rng_state, 0, max_val );
        op = atsRand32s( rng_state );

        if( op >= max_val - 2 )
        {
            int new_pos, new_pos0;
            int bad_range;
            int is_relative = op == max_val - 1;

            atsRandSetBounds( rng_state, -total, total );

            new_pos = atsRand32s( rng_state );
            new_pos0 = new_pos + (is_relative ? pos : 0 );

            if( new_pos0 < 0 ) new_pos0 += total;
            if( new_pos0 >= total ) new_pos0 -= total;

            bad_range = (unsigned)new_pos0 >= (unsigned)total;

            if( !bad_range )
            {
                DO_CV_ACTION( cvSetSeqReaderPos,
                                ( &reader, new_pos, is_relative ) );
                CHECK_CONDITION( new_pos0 == cvGetSeqReaderPos( &reader ),
                                 "set reader position doesn't work" );
                pos = new_pos0;
            }
            else
            {
                cvSetSeqReaderPos( &reader, new_pos, is_relative );
                /*CHECK_CONDITION( cvSetSeqReaderPos( new_pos, is_relative, &reader ) < 0,
                   "set reader position doesn't handle \"out of range\"" );*/
                CHECK_CONDITION( pos == cvGetSeqReaderPos( &reader ),
                   "reader doesn't leave previous position after wrong positioning" );
            }
        }
        else
        {
            int direction = (op % 3) - 1;

            if( direction > 0 )
            {
                CV_READ_SEQ_ELEM( el, reader )
            }
            else if( direction < 0 )
            {
                CV_REV_READ_SEQ_ELEM( el, reader )
            }
            else
            {
                el = (elem_type&)(reader.ptr[0]);
            }

            CHECK_CONDITION( !memcmp( &el, simple_seq_elem( sseq, pos), elem_size),
                             "reading is incorrect" );
            pos += direction;
            if( pos < 0 ) pos += total;
            if( pos >= total ) pos -= total;

            CHECK_CONDITION( pos == cvGetSeqReaderPos( &reader ),
                   "reader doesn't move position correctly after reading" );
        }
    }

test_exit:
    
    icvFree( &elem );
    *msg = message_string;
    *_result = result;
    return code;
}


static int  test_multi_create( int count, CvSeq** seq,
                               int hdr_size, simple_seq** sseq,
                               CvMemStorage* storage, AtsRandState* rng_state,
                               const char** msg, CvStatus * _result )
{
    const char* message_string = *msg;
    CvStatus  result = *_result;
    CvSeqWriter* writer = 0;
    int* pos = 0;
    int* index = 0;
    int  j, count2;
    int  code = TRS_OK;

    writer = (CvSeqWriter*)icvAlloc( count * sizeof(writer[0]));
    index = (int*)icvAlloc(count * sizeof(index[0]));
    pos = (int*)icvAlloc(count * sizeof(pos[0]));

    assert( writer && index && pos );
    
    for( j = 0; j < count; j++ )
    {
        pos[j] = -1;
        index[j] = j;
    }

    for( count2 = count; count2 > 0; count2-- )
    {
        atsRandSetBounds( rng_state, 0, count2 );

        for(;;)
        {
            int k = atsRand32s( rng_state );
            int seq_idx = index[k];

            if( pos[seq_idx] < 0 )
            {
                DO_CV_ACTION( cvStartWriteSeq,
                    ( 0, hdr_size, elem_size, storage, writer + seq_idx ));
                cvSetSeqBlockSize( writer[seq_idx].seq, atsRandPlain32s( rng_state ) % 10000 );
                pos[seq_idx] = 0;
            }

            if( pos[seq_idx] == sseq[seq_idx]->count )
            {
                seq[seq_idx] = cvEndWriteSeq( writer + seq_idx );
                /* del index */
                memmove( index + k, index + k + 1, (count2 - k - 1)*sizeof(int));
                break;
            }
            
            {
                elem_type el = (elem_type&)(simple_seq_elem( sseq[seq_idx],
                                                             pos[seq_idx] )[0]);
                CV_WRITE_SEQ_ELEM( el, writer[seq_idx] );
            }
            pos[seq_idx]++;
        }
    }

/*test_exit:*/

    icvFree( &writer );
    icvFree( &index );
    icvFree( &pos );

    *msg = message_string;
    *_result = result;
    return code;
}


static int  test_seq_ops( int count, CvSeq** seq, simple_seq** sseq,
                          AtsRandState* rng_state, int iters,
                          const char** msg, CvStatus * _result )
{
    const int max_op = 8;
    const char* message_string = *msg;
    CvStatus  result = *_result;
    int i, k, code = TRS_OK;
    char* elem;
    char* elem2;
    int idx, num;
    int seq_idx, op;

    elem = (char*)icvAlloc( (max_struct_size + 1) * elem_size );

    for( i = 0; i < iters; i++ )
    {
        atsRandSetBounds( rng_state, 0, count * max_op );

        seq_idx = atsRand32s( rng_state );
        op = seq_idx % max_op;
        seq_idx /= max_op;

        switch( op )
        {
        case 0: /* push */
            
            if( sseq[seq_idx]->count == sseq[seq_idx]->max_count  ) break;

            atsbRand8s( rng_state, elem, elem_size );
            push_simple_seq_elem( sseq[seq_idx], elem );
            
            DO_CV_ACTION( cvSeqPush, ( seq[seq_idx], elem ));

            idx = sseq[seq_idx]->count - 1;
            elem2 = cvGetSeqElem( seq[seq_idx], idx, 0 );
            if( !elem2 )
            {
                message_string = "Push operation doesn't add the element";
                code = TRS_FAIL;
                goto test_exit;
            }

            CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count &&
                             !memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx), elem_size),
                             "The last sequence element is wrong after PUSH" );
            break;

        case 1: /* pop */

            if( sseq[seq_idx]->count == 0 ) break;
            
            idx = sseq[seq_idx]->count - 1;
            DO_CV_ACTION( cvSeqPop, ( seq[seq_idx], elem ));

            CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count - 1 &&
                       !memcmp( elem, simple_seq_elem(sseq[seq_idx],idx), elem_size),
                       "The popped sequence element isn't equal to last elem of simple seq" );

            drop_simple_seq_elem( sseq[seq_idx] );
            if( sseq[seq_idx]->count != 0 )
            {
                elem2 = cvGetSeqElem( seq[seq_idx], -1, 0 );
                if( !elem2 )
                {
                    message_string = "GetSequenceElementPtr fails after POP";
                    code = TRS_FAIL;
                    goto test_exit;
                }

                CHECK_CONDITION( !memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx-1), elem_size),
                                 "The last sequence element is wrong after POP" );
            }
            else
            {
                CHECK_CONDITION( seq[seq_idx]->first == 0,
                                 "The sequence doesn't become empty after final POP" );
            }
            break;

        case 2: /* insert */

            if( sseq[seq_idx]->count == sseq[seq_idx]->max_count  ) break;
            atsbRand8s( rng_state, elem, elem_size );

            idx = atsRandPlain32s( rng_state ) % (sseq[seq_idx]->count + 1);
            
            insert_simple_seq_elem( sseq[seq_idx], idx, elem );
            
            DO_CV_ACTION( cvSeqInsert, ( seq[seq_idx], idx, elem ));

            elem2 = cvGetSeqElem( seq[seq_idx], idx, 0 );
            if( !elem2 )
            {
                message_string = "Insert operation doesn't add the element";
                code = TRS_FAIL;
                goto test_exit;
            }

            CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count &&
                             !memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx), elem_size),
                             "The inserted sequence element is wrong" );
            break;

        case 3: /* remove */

            if( sseq[seq_idx]->count == 0 ) break;
            
            idx = atsRandPlain32s( rng_state ) % sseq[seq_idx]->count;
            DO_CV_ACTION( cvSeqRemove, ( seq[seq_idx], idx ));

            remove_simple_seq_elem( sseq[seq_idx], idx );

            if( idx < sseq[seq_idx]->count )
            {
                elem2 = cvGetSeqElem( seq[seq_idx], idx, 0 );
                if( !elem2 )
                {
                    message_string = "GetSequenceElementPtr fails after Remove";
                    code = TRS_FAIL;
                    goto test_exit;
                }

                CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count &&
                                 !memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx), elem_size),
                                 "The element after removed one is wrong" );
            }
            else
            {
                CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count,
                                 "The sequence doesn't become empty after final POP" );
            }
            break;

        case 4: /* batch push */
            if( sseq[seq_idx]->count == sseq[seq_idx]->max_count  ) break;

            num = atsRandPlain32s( rng_state ) %
                  (sseq[seq_idx]->max_count - sseq[seq_idx]->count + 1);

            atsbRand8s( rng_state, elem, num * elem_size );
            
            for( k = 0; k < num; k++ )
            {
                push_simple_seq_elem( sseq[seq_idx], elem + k * elem_size );
            }
            
            DO_CV_ACTION( cvSeqPushMulti, ( seq[seq_idx], elem, num ));

            idx = sseq[seq_idx]->count;

            if( idx > 0 )
            {
                /* choose the random element among added */
                idx = num > 0 ? atsRandPlain32s( rng_state ) % num + (idx - num) : idx - 1;
                elem2 = cvGetSeqElem( seq[seq_idx], idx, 0 );
                if( !elem2 )
                {
                    message_string = "Multi Push operation doesn't add the element";
                    code = TRS_FAIL;
                    goto test_exit;
                }

                CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count &&
                                 !memcmp( elem2, simple_seq_elem(sseq[seq_idx],idx), elem_size),
                                 "The last sequence element is wrong after PUSH" );
            }
            else
            {
                CHECK_CONDITION( seq[seq_idx]->total == 0 && seq[seq_idx]->first == 0,
                                 "Adding no elements to empty sequence fails" );
            }
            break;

        case 5: /* multi pop */
            if( sseq[seq_idx]->count == 0 ) break;
            
            num = atsRandPlain32s( rng_state ) % (sseq[seq_idx]->count+1);

            DO_CV_ACTION( cvSeqPopMulti, ( seq[seq_idx], elem, num ));
            
            CHECK_CONDITION( seq[seq_idx]->total == sseq[seq_idx]->count - num,
                       "The multi pop left a wrong number of elements in the sequence" );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -