This program supports the Image processing micon car production kit (M-S348).
Dependencies: GR-PEACH_video mbed
Diff: image_process.cpp
- Revision:
- 0:00b6f7454ada
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/image_process.cpp Tue Oct 30 09:06:30 2018 +0000 @@ -0,0 +1,363 @@ +//------------------------------------------------------------------// +//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 +//------------------------------------------------------------------// \ No newline at end of file