This program supports the Image processing micon car production kit (M-S348).
Dependencies: GR-PEACH_video mbed
image_process.cpp
- Committer:
- TetsuyaKonno
- Date:
- 2018-10-30
- Revision:
- 0:00b6f7454ada
File content as of revision 0:00b6f7454ada:
//------------------------------------------------------------------// //Supported MCU: RZ/A1H //File Contents: Image Processing API ( Source file ) //Version number: Ver.1.00 //Date: 2018.10.30 //Copyright: Renesas Electronics Corporation // Hitachi Document Solutions Co., Ltd. //------------------------------------------------------------------// //------------------------------------------------------------------// //Include //------------------------------------------------------------------// #include <math.h> #include "mbed.h" #include "image_process.h" /*******************************/ /* Function Map */ /******************************** * ImageCopy * Extraction_Brightness * ImageReduction * Binarization * Image_part_Extraction * Standard_Deviation * Covariance * Judgement_ImageMatching * PatternMatching_process ********************************/ //******************************************************************// // Image process functions //*******************************************************************/ //------------------------------------------------------------------// // ImageCopy function //------------------------------------------------------------------// void ImageCopy( unsigned char *BuffAddrIn, int HW, int VW, unsigned char *BuffAddrOut, int Frame ) { static int counter = 0; static int X, Y; int HW_T;//HW Twice HW_T = HW + HW; switch( counter++ ) { case 0: // Top or Bottom field for( Y = Frame; Y < ( VW / 2 ); Y+=2 ){ for( X = 0; X < HW_T; X++ ){ BuffAddrOut[ ( Y * HW_T ) + X ] = BuffAddrIn[ ( Y * HW_T ) + X ]; } } break; case 1: // Top or Bottom field for( ; Y < VW; Y+=2 ){ for( X = 0; X < HW_T; X++ ){ BuffAddrOut[ ( Y * HW_T ) + X ] = BuffAddrIn[ ( Y * HW_T ) + X ]; } } //Frame Change if( Frame == 0 ) Frame = 1; else Frame = 0; for( Y = Frame; Y < VW; Y+=2 ){ for( X = 0; X < HW_T; X+=2 ){ BuffAddrOut[ ( Y * HW_T ) + ( X + 0 ) ] = 0; BuffAddrOut[ ( Y * HW_T ) + ( X + 1 ) ] = 128; } } counter = 0; break; default: break; } } //------------------------------------------------------------------// // Extraction Brightness function //------------------------------------------------------------------// void Extraction_Brightness( unsigned char *BuffAddrIn, int HW, int VW, unsigned char *BuffAddrOut, int Frame ) { static int conter = 0; int X, Y; int Px; int HW_T;//HW Twice HW_T = HW + HW; switch( conter++ ) { case 0: //Pixel Interpolation ( Top or Bottom ) for( Y = Frame; Y < ( VW / 2 ); Y+=2 ){ for( X = 0, Px = 0; X < HW_T; X+=2, Px++ ){ BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrIn[ ( Y * HW_T ) + X ]; } } //Frame Change if( Frame == 0 ) Frame = 1; else Frame = 0; //Bilinear Interpolation Method for( Y = Frame; Y < ( VW / 2 ); Y+=2 ){ for( X = 0, Px = 0; X < HW_T; X+=2, Px++ ){ if( Y <= 0 ) { BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrOut[ ( (Y+1) * HW ) + Px ]; } else if( ( ( VW / 2 ) - 1 ) > Y && Y > 0 ) { BuffAddrOut[ ( Y * HW ) + Px ] = ( BuffAddrOut[ ( (Y-1) * HW ) + Px ] * (double)0.5 ) + ( BuffAddrOut[ ( (Y+1) * HW ) + Px ] * (double)0.5 ); } else if( Y >= ( ( VW / 2 ) - 1 ) ) { BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrOut[ ( (Y-1) * HW ) + Px ]; } } } break; case 1: //Pixel Interpolation ( Top or Bottom ) for( Y = ( VW / 2 ) + Frame; Y < VW; Y+=2 ){ for( X = 0, Px = 0; X < HW_T; X+=2, Px++ ){ BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrIn[ ( Y * HW_T ) + X ]; } } //Frame Change if( Frame == 0 ) Frame = 1; else Frame = 0; //Bilinear Interpolation Method for( Y = ( VW / 2 ) + Frame; Y < VW; Y+=2 ){ for( X = 0, Px = 0; X < HW_T; X+=2, Px++ ){ if( Y <= 0 ) { BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrOut[ ( (Y+1) * HW ) + Px ]; } else if( ( VW - 1 ) > Y && Y > 0 ) { BuffAddrOut[ ( Y * HW ) + Px ] = ( BuffAddrOut[ ( (Y-1) * HW ) + Px ] * (double)0.5 ) + ( BuffAddrOut[ ( (Y+1) * HW ) + Px ] * (double)0.5 ); } else if( Y >= ( VW - 1 ) ) { BuffAddrOut[ ( Y * HW ) + Px ] = BuffAddrOut[ ( (Y-1) * HW ) + Px ]; } } } conter = 0; break; default: break; } } //------------------------------------------------------------------// // Image Reduction function // Parcent : 0.0 - 1.0 //------------------------------------------------------------------// void ImageReduction( unsigned char *BuffAddrIn, int HW, int VW, unsigned char *BuffAddrOut, double Percent ) { static int conter = 0; static int Y; int X; int HW_N; long Nx, Ny; long NxBuff, NyBuff; unsigned int BuffAddrData; double long Sx, Sy; NxBuff = -1; Sx = Sy = Percent; HW_N = HW * Percent; //Under 100% if( Percent <= 1 ) { switch( conter++ ) { case 0: for( Y = 0; Y < ( VW / 2 ); Y++ ){ //Affine Transformation Y-axis Ny = ( Sy * Y ); for( X = 0; X < HW; X++ ){ //Affine Transformation X-axis Nx = ( Sx * X ); if( NxBuff == Nx ) { BuffAddrData = BuffAddrOut[ ( Ny * HW_N ) + Nx ]; BuffAddrData += BuffAddrIn[ ( Y * HW ) + X ]; BuffAddrData /= 2; BuffAddrOut[ ( Ny * HW_N ) + Nx ] = BuffAddrData; } else { NxBuff = Nx; BuffAddrOut[ ( Ny * HW_N ) + Nx ] = BuffAddrIn[ ( Y * HW ) + X ]; } } if( NyBuff == Ny ) { for( X = 0; X < HW_N; X++ ){ BuffAddrData = BuffAddrOut[ ( Ny * HW_N ) + X ];//Now line BuffAddrData += BuffAddrOut[ ( (Ny - 1) * HW_N ) + X ];//Before now line BuffAddrData /= 2; BuffAddrOut[ ( Ny * HW_N ) + X ] = BuffAddrData; } } else { NyBuff = Ny; } } break; case 1: for( ; Y < VW; Y++ ){ //Affine Transformation Y-axis Ny = ( Sy * Y ); for( X = 0; X < HW; X++ ){ //Affine Transformation X-axis Nx = ( Sx * X ); if( NxBuff == Nx ) { BuffAddrData = BuffAddrOut[ ( Ny * HW_N ) + Nx ]; BuffAddrData += BuffAddrIn[ ( Y * HW ) + X ]; BuffAddrData /= 2; BuffAddrOut[ ( Ny * HW_N ) + Nx ] = BuffAddrData; } else { NxBuff = Nx; BuffAddrOut[ ( Ny * HW_N ) + Nx ] = BuffAddrIn[ ( Y * HW ) + X ]; } } if( NyBuff == Ny ) { for( X = 0; X < HW_N; X++ ){ BuffAddrData = BuffAddrOut[ ( Ny * HW_N ) + X ];//Now line BuffAddrData += BuffAddrOut[ ( (Ny - 1) * HW_N ) + X ];//Before now line BuffAddrData /= 2; BuffAddrOut[ ( Ny * HW_N ) + X ] = BuffAddrData; } } else { NyBuff = Ny; } } conter = 0; break; default: break; } } } //------------------------------------------------------------------// // Binarization process Function //------------------------------------------------------------------// void Binarization( unsigned char *BuffAddrIn, int HW, int VW, unsigned char *BuffAddrOut, int threshold ) { int i; int items; items = HW * VW; for( i = 0; i < items; i++ ) { if( BuffAddrIn[i] >= threshold ) BuffAddrOut[i] = 1; else BuffAddrOut[i] = 0; } } //******************************************************************// // Mark detect functions //*******************************************************************/ //------------------------------------------------------------------// // Extract_Image //------------------------------------------------------------------// void Image_part_Extraction( unsigned char *BuffAddrIn, int HW, int VW, int CutPointX, int CutPointY, unsigned char *BuffAddrOut, int Xsize, int Ysize ) { int X, Y; for( Y = 0; Y < Ysize; Y++ ) { for( X = 0; X < Xsize; X++ ) { BuffAddrOut[ X + ( Y * Xsize ) ] = BuffAddrIn[ ( ( Y + CutPointY ) * HW ) + ( X + CutPointX ) ]; } } } //------------------------------------------------------------------// // Standard deviation //------------------------------------------------------------------// double Standard_Deviation( unsigned char *data, double *Devi, int Xsize, int Ysize ) { int i; int items; double iRet_A, iRet_C, iRet_D; items = Xsize * Ysize; /* A 合計値 平均化 */ iRet_A = 0; for( i = 0; i < items; i++ ) { iRet_A += data[i]; } iRet_A /= items; /* B 偏差値 */ for( i = 0; i < items; i++ ) { Devi[i] = data[i] - iRet_A; } /* C 分散 */ iRet_C = 0; for( i = 0; i < items; i++ ) { iRet_C += ( Devi[i] * Devi[i] ); } iRet_C /= items; /* D 標準偏差 */ iRet_D = sqrt( iRet_C ); return iRet_D; } //------------------------------------------------------------------// // Covariance //------------------------------------------------------------------// double Covariance( double *Devi_A, double *Devi_B, int Xsize, int Ysize ) { int i; int items; double iRet, iRet_buff; items = Xsize * Ysize; iRet = 0; for( i = 0; i < items; i++ ) { iRet_buff = Devi_A[i] * Devi_B[i]; iRet += iRet_buff; } iRet /= items; return iRet; } //------------------------------------------------------------------// // Judgement_ImageMatching //------------------------------------------------------------------// int Judgement_ImageMatching( double Covari, double SDevi_A, double SDevi_B ) { int iRet; iRet = ( Covari * 100 ) / ( SDevi_A * SDevi_B ); return iRet; } //------------------------------------------------------------------// // Pattern Matching process //------------------------------------------------------------------// void PatternMatching_process( unsigned char *BuffAddrIn, int HW, int VW, ImagePartPattern *Temp, int Xs, int Xe, int Ys, int Ye ) { ImagePartPattern NowImage; volatile int x, y; volatile int retJudge; volatile double retCovari; Temp->p = 0; for( y = Ys; y <= Ye; y++ ) { for( x = Xs; x <= Xe; x++ ) { Image_part_Extraction( BuffAddrIn, HW, VW, x, y, NowImage.binary, Temp->w, Temp->h ); NowImage.sdevi = Standard_Deviation( NowImage.binary, NowImage.devi, Temp->w, Temp->h); retCovari = Covariance( Temp->devi, NowImage.devi, Temp->w, Temp->h ); retJudge = 0; retJudge = Judgement_ImageMatching( retCovari, Temp->sdevi, NowImage.sdevi ); if( 100 >= retJudge && retJudge > Temp->p ) { Temp->x = x; Temp->y = y; Temp->p = retJudge; } } } } //------------------------------------------------------------------// // End of file //------------------------------------------------------------------//