Micon Car Rally / Mbed 2 deprecated kit18_gr-peach

Dependencies:   GR-PEACH_video mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers image_process.cpp Source File

image_process.cpp

00001 //------------------------------------------------------------------//
00002 //Supported MCU:   RZ/A1H
00003 //File Contents:   Image Processing API ( Source file )
00004 //Version number:  Ver.1.00
00005 //Date:            2018.10.30
00006 //Copyright:       Renesas Electronics Corporation
00007 //                 Hitachi Document Solutions Co., Ltd.
00008 //------------------------------------------------------------------//
00009 
00010 //------------------------------------------------------------------//
00011 //Include
00012 //------------------------------------------------------------------//
00013 #include <math.h>
00014 #include "mbed.h"
00015 #include "image_process.h"
00016 
00017 /*******************************/
00018 /* Function Map                */
00019 /********************************
00020 * ImageCopy
00021 * Extraction_Brightness
00022 * ImageReduction
00023 * Binarization
00024 * Image_part_Extraction
00025 * Standard_Deviation
00026 * Covariance
00027 * Judgement_ImageMatching
00028 * PatternMatching_process
00029 ********************************/
00030 
00031 //******************************************************************//
00032 // Image process functions
00033 //*******************************************************************/
00034 //------------------------------------------------------------------//
00035 // ImageCopy function
00036 //------------------------------------------------------------------//
00037 void ImageCopy( unsigned char *BuffAddrIn, int HW, int VW, unsigned char *BuffAddrOut, int Frame )
00038 {
00039     static int  counter = 0;
00040     static int  X, Y;
00041     int         HW_T;//HW Twice
00042 
00043     HW_T  = HW + HW;
00044 
00045     switch( counter++ ) {
00046     case 0:
00047         // Top or Bottom field
00048         for( Y = Frame; Y < ( VW / 2 ); Y+=2 ){
00049             for( X = 0; X < HW_T; X++ ){
00050                 BuffAddrOut[ ( Y * HW_T ) + X ] = BuffAddrIn[ ( Y * HW_T ) + X ];
00051             }
00052         }
00053         break;
00054     case 1:
00055         // Top or Bottom field
00056         for(          ; Y < VW; Y+=2 ){
00057             for( X = 0; X < HW_T; X++ ){
00058                 BuffAddrOut[ ( Y * HW_T ) + X ] = BuffAddrIn[ ( Y * HW_T ) + X ];
00059             }
00060         }
00061         //Frame Change
00062         if( Frame == 0 ) Frame = 1;
00063         else             Frame = 0;
00064         for( Y = Frame; Y < VW; Y+=2 ){
00065             for( X = 0; X < HW_T; X+=2 ){
00066                 BuffAddrOut[ ( Y * HW_T ) + ( X + 0 ) ] = 0;
00067                 BuffAddrOut[ ( Y * HW_T ) + ( X + 1 ) ] = 128;
00068             }
00069         }
00070         counter = 0;
00071         break;
00072     default:
00073         break;
00074     }
00075 }
00076 
00077 //------------------------------------------------------------------//
00078 // Extraction Brightness function
00079 //------------------------------------------------------------------//
00080 void Extraction_Brightness( unsigned char *BuffAddrIn, int HW, int VW, unsigned char *BuffAddrOut, int Frame )
00081 {
00082     static int  conter = 0;
00083 
00084     int X, Y;
00085     int Px;
00086     int HW_T;//HW Twice
00087 
00088     HW_T  = HW + HW;
00089 
00090     switch( conter++ ) {
00091     case 0:
00092         //Pixel Interpolation ( Top or Bottom )
00093         for( Y = Frame; Y < ( VW / 2 ); Y+=2 ){
00094             for( X = 0, Px = 0; X < HW_T; X+=2, Px++  ){
00095                 BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrIn[ ( Y * HW_T ) + X ];
00096             }
00097         }
00098         //Frame Change
00099         if( Frame == 0 ) Frame = 1;
00100         else             Frame = 0;
00101         //Bilinear Interpolation Method
00102         for( Y = Frame; Y < ( VW / 2 ); Y+=2 ){
00103             for( X = 0, Px = 0; X < HW_T; X+=2, Px++  ){
00104                 if( Y <= 0 ) {
00105                     BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrOut[ ( (Y+1) * HW ) + Px ];
00106                 } else if( ( ( VW / 2 ) - 1 ) > Y && Y > 0 ) {
00107                     BuffAddrOut[ ( Y * HW ) + Px ] = ( BuffAddrOut[ ( (Y-1) * HW ) + Px ] * (double)0.5 ) + ( BuffAddrOut[ ( (Y+1) * HW ) + Px ] * (double)0.5 );
00108                 } else if( Y >= ( ( VW / 2 ) - 1 ) ) {
00109                     BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrOut[ ( (Y-1) * HW ) + Px ];
00110                 }
00111             }
00112         }
00113         break;
00114     case 1:
00115         //Pixel Interpolation ( Top or Bottom )
00116         for( Y = ( VW / 2 ) + Frame; Y < VW; Y+=2 ){
00117             for( X = 0, Px = 0; X < HW_T; X+=2, Px++  ){
00118                 BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrIn[ ( Y * HW_T ) + X ];
00119             }
00120         }
00121         //Frame Change
00122         if( Frame == 0 ) Frame = 1;
00123         else             Frame = 0;
00124         //Bilinear Interpolation Method
00125         for( Y = ( VW / 2 ) + Frame; Y < VW; Y+=2 ){
00126             for( X = 0, Px = 0; X < HW_T; X+=2, Px++  ){
00127                 if( Y <= 0 ) {
00128                     BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrOut[ ( (Y+1) * HW ) + Px ];
00129                 } else if( ( VW - 1 ) > Y && Y > 0 ) {
00130                     BuffAddrOut[ ( Y * HW ) + Px ] = ( BuffAddrOut[ ( (Y-1) * HW ) + Px ] * (double)0.5 ) + ( BuffAddrOut[ ( (Y+1) * HW ) + Px ] * (double)0.5 );
00131                 } else if( Y >= ( VW - 1 ) ) {
00132                     BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrOut[ ( (Y-1) * HW ) + Px ];
00133                 }
00134             }
00135         }
00136         conter = 0;
00137         break;
00138     default:
00139         break;
00140     }
00141 }
00142 
00143 //------------------------------------------------------------------//
00144 // Image Reduction function
00145 // Parcent : 0.0 - 1.0
00146 //------------------------------------------------------------------//
00147 void ImageReduction( unsigned char *BuffAddrIn, int HW, int VW, unsigned char *BuffAddrOut, double Percent )
00148 {
00149     static int      conter = 0;
00150     static int      Y;
00151 
00152     int             X;
00153     int             HW_N;
00154     long            Nx, Ny;
00155     long            NxBuff, NyBuff;
00156     unsigned int    BuffAddrData;
00157     double long     Sx, Sy;
00158 
00159     NxBuff  = -1;
00160     Sx = Sy = Percent;
00161     HW_N    = HW * Percent;
00162 
00163     //Under 100%
00164     if( Percent <= 1 ) {
00165         switch( conter++ ) {
00166         case 0:
00167             for( Y = 0; Y < ( VW / 2 ); Y++ ){
00168                 //Affine Transformation Y-axis
00169                 Ny = ( Sy * Y );
00170                 for( X = 0; X < HW; X++ ){
00171                     //Affine Transformation X-axis
00172                     Nx = ( Sx * X );
00173                     if( NxBuff == Nx ) {
00174                         BuffAddrData  = BuffAddrOut[ ( Ny * HW_N ) + Nx ];
00175                         BuffAddrData += BuffAddrIn[ ( Y * HW ) + X ];
00176                         BuffAddrData /= 2;
00177                         BuffAddrOut[ ( Ny * HW_N ) + Nx ] = BuffAddrData;
00178                     } else {
00179                         NxBuff = Nx;
00180                         BuffAddrOut[ ( Ny * HW_N ) + Nx ] = BuffAddrIn[ ( Y * HW ) + X ];
00181                     }
00182                 }
00183                 if( NyBuff == Ny ) {
00184                     for( X = 0; X < HW_N; X++ ){
00185                         BuffAddrData  = BuffAddrOut[ (  Ny      * HW_N ) + X ];//Now line
00186                         BuffAddrData += BuffAddrOut[ ( (Ny - 1) * HW_N ) + X ];//Before now line
00187                         BuffAddrData /= 2;
00188                         BuffAddrOut[ ( Ny * HW_N ) + X ] = BuffAddrData;
00189                     }
00190                 } else {
00191                     NyBuff = Ny;
00192                 }
00193             }
00194             break;
00195         case 1:
00196             for(      ; Y < VW; Y++ ){
00197                 //Affine Transformation Y-axis
00198                 Ny = ( Sy * Y );
00199                 for( X = 0; X < HW; X++ ){
00200                     //Affine Transformation X-axis
00201                     Nx = ( Sx * X );
00202                     if( NxBuff == Nx ) {
00203                         BuffAddrData  = BuffAddrOut[ ( Ny * HW_N ) + Nx ];
00204                         BuffAddrData += BuffAddrIn[ ( Y * HW ) + X ];
00205                         BuffAddrData /= 2;
00206                         BuffAddrOut[ ( Ny * HW_N ) + Nx ] = BuffAddrData;
00207                     } else {
00208                         NxBuff = Nx;
00209                         BuffAddrOut[ ( Ny * HW_N ) + Nx ] = BuffAddrIn[ ( Y * HW ) + X ];
00210                     }
00211                 }
00212                 if( NyBuff == Ny ) {
00213                     for( X = 0; X < HW_N; X++ ){
00214                         BuffAddrData  = BuffAddrOut[ (  Ny      * HW_N ) + X ];//Now line
00215                         BuffAddrData += BuffAddrOut[ ( (Ny - 1) * HW_N ) + X ];//Before now line
00216                         BuffAddrData /= 2;
00217                         BuffAddrOut[ ( Ny * HW_N ) + X ] = BuffAddrData;
00218                     }
00219                 } else {
00220                     NyBuff = Ny;
00221                 }
00222             }
00223             conter = 0;
00224             break;
00225         default:
00226             break;
00227         }
00228     }
00229 }
00230 
00231 //------------------------------------------------------------------//
00232 // Binarization process Function
00233 //------------------------------------------------------------------//
00234 void Binarization( unsigned char *BuffAddrIn, int HW, int VW, unsigned char *BuffAddrOut, int threshold )
00235 {
00236     int     i;
00237     int     items;
00238 
00239     items = HW * VW;
00240 
00241     for( i = 0; i < items; i++ ) {
00242         if( BuffAddrIn[i] >= threshold ) BuffAddrOut[i] = 1;
00243         else                             BuffAddrOut[i] = 0;
00244     }
00245 }
00246 
00247 //******************************************************************//
00248 // Mark detect functions
00249 //*******************************************************************/
00250 //------------------------------------------------------------------//
00251 // Extract_Image
00252 //------------------------------------------------------------------//
00253 void Image_part_Extraction( unsigned char *BuffAddrIn, int HW, int VW,
00254                             int CutPointX, int CutPointY, unsigned char *BuffAddrOut, int Xsize, int Ysize )
00255 {
00256     int     X, Y;
00257     for( Y = 0; Y < Ysize; Y++ ) {
00258         for( X = 0; X < Xsize; X++ ) {
00259             BuffAddrOut[ X + ( Y * Xsize ) ] = BuffAddrIn[ ( ( Y + CutPointY ) * HW ) + ( X + CutPointX ) ];
00260        }
00261     }
00262 }
00263 
00264 //------------------------------------------------------------------//
00265 // Standard deviation
00266 //------------------------------------------------------------------//
00267 double Standard_Deviation( unsigned char *data, double *Devi, int Xsize, int Ysize )
00268 {
00269     int         i;
00270     int         items;
00271     double      iRet_A, iRet_C, iRet_D;
00272 
00273     items = Xsize * Ysize;
00274 
00275     /* A 合計値 平均化 */
00276     iRet_A = 0;
00277     for( i = 0; i < items; i++ ) {
00278         iRet_A += data[i];
00279     }
00280     iRet_A /= items;
00281 
00282     /* B 偏差値 */
00283     for( i = 0; i < items; i++ ) {
00284         Devi[i] = data[i] - iRet_A;
00285     }
00286 
00287     /* C 分散 */
00288     iRet_C = 0;
00289     for( i = 0; i < items; i++ ) {
00290         iRet_C += ( Devi[i] * Devi[i] );
00291     }
00292     iRet_C /= items;
00293 
00294     /* D 標準偏差 */
00295     iRet_D = sqrt( iRet_C );
00296 
00297     return iRet_D;
00298 }
00299 
00300 //------------------------------------------------------------------//
00301 // Covariance
00302 //------------------------------------------------------------------//
00303 double Covariance( double *Devi_A, double *Devi_B, int Xsize, int Ysize )
00304 {
00305     int     i;
00306     int         items;
00307     double  iRet, iRet_buff;
00308 
00309     items = Xsize * Ysize;
00310 
00311     iRet = 0;
00312     for( i = 0; i < items; i++ ) {
00313         iRet_buff = Devi_A[i] * Devi_B[i];
00314         iRet     += iRet_buff;
00315     }
00316     iRet /= items;
00317 
00318     return iRet;
00319 }
00320 
00321 //------------------------------------------------------------------//
00322 // Judgement_ImageMatching
00323 //------------------------------------------------------------------//
00324 int Judgement_ImageMatching( double Covari, double SDevi_A, double SDevi_B )
00325 {
00326     int     iRet;
00327 
00328     iRet  = ( Covari * 100 ) / ( SDevi_A * SDevi_B );
00329 
00330     return iRet;
00331 }
00332 
00333 //------------------------------------------------------------------//
00334 // Pattern Matching process
00335 //------------------------------------------------------------------//
00336 void PatternMatching_process( unsigned char *BuffAddrIn, int HW, int VW,
00337                               ImagePartPattern *Temp, int Xs, int Xe, int Ys, int Ye )
00338 {
00339     ImagePartPattern    NowImage;
00340     volatile int        x, y;
00341     volatile int        retJudge;
00342     volatile double     retCovari;
00343 
00344     Temp->p = 0;
00345     for( y = Ys; y <= Ye; y++ ) {
00346         for( x = Xs; x <= Xe; x++ ) {
00347             Image_part_Extraction( BuffAddrIn, HW, VW, x, y, NowImage.binary, Temp->w, Temp->h );
00348             NowImage.sdevi = Standard_Deviation( NowImage.binary, NowImage.devi, Temp->w, Temp->h);
00349             retCovari      = Covariance( Temp->devi, NowImage.devi, Temp->w, Temp->h );
00350             retJudge       = 0;
00351             retJudge       = Judgement_ImageMatching( retCovari, Temp->sdevi, NowImage.sdevi );
00352             if( 100 >= retJudge && retJudge > Temp->p ) {
00353                 Temp->x = x;
00354                 Temp->y = y;
00355                 Temp->p = retJudge;
00356             }
00357         }
00358     }
00359 }
00360 
00361 //------------------------------------------------------------------//
00362 // End of file
00363 //------------------------------------------------------------------//