//*************************************************************************
// 関数名 resizeImage
// 概要 画像のリサイズ
// 引数 <in> const IplImage* v_in_image 対象画像
// <in> int v_width リサイズ後の幅
// <in> int v_height リサイズ後の高さ
// <out> IplImage &v_out_image リサイズ後の画像
// 作者 arkdemon
// 作成日 2015.07.15
//*************************************************************************
int resizeImage
( const IplImage* v_in_image,
int v_width,
int v_height,
IplImage* &v_out_image
)
{
//P)前処理.................................................................
int return_value = CAI_RES_OK;
if ( v_in_image == NULL )
{
return_value = CAI_RES_RESIZEIMAGE_ERROR + CAI_RES_NonImage;
}
if ( CAI_RES_OK == return_value )
{
if ( ( v_in_image->width < 1 ) || ( v_in_image->height < 1 ) )
{
return_value = CAI_RES_RESIZEIMAGE_ERROR + CAI_RES_PARAM_ERROR;
}
if ( v_in_image->nChannels != 3 )
{
return_value = CAI_RES_RESIZEIMAGE_ERROR + CAI_RES_PARAM_ERROR;
}
}
if ( CAI_RES_OK == return_value )
{
if ( ( v_width < 1 ) || ( v_height < 1 ) )
{
return_value = CAI_RES_RESIZEIMAGE_ERROR + CAI_RES_PARAM_ERROR;
}
}
if ( CAI_RES_OK == return_value )
{
v_out_image = cvCreateImage
( cvSize( v_width, v_height ),
IPL_DEPTH_8U,
v_in_image->nChannels
);
if ( v_out_image == NULL )
{
return_value = CAI_RES_CreateImage_Error;
}
}
//P).......................................................................
//1)主処理.................................................................
double ozz_x = 1.00;
double ozz_y = 1.00;
if ( CAI_RES_OK == return_value )
{
ozz_x = (double)v_width / (double)v_in_image->width;
ozz_y = (double)v_height / (double)v_in_image->height;
int sx = 0;
int sy = 0;
int ex = 0;
int ey = 0;
double sum_area = 0.00;
double sum_blue = 0.00;
double sum_red = 0.00;
double sum_green = 0.00;
//縮小画像へドット情報を格納する
for( int wy = 0; wy < v_height; wy++ )
{
for( int wx = 0; wx < v_width; wx++ )
{
int addr = wy * v_out_image->widthStep + (wx * v_out_image->nChannels);
v_out_image->imageData[addr + 0] = (unsigned char)(255);
v_out_image->imageData[addr + 1] = (unsigned char)(255);
v_out_image->imageData[addr + 2] = (unsigned char)(255);
//その座標に対応する縮小前の座標を計算する
sx = int((double)(wx - 0.0) / ozz_x);
sy = int((double)(wy - 0.0) / ozz_y);
ex = int((double)(wx + 1.0) / ozz_x + 1);
ey = int((double)(wy + 1.0) / ozz_y + 1);
if(sx < 0){ sx = 0;}
if(sy < 0){ sy = 0;}
if(ex >= v_in_image->width){ ex = v_in_image->width – 1;}
if(ey >= v_in_image->height){ ey = v_in_image->height - 1;}
//その範囲の明度(BGR成分について)の平均を取得する
sum_area = 0.00;
sum_blue = 0.00;
sum_red = 0.00;
sum_green = 0.00;
for( int in_wy = sy; in_wy <= ey; in_wy++ )
{
double double_y = 1.00;
if( in_wy == sy )
{
double_y =(double)(in_wy + 1) - ((double)(wy) / ozz_x);
if(double_y < 0.00){ double_y = 0.00;}
if(double_y > 1.00){ double_y = 1.00;}
}
if ( in_wy == ey )
{
double_y = ( (double)(wy) / ozz_x - (double)(in_wy - 1));
if(double_y < 0.00){ double_y = 0.00;}
if(double_y > 1.00){ double_y = 1.00;}
}
for( int in_wx = sx; in_wx <= ex; in_wx++ )
{
double double_x = 1.00;
if( in_wx == sx )
{
double_x =(double)(in_wx + 1) - ((double)(wx) / ozz_x);
if(double_x < 0.00){ double_x = 0.00;}
if(double_x > 1.00){ double_x = 1.00;}
}
if( in_wx == ex )
{
double_x = ( (double)(wx) / ozz_x - (double)(in_wx - 1));
if(double_x < 0.00){ double_x = 0.00;}
if(double_x > 1.00){ double_x = 1.00;}
}
int in_addr
= in_wy * v_in_image->widthStep + (in_wx * v_in_image->nChannels);
sum_area += (double_x * double_y);
sum_blue += (double)( (unsigned char)v_in_image->imageData
[in_addr + 0] ) * (double_x * double_y);
sum_green += (double)( (unsigned char)v_in_image->imageData
[in_addr + 1] ) * (double_x * double_y);
sum_red += (double)( (unsigned char)v_in_image->imageData
[in_addr + 2] ) * (double_x * double_y);
}
}
if( sum_area >= 0.0000001 )
{
sum_blue /= sum_area;
sum_red /= sum_area;
sum_green /= sum_area;
if(sum_blue < 0){ sum_blue = 0;} if(sum_blue > 255){ sum_blue = 255;}
if(sum_green < 0){ sum_green = 0;} if(sum_green > 255){ sum_green = 255;}
if(sum_red < 0){ sum_red = 0;} if(sum_red > 255){ sum_red = 255;}
v_out_image->imageData[addr + 0] = (unsigned char)sum_blue;
v_out_image->imageData[addr + 1] = (unsigned char)sum_green;
v_out_image->imageData[addr + 2] = (unsigned char)sum_red;
}
}
}
}
//1).......................................................................
return return_value;
}