cvhmm.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 1,633 行 · 第 1/4 页

SVN-BASE
1,633
字号
    for( last_obs = m_minNumObs-1, i = 0; last_obs < m_maxNumObs; last_obs++, i++ )
    {
        int t;

        /******************************************************************/
        /*    Viterbi termination                                         */
    
        if ( m_ProbType == _CV_LAST_STATE )
        {
            m_MaxGamma[i] = m_Gamma[last_obs * num_states + num_states - 1];
            q[i][last_obs] = num_states - 1;
        }
        else if( m_ProbType == _CV_BEST_STATE )
        {
            int k;
            q[i][last_obs] = 0;  
            m_MaxGamma[i] = m_Gamma[last_obs * num_states + 0]; 
        
            for(k = 1; k < num_states; k++)
            { 
                if ( m_Gamma[last_obs * num_states + k] > m_MaxGamma[i] )
                {
                    m_MaxGamma[i] = m_Gamma[last_obs * num_states + k];
                    q[i][last_obs] = k;
                }    
            }
        } 
    
        /******************************************************************/
        /*    Viterbi backtracking                                        */
        for  (t = last_obs-1; t >= 0; t--)
        {
            q[i][t] = m_csi[(t+1) * num_states + q[i][t+1] ];   
        } 
    }            
    
    /* memory free */
    icvFree( &m_pi );
    icvFree( &m_csi );
    icvDeleteMatrix( m_Gamma );   
       
    return CV_NO_ERR;
} 

/*F///////////////////////////////////////////////////////////////////////////////////////
//    Name: icvEViterbi
//    Purpose: The function calculates the embedded Viterbi algorithm
//             for 1 image 
//    Context:
//    Parameters:  
//             obs_info - observations
//             hmm      - HMM
//                
//    Returns: the Embedded Viterbi probability (float) 
//             and do state segmentation of observations
//
//    Notes: 
//F*/
IPCVAPI_IMPL(float, icvEViterbi, (CvImgObsInfo* obs_info, CvEHMM* hmm))
{
    int    i, j, counter;
    float  log_likelihood;

    float inv_obs_x = 1.f / obs_info->obs_x;

    CvEHMMState* first_state = hmm->u.ehmm->u.state;
    
    /* memory allocation for superB */
    CvMatr32f superB = icvCreateMatrix_32f(hmm->num_states, obs_info->obs_y );
    
    /* memory allocation for q */
    int*** q = (int***)icvAlloc( hmm->num_states * sizeof(int**) );
    int* super_q = (int*)icvAlloc( obs_info->obs_y * sizeof(int) );
    
    for (i = 0; i < hmm->num_states; i++)
    {
        q[i] = (int**)icvAlloc( obs_info->obs_y * sizeof(int*) );
        
        for (j = 0; j < obs_info->obs_y ; j++)
        {
            q[i][j] = (int*)icvAlloc( obs_info->obs_x * sizeof(int) );
        }
    }             
    
    /* start Viterbi segmentation */
    for (i = 0; i < hmm->num_states; i++)
    {
        CvEHMM* ehmm = &(hmm->u.ehmm[i]);
        
        for (j = 0; j < obs_info->obs_y; j++)
        {
            float max_gamma;
            
            /* 1D HMM Viterbi segmentation */
            icvViterbiSegmentation( ehmm->num_states, obs_info->obs_x, 
                ehmm->transP, ehmm->obsProb[j], 0, 
                _CV_LAST_STATE, &q[i][j], obs_info->obs_x,
                obs_info->obs_x, &max_gamma);
            
            superB[j * hmm->num_states + i] = max_gamma * inv_obs_x;
        }
    }
    
    /* perform global Viterbi segmentation (i.e. process higher-level HMM) */
    
    icvViterbiSegmentation( hmm->num_states, obs_info->obs_y, 
                             hmm->transP, superB, 0, 
                             _CV_LAST_STATE, &super_q, obs_info->obs_y,
                             obs_info->obs_y, &log_likelihood );
    
    log_likelihood /= obs_info->obs_y ;   
    
    
    counter = 0;
    /* assign new state to observation vectors */
    for (i = 0; i < obs_info->obs_y; i++)
    {   
        for (j = 0; j < obs_info->obs_x; j++, counter++)
        {
            int superstate = super_q[i];
            int state = hmm->u.ehmm[superstate].u.state - first_state;
            
            obs_info->state[2 * counter] = superstate;
            obs_info->state[2 * counter + 1] = state + q[superstate][i][j];
        }
    }
    
    /* memory deallocation for superB */
    icvDeleteMatrix( superB );
    
    /*memory deallocation for q */
    for (i = 0; i < hmm->num_states; i++)
    {
        for (j = 0; j < obs_info->obs_y ; j++)
        {
            icvFree( &q[i][j] );
        }
        icvFree( &q[i] );
    }
    
    icvFree( &q );
    icvFree( &super_q );
    
    return log_likelihood;
}  

IPCVAPI_IMPL(CvStatus, icvEstimateHMMStateParams, (CvImgObsInfo** obs_info_array,
                                                   int num_img, CvEHMM* hmm))

{
    /* compute gamma, weights, means, vars */
    int k, i, j, m;
    int total = 0;
    int vect_len = obs_info_array[0]->obs_size;

    float start_log_var_val = LN2PI * vect_len;

    CvVect32f tmp_vect = icvCreateVector_32f( vect_len );
    
    CvEHMMState* first_state = hmm->u.ehmm[0].u.state;

    assert( sizeof(float) == sizeof(int) );

    for(i = 0; i < hmm->num_states; i++ )
    {
        total+= hmm->u.ehmm[i].num_states;
    }

    /***************Gamma***********************/
    /* initialize gamma */
    for( i = 0; i < total; i++ )
    {
        for (m = 0; m < first_state[i].num_mix; m++)
        {
            ((int*)(first_state[i].weight))[m] = 0;
        }     
    }
    
    /* maybe gamma must be computed in mixsegm process ?? */

    /* compute gamma */
    for (k = 0; k < num_img; k++)
    {
        CvImgObsInfo* info = obs_info_array[k];
        int num_obs = info->obs_y * info->obs_x;

        for (i = 0; i < num_obs; i++)
        {
            int state, mixture;
            state = info->state[2*i + 1];
            mixture = info->mix[i];
            /* computes gamma - number of observations corresponding 
               to every mixture of every state */ 
            ((int*)(first_state[state].weight))[mixture] += 1;              
        }
    }     
    /***************Mean and Var***********************/
    /* compute means and variances of every item */
    /* initially variance placed to inv_var */
    /* zero mean and variance */
    for (i = 0; i < total; i++)
    {
        memset( (void*)first_state[i].mu, 0, first_state[i].num_mix * vect_len * 
                                                                         sizeof(float) );
        memset( (void*)first_state[i].inv_var, 0, first_state[i].num_mix * vect_len * 
                                                                         sizeof(float) );
    }
    
    /* compute sums */
    for (i = 0; i < num_img; i++)
    {
        CvImgObsInfo* info = obs_info_array[i];
        int total_obs = info->obs_x * info->obs_y;

        float* vector = info->obs;

        for (j = 0; j < total_obs; j++, vector+=vect_len )
        {   
            int state = info->state[2 * j + 1];
            int mixture = info->mix[j]; 
            
            CvVect32f mean  = first_state[state].mu + mixture * vect_len;
            CvVect32f mean2 = first_state[state].inv_var + mixture * vect_len;
            
            icvAddVector_32f( mean, vector, mean, vect_len );
            icvAddSquare_32f_C1IR( vector, vect_len * sizeof(float),
                                    mean2, vect_len * sizeof(float), cvSize(vect_len, 1) ); 
        }   
    }
    
    /*compute the means and variances */
    /* assume gamma already computed */
    for (i = 0; i < total; i++)
    {           
        CvEHMMState* state = &(first_state[i]);

        for (m = 0; m < state->num_mix; m++)
        {
            int k;
            CvVect32f mu  = state->mu + m * vect_len;
            CvVect32f invar = state->inv_var + m * vect_len;             
            
            if ( ((int*)state->weight)[m] > 1)
            {
                float inv_gamma = 1.f/((int*)(state->weight))[m];
            
                icvScaleVector_32f( mu, mu, vect_len, inv_gamma);
                icvScaleVector_32f( invar, invar, vect_len, inv_gamma);
            }

            icvMulVectors_32f(mu, mu, tmp_vect, vect_len);
            icvSubVector_32f( invar, tmp_vect, invar, vect_len);     
            
            /* low bound of variance - 100 (Ara's experimental result) */
            for( k = 0; k < vect_len; k++ )
            {
                invar[k] = (invar[k] > 100.f) ? invar[k] : 100.f;
            }

            /* compute log_var */
            state->log_var_val[m] = start_log_var_val;
            for( k = 0; k < vect_len; k++ )
            {
                state->log_var_val[m] += (float)log( invar[k] );
            }           

            /* SMOLI 27.10.2000 */
            state->log_var_val[m] *= 0.5;


            /* compute inv_var = 1/sqrt(2*variance) */
            icvScaleVector_32f(invar, invar, vect_len, 2.f );
            icvbInvSqrt_32f(invar, invar, vect_len );
        }
    }
  
    /***************Weights***********************/
    /* normilize gammas - i.e. compute mixture weights */
    
    //compute weights
    for (i = 0; i < total; i++)
    {           
        int gamma_total = 0;
        float norm;

        for (m = 0; m < first_state[i].num_mix; m++)
        {
            gamma_total += ((int*)(first_state[i].weight))[m];  
        }

        norm = gamma_total ? (1.f/(float)gamma_total) : 0.f;
            
        for (m = 0; m < first_state[i].num_mix; m++)
        {
            first_state[i].weight[m] = ((int*)(first_state[i].weight))[m] * norm;
        } 
    }                                               

    icvDeleteVector( tmp_vect);
    return CV_NO_ERR; 
}   

/*
CvStatus icvLightingCorrection8uC1R( uchar* img, CvSize roi, int src_step )
{
    int i, j;
    int width = roi.width;
    int height = roi.height;
    
    float x1, x2, y1, y2;
    int f[3] = {0, 0, 0};
    float a[3] = {0, 0, 0};
    
    float h1;
    float h2;
    
    float c1,c2;
    
    float min = FLT_MAX;
    float max = -FLT_MAX;
    float correction;
    
    float* float_img = icvAlloc( width * height * sizeof(float) );
    
    x1 = width * (width + 1) / 2.0f; // Sum (1, ... , width)
    x2 = width * (width + 1 ) * (2 * width + 1) / 6.0f; // Sum (1^2, ... , width^2)
    y1 = height * (height + 1)/2.0f; // Sum (1, ... , width)
    y2 = height * (height + 1 ) * (2 * height + 1) / 6.0f; // Sum (1^2, ... , width^2)
    
    
    // extract grayvalues
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            f[2] = f[2] + j * img[i*src_step + j];
            f[1] = f[1] + i * img[i*src_step + j];
            f[0] = f[0] +     img[i*src_step + j];
        }
    }
    
    h1 = (float)f[0] * (float)x1 / (float)width;
    h2 = (float)f[0] * (float)y1 / (float)height;
    
    a[2] = ((float)f[2] - h1) / (float)(x2*height - x1*x1*height/(float)width);
    a[1] = ((float)f[1] - h2) / (float)(y2*width - y1*y1*width/(float)height);
    a[0] = (float)f[0]/(float)(width*height) - (float)y1*a[1]/(float)height - 
        (float)x1*a[2]/(float)width;
    
    for (i = 0; i < height; i++) 
    {    
        for (j = 0; j < width; j++)
        {
            
            correction = a[0] + a[1]*(float)i + a[2]*(float)j;
            
            float_img[i*width + j] = img[i*src_step + j] - correction;
            
            if (float_img[i*width + j] < min) min = float_img[i*width+j];
            if (float_img[i*width + j] > max) max = float_img[i*width+j];
        }
    }
    
    //rescaling to the range 0:255
    c2 = 0;
    if (max == min)
        c2 = 255.0f;
    else
        c2 = 255.0f/(float)(max - min);
    
    c1 = (-(float)min)*c2;
    
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            int value = (int)floor(c2*float_img[i*width + j] + c1);
            if (value < 0) value = 0;
            if (value > 255) value = 255;
            img[i*src_step + j] = (uchar)value;
        }
    }

    icvFree( &float_img );
    return CV_NO_ERR;
}
                              

CvStatus icvLightingCorrection( icvImage* img ) 
{
    CvSize roi;
    if ( img->type != IPL_DEPTH_8U || img->channels != 1 )
    return CV_BADFACTOR_ERR;

    roi = _cvSize( img->roi.width, img->roi.height );
    
    return _cvLightingCorrection8uC1R( img->data + img->roi.y * img->step + img->roi.x, 
                                        roi, img->step );

}

*/

/* End of file */

⌨️ 快捷键说明

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