Into to Computer Vision Homework 6 October 22, 2015 Jacob St.Amand The goal of this lab was to use correlation/convolution to do template matching to find waldo in a scene. To start, I first wrote the correlation function. Once I got that to work correctly, I wrote a similar function to perform the Normalized Cross Correlation algorithm. I did this lab in C++, using OpenCV. For dealing with the edges, I did not add padding or anything. I just skipped any part of the algorithm that wanted to use a pixel location outside of the image border. This did create a false brightness at the left edge of the output. I will likely have to change my code to handle edges better for homework 7. • NCC function: • Program output: Normalized Cross Correlation done ! x_loc : 296 y_loc : 132 • Output of the normalized cross correlation: • Main Function Code: int main ( int argc , char ∗∗ argv ) { std : : ofstream output_file ; Mat sceneMat , kernelMat , correlationMat , convolutionMat ; sceneMat = imread ( " WaldoScene . png " ) ; kernelMat = imread ( " WaldoKernel . png" ) ; // 20 x38 output_file . open ( " output . txt " , std : : ios : : trunc | std : : ios : : out ) ; int error ; double min , max ; Point min_loc , max_loc ; correlationMat = Mat ( sceneMat . rows , sceneMat . cols , CV_32FC3 , ( 0 . 0 , 0 . 0 , 0 . 0 ) ) ; convolutionMat = Mat ( sceneMat . rows , sceneMat . cols , CV_32FC3 , ( 0 . 0 , 0 . 0 , 0 . 0 ) ) ; sceneMat . convertTo ( sceneMat , CV_32F , 1 . 0 / 2 5 5 . 0 ) ; kernelMat . convertTo ( kernelMat , CV_32F , 1 . 0 / 2 5 5 . 0 ) ; error = nCrossCorrelation ( sceneMat , kernelMat , correlationMat , 1 0 , 1 9 ) ; correlationMat . convertTo ( correlationMat , CV_8U , 2 5 5 . 0 ) ; Mat grayMat ; cvtColor ( correlationMat , grayMat , COLOR_BGR2GRAY ) ; minMaxLoc ( grayMat , &min , &max , &min_loc , &max_loc ) ; std : : cout << " Normalized Cross Correlation done !\n" ; std : : cout << " x_loc : " << max_loc . x << "\n" ; std : : cout << " y_loc : " << max_loc . y << "\n\n" ; output_file << " Normalized Cross Correlation done !\n" ; output_file << " x_loc : " << max_loc . x << "\n" ; output_file << " y_loc : " << max_loc . y << "\n\n" ; imwrite ( " correlationOut .png " , correlationMat ) ; imwrite ( " correlationOutGray . png " , grayMat ) ; output_file . close ( ) ; } return error ; • Correlation Function Code: int correlation ( Mat inputMat , Mat kernelMat , Mat correlationOutMat , int anchor_x , int an { int i , j , u , v ; i = inputMat . rows ; j = inputMat . cols ; u = kernelMat . rows ; v = kernelMat . cols ; float max_value ; max_value = 0 ; int ia , ib , ic , id , ie ; int px , py ; float ∗ a ; float ∗ b ; float ∗ c ; // p r o c e s s each p i x e l for ( ia = 0 ; ia < i ; ia++) { for ( ib = 0 ; ib < j ; ib++) { // f o r each p i x e l , p r o c e s s k e r n e l for ( ic = 0 ; ic < u ; ic++) { // check i f row i s even p a r t o f t h e image px = ia + ic − anchor_x ; if ( ( px >= 0 ) and ( px < i ) ) { for ( id = 0 ; id < v ; id++) { // check i f c o l i s even p a r t o f t h e image py = ib + id − anchor_y ; if ( ( py >= 0 ) and ( py < j ) ) { a = &correlationOutMat . ptr<float >(ia , ib ) [ 0 ] ; b = &inputMat . ptr<float >(px , py ) [ 0 ] ; c = &kernelMat . ptr<float >(ic , id ) [ 0 ] ; a[0] = a[0] + b[0] ∗ c [0]; // a = &c o r r e l a t i o n O u t M a t . ptr<f l o a t >( i a , i b ) [ 1 ] ; //b = &inputMat . ptr<f l o a t >(px , py ) [ 1 ] ; // c = &kernelMat . ptr<f l o a t >( i c , i d ) [ 1 ] ; a[1] = a[1] + b[1] ∗ c [1]; } } // a = &c o r r e l a t i o n O u t M a t . ptr<f l o a t >( i a , i b ) [ 2 ] ; //b = &inputMat . ptr<f l o a t >(px , py ) [ 2 ] ; // c = &kernelMat . ptr<f l o a t >( i c , i d ) [ 2 ] ; a[2] = a[2] + b[2] ∗ c [2]; } } // check p i x e l v a l u e a = &correlationOutMat . ptr<float >(ia , ib ) [ 0 ] ; if ( a [ 0 ] > max_value ) { max_value = a [ 0 ] ; } if ( a [ 1 ] > max_value ) { max_value = a [ 1 ] ; } if ( a [ 2 ] > max_value ) { max_value = a [ 2 ] ; } } } std : : cout << ia << " / " << i << "\n" ; correlationOutMat . convertTo ( correlationOutMat , CV_32F , 1 . 0 / max_value ) ; } return 0 ; • Normalized Cross Correlation Function Code: int nCrossCorrelation ( Mat inputMat , Mat kernelMat , Mat correlationOutMat , int anchor_x , { int i , j , u , v ; i = inputMat . rows ; j = inputMat . cols ; u = kernelMat . rows ; v = kernelMat . cols ; float max_value ; max_value = 0 ; // t h r e e sum components o f NCC a l g o r i t h m // NCC = top1 / s q r t ( bot1 ∗ bot2 ) Mat top1 , bot1 , bot2 ; top1 = Mat ( i , j , CV_32FC3 , ( 0 . 0 , 0 . 0 , 0 . 0 ) ) ; bot1 = Mat ( i , j , CV_32FC3 , ( 0 . 0 , 0 . 0 , 0 . 0 ) ) ; bot2 = Mat ( i , j , CV_32FC3 , ( 0 . 0 , 0 . 0 , 0 . 0 ) ) ; int ia , ib , ic , id , ie ; int px , py ; float ∗ a ; float ∗ b ; float ∗ c ; float ∗ d ; float kernelMean [ 3 ] ; float windowMean [ 3 ] ; kernelMean [ 0 ] = 0 . 0 ; kernelMean [ 1 ] = 0 . 0 ; kernelMean [ 2 ] = 0 . 0 ; // g e t t h e mean o f t h e t e m p l a t e / k e r n e l for ( ia = 0 ; ia < u ; ia++) { for ( ib = 0 ; ib < v ; ib++) { a = &kernelMat . ptr<float >(ia , ib ) [ 0 ] ; kernelMean [ 0 ] += a [ 0 ] ; kernelMean [ 1 ] += a [ 1 ] ; kernelMean [ 2 ] += a [ 2 ] ; } } kernelMean [ 0 ] = kernelMean [ 0 ] / ( u∗v ) ; kernelMean [ 1 ] = kernelMean [ 1 ] / ( u∗v ) ; kernelMean [ 2 ] = kernelMean [ 2 ] / ( u∗v ) ; // l o o p through each p i x e l for ( ia = 0 ; ia < i ; ia++) { for ( ib = 0 ; ib < j ; ib++) { windowMean [ 0 ] = 0 . 0 ; windowMean [ 1 ] = 0 . 0 ; windowMean [ 2 ] = 0 . 0 ; // f i r s t f i n d mean o f t h e c u r r e n t window for ( ic = 0 ; ic < u ; ic++) { // check i f row i s even p a r t o f t h e image px = ia + ic − anchor_x ; if ( ( px >= 0 ) and ( px < i ) ) { for ( id = 0 ; id < v ; id++) { // check i f c o l i s even p a r t o f t h e image py = ib + id − anchor_y ; if ( ( py >= 0 ) and ( py < j ) ) { a = &inputMat . ptr<float >(px , py ) [ 0 ] ; windowMean [ 0 ] += a [ 0 ] ; windowMean [ 1 ] += a [ 1 ] ; windowMean [ 2 ] += a [ 2 ] ; } } } } windowMean [ 0 ] = windowMean [ 0 ] / ( u∗v ) ; windowMean [ 1 ] = windowMean [ 1 ] / ( u∗v ) ; windowMean [ 2 ] = windowMean [ 2 ] / ( u∗v ) ; // p r o c e s s t h e window // f i n d each NCC sum component ( top1 , bot1 , bot2 ) for ( ic = 0 ; ic < u ; ic++) { // check i f row i s even p a r t o f t h e image px = ia + ic − anchor_x ; if ( ( px >= 0 ) and ( px < i ) ) { for ( id = 0 ; id < v ; id++) { // check i f c o l i s even p a r t o f t h e image py = ib + id − anchor_y ; if ( ( py >= 0 ) and ( py < j ) ) { a = &top1 . ptr<float >(ia , ib ) [ 0 ] ; b = &inputMat . ptr<float >(px , py ) [ 0 ] ; c = &kernelMat . ptr<float >(ic , id ) [ 0 ] ; a [ 0 ] = a [ 0 ] + ( b [ 0 ] − windowMean [ 0 ] ) ∗ ( c [ 0 ] − kernelMean [ 0 ] ) a [ 1 ] = a [ 1 ] + ( b [ 1 ] − windowMean [ 1 ] ) ∗ ( c [ 1 ] − kernelMean [ 1 ] ) a [ 2 ] = a [ 2 ] + ( b [ 2 ] − windowMean [ 2 ] ) ∗ ( c [ 2 ] − kernelMean [ 2 ] ) a = &bot1 . ptr<float >(ia , ib ) [ 0 ] ; a [ 0 ] = a [ 0 ] + ( b [ 0 ] − windowMean [ 0 ] ) ∗ ( b [ 0 ] − windowMean [ 0 ] ) a [ 1 ] = a [ 1 ] + ( b [ 1 ] − windowMean [ 1 ] ) ∗ ( b [ 1 ] − windowMean [ 1 ] ) a [ 2 ] = a [ 2 ] + ( b [ 2 ] − windowMean [ 2 ] ) ∗ ( b [ 2 ] − windowMean [ 2 ] ) a = &bot2 . ptr<float >(ia , ib ) [ 0 ] ; a [ 0 ] = a [ 0 ] + ( c [ 0 ] − kernelMean [ 0 ] ) ∗ ( c [ 0 ] − kernelMean [ 0 ] ) a [ 1 ] = a [ 1 ] + ( c [ 1 ] − kernelMean [ 1 ] ) ∗ ( c [ 1 ] − kernelMean [ 1 ] ) a [ 2 ] = a [ 2 ] + ( c [ 2 ] − kernelMean [ 2 ] ) ∗ ( c [ 2 ] − kernelMean [ 2 ] ) } } } } //NCC a l g o r i t h m . combine t h e p a r t s (NCC = top1 / s q r t ( bot1 ∗ bot2 ) ) a = &correlationOutMat . ptr<float >(ia , ib ) [ 0 ] ; b = &top1 . ptr<float >(ia , ib ) [ 0 ] ; c = &bot1 . ptr<float >(ia , ib ) [ 0 ] ; d = &bot2 . ptr<float >(ia , ib ) [ 0 ] ; a [ 0 ] = b [ 0 ] / sqrt ( c [ 0 ] ∗ d [ 0 ] ) ; a [ 1 ] = b [ 1 ] / sqrt ( c [ 1 ] ∗ d [ 1 ] ) ; a [ 2 ] = b [ 2 ] / sqrt ( c [ 2 ] ∗ d [ 2 ] ) ; // a l s o check max v a l u e o f output s o we can s c a l e t o 1 . 0 max if ( a [ 0 ] > max_value ) { max_value = a [ 0 ] ; } if ( a [ 1 ] > max_value ) { max_value = a [ 1 ] ; } if ( a [ 2 ] > max_value ) { max_value = a [ 2 ] ; } } } // output c o m p l e t i o n s t a t u s ( a s a f r a c t i o n o f rows completed ) std : : cout << ia << " / " << i << "\n" ; // s c a l e t o 1 . 0 max correlationOutMat . convertTo ( correlationOutMat , CV_32F , 1 . 0 / max_value ) ; } return 0 ;