Homework 6

advertisement
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 ;
Download