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
//------------------------------------------------------------------//