#include <stdio.h>
#include "fie.h"
#include "oal_aloc.h"
#include <math.h>
typedef struct
{
INT x;
INT y;
INT score;
INT angle;
}SMP_RESULT_ROT;
#define DEG_TO_RAD(a) ( (a)*PI/180.0 )
#define RAD_TO_DEG(a) ( (a)*180.0/PI )
#define SAMPLE_PRINT
#ifdef SAMPLE_PRINT
#define PRINT_RESULT( result, result_num )\
{\
INT num;\
puts("result");\
for( num = 0; num < result_num; num++ )\
{\
printf("No.%2d : score %d, ( %d, %d ) angle:%d\n",\
num, result[num].score, result[num].x/100, result[num].y/100, result[num].angle/10 );\
}\
}
#else
#define PRINT_RESULT( result, result_num )
#endif
INT fnSMP_gray_search_rot(
FHANDLE hgs,
FHANDLE hpattern,
FHANDLE himage,
BOX_T search_window,
INT threshold_mid,
INT threshold_final,
INT edge_detect,
INT reverse_mode,
INT pitch_x,
INT pitch_y,
INT pitch_angle,
INT first_unit,
INT last_unit,
enum f_gs2_subpxl_neib subpxl_neib,
INT max_result_num,
INT base_angle,
INT plus_rot,
INT minus_rot,
SMP_RESULT_ROT *result,
INT *result_num
);
static BOOL fnSMP_angle_diff_comp( INT a, INT b, INT pitch_angle );
static INT FVALGAPI fnSMP_comp_ex( VOID *search_result, const VOID *p_index1, const VOID *p_index2 );
static INT fnSMP_sort_result( FHANDLE hvarray, SMP_RESULT_ROT *result, INT pitch_x, INT pitch_y, INT pitch_angle, INT max_result_num, INT *result_num );
static INT fnSMP_result_add( F_GS_RESULT *result, FHANDLE hvarray, INT result_num, INT angle );
INT fnSMP_gray_search_rot(
FHANDLE hgs,
FHANDLE hpattern,
FHANDLE himage,
BOX_T search_window,
INT threshold_mid,
INT threshold_final,
INT edge_detect,
INT reverse_mode,
INT pitch_x,
INT pitch_y,
INT pitch_angle,
INT first_unit,
INT last_unit,
enum f_gs2_subpxl_neib subpxl_neib,
INT max_result_num,
INT base_angle,
INT plus_rot,
INT minus_rot,
SMP_RESULT_ROT *result,
INT *result_num
)
{
INT ret = F_ERR_UNKNOWN;
FHANDLE hrot_pattern = NULL;
INT clip_width = I32_MAX;
INT clip_height = I32_MAX;
INT rotate_pattern = 0;
F_GS_RESULT *result_buff = NULL;
FHANDLE hvary = NULL;
INT inc_num = 10;
INT total_count = ( plus_rot + minus_rot ) / inc_num + 1;
FHANDLE pat_img = NULL;
ret = F_ERR_INVALID_PARAM;
if( base_angle < 0 || base_angle > 3600 || plus_rot < 0 || plus_rot > 1800 || minus_rot < 0 || minus_rot > 1800 )
goto EXIT;
if( pitch_x < 0 || pitch_y < 0 )
goto EXIT;
if( pitch_angle < 0 || pitch_angle > 180 )
goto EXIT;
if( NULL == result || NULL == result_num )
goto EXIT;
ret = F_ERR_NOMEMORY;
result_buff = (F_GS_RESULT*)fnOAL_calloc( max_result_num, sizeof(F_GS_RESULT) );
if( NULL == result_buff ) goto EXIT;
hvary = fnFIE_vectarray_alloc( (enum f_objtag)0, sizeof(SMP_RESULT_ROT), 0 );
if( NULL == hvary ) goto EXIT;
if( pitch_x == 0 || pitch_y == 0 )
{
ret = fnFIE_gs2_pattern_get_image( hpattern, &pat_img );
if( F_ERR_NONE != ret ) goto EXIT;
if( pitch_x == 0 )
pitch_x = fnFIE_img_get_width( pat_img ) / 2;
if( pitch_y == 0 )
pitch_y = fnFIE_img_get_height( pat_img ) / 2;
}
if( pitch_angle == 0 )
pitch_angle = ( plus_rot + minus_rot ) / 2;
{
INT i;
INT start = base_angle - minus_rot;
INT end = base_angle + plus_rot;
INT rot_angle;
FHANDLE himage_buff = himage;
for( i = start; i <= end; i+= inc_num )
{
rot_angle = i % 3600;
if( rot_angle < 0 )
rot_angle += 3600;
ret = fnFIE_gs2_pattern_rotate(
hpattern,
rot_angle,
clip_width,
clip_height,
rotate_pattern,
&hrot_pattern
);
if( F_ERR_NONE != ret ) goto EXIT;
ret =fnFIE_gs2_search_enforce2(
hgs,
hrot_pattern,
himage_buff,
search_window,
threshold_mid, threshold_final,
edge_detect,
reverse_mode,
pitch_x, pitch_y,
first_unit,
last_unit,
subpxl_neib,
result_buff,
max_result_num,
result_num
);
if( F_ERR_NONE != ret ) goto EXIT;
ret = fnSMP_result_add( result_buff, hvary, *result_num, rot_angle );
if( F_ERR_NONE != ret ) goto EXIT;
fnFIE_free_object( hrot_pattern ); hrot_pattern = NULL;
himage_buff = NULL;
}
ret = fnSMP_sort_result( hvary, result, pitch_x, pitch_y, pitch_angle, max_result_num, result_num );
if( F_ERR_NONE != ret ) goto EXIT;
}
EXIT:
fnOAL_free( result_buff );
fnFIE_free_object( hrot_pattern );
fnFIE_free_object( pat_img );
fnFIE_vectarray_free( hvary );
return ret;
}
static BOOL fnSMP_angle_diff_comp( INT a, INT b, INT pitch_angle )
{
DOUBLE rad_a = DEG_TO_RAD( a );
DOUBLE rad_b = DEG_TO_RAD( b );
DOUBLE pitch_angle_cos = cos( DEG_TO_RAD( pitch_angle ) );
DOUBLE x1, y1;
DOUBLE x2, y2;
DOUBLE angle_sub_cos;
x1 = cos( rad_a );
y1 = sin( rad_a );
x2 = cos( rad_b );
y2 = sin( rad_b );
angle_sub_cos = ( ( x1 * x2 ) + ( y1 * y2 ) );
if( angle_sub_cos > pitch_angle_cos )
return TRUE;
else
return FALSE;
}
static INT FVALGAPI fnSMP_comp_ex( VOID *search_result, const VOID *p_index1, const VOID *p_index2 )
{
SMP_RESULT_ROT *result = (SMP_RESULT_ROT*)search_result;
INT index1 = *(INT*)p_index1;
INT index2 = *(INT*)p_index2;
SMP_RESULT_ROT *result1 = result + index1;
SMP_RESULT_ROT *result2 = result + index2;
if( result1->score < result2->score )
return 1;
else if( result1->score > result2->score )
return -1;
else
{
if( result1->angle < result2->angle )
return -1;
else if( result1->angle > result2->angle )
return 1;
else
return 0;
}
}
static INT fnSMP_sort_result(
FHANDLE hvarray,
SMP_RESULT_ROT *result,
INT pitch_x, INT pitch_y, INT pitch_angle,
INT max_result_num, INT *result_num
)
{
INT ret = F_ERR_UNKNOWN;
SMP_RESULT_ROT *p_hvarray = NULL;
INT ary_size;
INT *sort_indexes = NULL;
INT *hit_flags = NULL;
ret = F_ERR_INVALID_PARAM;
if( NULL == hvarray || NULL == result || NULL == result_num ) goto EXIT;
if( max_result_num < 1 ) goto EXIT;
if( pitch_x < 1 || pitch_y < 1 || pitch_angle < 1 ) goto EXIT;
ary_size = fnFIE_vectarray_getnum( hvarray );
if( ary_size < 0 ) goto EXIT;
ret = F_ERR_NOMEMORY;
sort_indexes = (INT*)fnOAL_malloc( sizeof(INT) * ary_size );
if( NULL == sort_indexes ) goto EXIT;
hit_flags = (INT*)fnOAL_malloc( sizeof(INT) * ary_size );
if( NULL == hit_flags ) goto EXIT;
{
INT i;
for( i = 0; i < ary_size; i++ )
{
sort_indexes[i] = i;
hit_flags[i] = 0;
}
}
p_hvarray = (SMP_RESULT_ROT*)fnFIE_vectarray_getptr( hvarray );
fnFIE_qsort_ex( sort_indexes, ary_size, sizeof(INT), fnSMP_comp_ex, (SMP_RESULT_ROT*)p_hvarray );
pitch_x *= 100;
pitch_y *= 100;
{
INT i;
for( i = 0; i < ary_size; i++ )
{
SMP_RESULT_ROT result = *( ( SMP_RESULT_ROT* )fnFIE_vectarray_getat( hvarray, sort_indexes[i] ) );
INT x = result.x;
INT y = result.y;
INT angle = result.angle;
INT j;
for( j = i+1; j < ary_size; j++ )
{
SMP_RESULT_ROT dresult = *( ( SMP_RESULT_ROT* )fnFIE_vectarray_getat( hvarray, sort_indexes[j] ) );
INT dx = abs( dresult.x - x );
INT dy = abs( dresult.y - y );
INT dangle = dresult.angle;
BOOL angle_judge = fnSMP_angle_diff_comp( angle/10, dangle/10, pitch_angle );
if( ( dx < pitch_x ) && ( dy < pitch_y ) && ( angle_judge ) )
{
hit_flags[j] = 1;
}
}
}
}
{
INT i;
INT dst_ary_index = 0;
for( i = 0; i < ary_size; i++ )
{
if( !(hit_flags[i]) )
{
SMP_RESULT_ROT result_buff = *( ( SMP_RESULT_ROT* )fnFIE_vectarray_getat( hvarray, sort_indexes[i] ) );
result[dst_ary_index].score = result_buff.score;
result[dst_ary_index].x = result_buff.x;
result[dst_ary_index].y = result_buff.y;
result[dst_ary_index].angle = result_buff.angle;
dst_ary_index++;
}
if( max_result_num <= dst_ary_index )
{
dst_ary_index = max_result_num;
break;
}
}
*result_num = dst_ary_index;
}
ret = F_ERR_NONE;
EXIT:
fnOAL_free( sort_indexes );
fnOAL_free( hit_flags );
return ret;
}
static INT fnSMP_result_add( F_GS_RESULT *result, FHANDLE hvarray, INT result_num, INT angle )
{
INT ret = F_ERR_UNKNOWN;
SMP_RESULT_ROT result_buff;
INT i;
if( NULL == result || NULL == hvarray )
return F_ERR_INVALID_PARAM;
if( result_num < 0 )
return F_ERR_INVALID_PARAM;
for( i = 0; i < result_num; i++ )
{
result_buff.score = result[i].score;
result_buff.x = result[i].x;
result_buff.y = result[i].y;
result_buff.angle = angle;
ret = fnFIE_vectarray_push_back( hvarray, &result_buff );
if( F_ERR_NONE != ret ) return ret;
}
return F_ERR_NONE;
}
static INT execute()
{
INT ret = F_ERR_UNKNOWN;
FHANDLE pat_img = NULL;
INT pattern_w, pattern_h;
FHANDLE hgs = NULL;
FHANDLE himage = NULL;
FHANDLE hpattern = NULL;
BOX_T search_window;
INT threshold_mid = 3500;
INT threshold_final = 5000;
INT edge_detect = TRUE;
INT reverse_mode = FALSE;
INT pitch_x = 0;
INT pitch_y = 0;
INT pitch_angle = 45;
INT first_unit = 5;
INT last_unit = 0;
enum f_gs2_subpxl_neib subpxl_neib = F_GS2_SUBPXL_NEIB_4;
INT max_result_num = 100;
INT base_angle = 0;
INT plus_rot = 1800;
INT minus_rot = 1800;
SMP_RESULT_ROT *result = NULL;
INT result_num;
ret = fnFIE_load_img_file( "rot_gray_search.png", &himage, F_COLOR_IMG_TYPE_UC8 );
if( F_ERR_NONE != ret ) goto EXIT;
ret = fnFIE_load_img_file( "rot_pattern.png", &pat_img, F_COLOR_IMG_TYPE_UC8 );
if( F_ERR_NONE != ret ) goto EXIT;
pattern_w = ( fnFIE_img_get_width( pat_img ) / 2 ) * 100;
pattern_h = ( fnFIE_img_get_height( pat_img ) / 2 ) * 100;
hpattern = fnFIE_gs2_pattern_alloc( pat_img, NULL, pattern_w, pattern_h, F_COMP_MODE_SMOOTH, &ret );
if( F_ERR_NONE != ret ) goto EXIT;
hgs = fnFIE_gs2_alloc( 0, 0, 0 );
search_window.st.x = 0;
search_window.st.y = 0;
search_window.ed.x = fnFIE_img_get_width( himage )-1;
search_window.ed.y = fnFIE_img_get_height( himage )-1;
result = (SMP_RESULT_ROT*)fnOAL_calloc( max_result_num, sizeof(SMP_RESULT_ROT) );
if( NULL == result ) goto EXIT;
ret = fnSMP_gray_search_rot( hgs,
hpattern,
himage,
search_window,
threshold_mid,
threshold_final,
edge_detect,
reverse_mode,
pitch_x,
pitch_y,
pitch_angle,
first_unit,
last_unit,
subpxl_neib,
max_result_num,
base_angle,
plus_rot,
minus_rot,
result,
&result_num
);
PRINT_RESULT( result, result_num );
EXIT:
fnFIE_free_object( himage );
fnFIE_free_object( pat_img );
fnFIE_free_object( hpattern );
fnFIE_free_object( hgs );
fnOAL_free( result );
return ret;
}
INT main( )
{
INT ret = F_ERR_UNKNOWN;
fnFIE_setup();
ret = execute();
fnFIE_teardown();
return ret;
}
微小変形する対象のサーチにおける位置決め
#include <stdio.h>
#include "fie.h"
#include "oal_aloc.h"
#include <math.h>
typedef struct
{
INT x;
INT y;
INT score;
INT pattern_id;
}SMP_RESULT_MULTI;
#define SAMPLE_PRINT
#define PATTERN_NUM 4
#ifdef SAMPLE_PRINT
#define PRINT_RESULT( result, result_num )\
{\
INT num;\
puts("result");\
for( num = 0; num < result_num; num++ )\
{\
printf("No.%2d : score %d, ( %d, %d ) pattarn_id:%d\n",\
num, result[num].score, result[num].x/100, result[num].y/100, result[num].pattern_id );\
}\
}
#else
#define PRINT_RESULT( result, result_num )
#endif
INT fnSMP_gray_search_multipattern(
FHANDLE hgs,
FHANDLE *hpatterns,
INT pattern_num,
FHANDLE himage,
BOX_T search_window,
INT threshold_mid,
INT threshold_final,
INT edge_detect,
INT reverse_mode,
INT pitch_x,
INT pitch_y,
INT first_unit,
INT last_unit,
enum f_gs2_subpxl_neib subpxl_neib,
INT max_result_num,
SMP_RESULT_MULTI *result,
INT *result_num
);
static INT fnSMP_alloc_patterns( CHAR **filenames, PNT_T *mark_offset, FHANDLE *hmasks, INT pattern_num, FHANDLE **hpatterns );
static VOID fnSMP_free_patterns( FHANDLE *hpatterns, INT pattern_num );
static INT FVALGAPI fnSMP_comp_ex( VOID *search_result, const VOID *p_index1, const VOID *p_index2 );
static INT fnSMP_sort_result( FHANDLE hvarray, SMP_RESULT_MULTI *result, INT pitch_x, INT pitch_y, INT max_result_num, INT *result_num );
static INT fnSMP_result_add( F_GS_RESULT *result, FHANDLE hvarray, INT result_num, INT pattern_id );
static INT fnSMP_pitch_calc( FHANDLE *hpatterns, INT pattern_num, INT *pitch_x, INT *pitch_y );
INT fnSMP_gray_search_multipattern(
FHANDLE hgs,
FHANDLE *hpatterns,
INT pattern_num,
FHANDLE himage,
BOX_T search_window,
INT threshold_mid,
INT threshold_final,
INT edge_detect,
INT reverse_mode,
INT pitch_x,
INT pitch_y,
INT first_unit,
INT last_unit,
enum f_gs2_subpxl_neib subpxl_neib,
INT max_result_num,
SMP_RESULT_MULTI *result,
INT *result_num
)
{
INT ret = F_ERR_UNKNOWN;
F_GS_RESULT *result_buff = NULL;
FHANDLE hvary = NULL;
ret = F_ERR_INVALID_PARAM;
if( NULL == result || NULL == hpatterns ) goto EXIT;
if( pitch_x < 0 || pitch_y < 0 ) goto EXIT;
ret = F_ERR_NOMEMORY;
result_buff = (F_GS_RESULT*)fnOAL_calloc( max_result_num, sizeof(F_GS_RESULT) );
if( NULL == result_buff ) goto EXIT;
hvary = fnFIE_vectarray_alloc( (enum f_objtag)0, sizeof(SMP_RESULT_MULTI), 0 );
if( NULL == hvary ) goto EXIT;
if( pitch_x == 0 || pitch_y == 0 )
{
ret = fnSMP_pitch_calc( hpatterns, pattern_num, &pitch_x, &pitch_y );
if( F_ERR_NONE != ret ) goto EXIT;
}
ret = F_ERR_UNKNOWN;
{
INT i;
FHANDLE himage_buff = himage;
for( i = 0; i < pattern_num; i++ )
{
ret = fnFIE_gs2_search_enforce2(
hgs,
hpatterns[i],
himage_buff,
search_window,
threshold_mid, threshold_final,
edge_detect,
reverse_mode,
pitch_x, pitch_y,
first_unit,
last_unit,
subpxl_neib,
result_buff,
max_result_num,
result_num
);
if( F_ERR_NONE != ret ) goto EXIT;
ret = fnSMP_result_add( result_buff, hvary, *result_num, i );
if( F_ERR_NONE != ret ) goto EXIT;
himage_buff = NULL;
}
ret = fnSMP_sort_result( hvary, result, pitch_x, pitch_y, max_result_num, result_num );
if( ret != F_ERR_NONE ) goto EXIT;
}
EXIT:
fnOAL_free( result_buff );
fnFIE_vectarray_free( hvary );
return ret;
}
static INT fnSMP_alloc_patterns( CHAR **filenames, PNT_T *mark_offset, FHANDLE *hmasks, INT pattern_num, FHANDLE **hpatterns )
{
INT ret = F_ERR_UNKNOWN;
enum f_comp_filter comp_filter = F_COMP_MODE_SMOOTH;
FHANDLE *hpat_buff = NULL;
FHANDLE himg = NULL;
ret = F_ERR_INVALID_PARAM;
if( NULL == hpatterns || NULL != (*hpatterns) ) goto EXIT;
ret = F_ERR_NOMEMORY;
hpat_buff = (FHANDLE*)fnOAL_calloc( pattern_num, sizeof(FHANDLE) );
if( NULL == hpat_buff ) goto EXIT;
{
INT i;
for( i = 0; i < pattern_num; i++ )
{
ret = fnFIE_load_img_file( filenames[i], &himg, F_COLOR_IMG_TYPE_UC8 );
if( F_ERR_NONE != ret ) goto EXIT;
hpat_buff[i] = fnFIE_gs2_pattern_alloc( himg, hmasks[i], mark_offset[i].x, mark_offset[i].y, comp_filter, &ret );
if( F_ERR_NONE != ret ) goto EXIT;
}
}
EXIT:
if( F_ERR_NONE == ret )
*hpatterns = hpat_buff;
else
fnSMP_free_patterns( hpat_buff, pattern_num );
fnFIE_free_object( himg );
return ret;
}
static VOID fnSMP_free_patterns( FHANDLE *hpatterns, INT pattern_num )
{
INT i;
if( NULL == hpatterns ) return;
for( i =0; i < pattern_num; i++ )
{
fnFIE_free_object( hpatterns[i] );
}
fnOAL_free( hpatterns );
return;
}
static INT FVALGAPI fnSMP_comp_ex( VOID *search_result, const VOID *p_index1, const VOID *p_index2 )
{
SMP_RESULT_MULTI *result = (SMP_RESULT_MULTI*)search_result;
INT index1 = *(INT*)p_index1;
INT index2 = *(INT*)p_index2;
SMP_RESULT_MULTI *result1 = result + index1;
SMP_RESULT_MULTI *result2 = result + index2;
if( result1->score < result2->score )
return 1;
else if( result1->score > result2->score )
return -1;
else
return 0;
}
static INT fnSMP_sort_result(
FHANDLE hvarray,
SMP_RESULT_MULTI *result,
INT pitch_x, INT pitch_y,
INT max_result_num, INT *result_num
)
{
INT ret = F_ERR_UNKNOWN;
SMP_RESULT_MULTI *p_hvarray = NULL;
INT ary_size;
INT *sort_indexes = NULL;
INT *hit_flags = NULL;
ret = F_ERR_INVALID_PARAM;
if( NULL == result ) goto EXIT;
ary_size = fnFIE_vectarray_getnum( hvarray );
ret = F_ERR_NOMEMORY;
sort_indexes = (INT*)fnOAL_malloc( sizeof(INT) * ary_size );
if( NULL == sort_indexes ) goto EXIT;
hit_flags = (INT*)fnOAL_malloc( sizeof(INT) * ary_size );
if( NULL == hit_flags ) goto EXIT;
{
INT i;
for( i = 0; i < ary_size; i++ )
{
sort_indexes[i] = i;
hit_flags[i] = 0;
}
}
p_hvarray = (SMP_RESULT_MULTI*)fnFIE_vectarray_getptr( hvarray );
fnFIE_qsort_ex( sort_indexes, ary_size, sizeof(INT), fnSMP_comp_ex, (SMP_RESULT_MULTI*)p_hvarray );
pitch_x *= 100;
pitch_y *= 100;
{
INT i;
INT num = 0;
for( i = 0; i < ary_size; i++ )
{
SMP_RESULT_MULTI result = *( ( SMP_RESULT_MULTI* )fnFIE_vectarray_getat( hvarray, sort_indexes[i] ) );
INT x = result.x;
INT y = result.y;
INT j;
for( j = i+1; j < ary_size; j++ )
{
SMP_RESULT_MULTI dresult = *( ( SMP_RESULT_MULTI* )fnFIE_vectarray_getat( hvarray, sort_indexes[j] ) );
INT dx = abs( dresult.x - x );
INT dy = abs( dresult.y - y );
if( ( dx < pitch_x ) && ( dy < pitch_y ) )
{
hit_flags[j] = 1;
}
}
}
}
{
INT i;
INT dst_ary_index = 0;
for( i = 0; i < ary_size; i++ )
{
if( !(hit_flags[i]) )
{
SMP_RESULT_MULTI result_buff = *( ( SMP_RESULT_MULTI* )fnFIE_vectarray_getat( hvarray, sort_indexes[i] ) );
result[dst_ary_index].score = result_buff.score;
result[dst_ary_index].x = result_buff.x;
result[dst_ary_index].y = result_buff.y;
result[dst_ary_index].pattern_id = result_buff.pattern_id;
dst_ary_index++;
}
if( max_result_num <= dst_ary_index )
{
dst_ary_index = max_result_num;
break;
}
}
*result_num = dst_ary_index;
}
ret = F_ERR_NONE;
EXIT:
fnOAL_free( sort_indexes );
fnOAL_free( hit_flags );
return ret;
}
static INT fnSMP_result_add( F_GS_RESULT *result, FHANDLE hvarray, INT result_num, INT pattern_id )
{
INT ret = F_ERR_UNKNOWN;
SMP_RESULT_MULTI result_buff;
INT i;
if( NULL == result || NULL == hvarray )
return F_ERR_INVALID_PARAM;
if( result_num < 0 )
return F_ERR_INVALID_PARAM;
for( i = 0; i < result_num; i++ )
{
result_buff.score = result[i].score;
result_buff.x = result[i].x;
result_buff.y = result[i].y;
result_buff.pattern_id = pattern_id;
ret = fnFIE_vectarray_push_back( hvarray, &result_buff );
if( F_ERR_NONE != ret ) return ret;
}
return F_ERR_NONE;
}
static INT fnSMP_pitch_calc( FHANDLE *hpatterns, INT pattern_num, INT *pitch_x, INT *pitch_y )
{
INT ret = F_ERR_UNKNOWN;
DOUBLE x = 0.0;
DOUBLE y = 0.0;
INT i;
FHANDLE pat_img = NULL;
for( i = 0; i < pattern_num; i++ )
{
ret = fnFIE_gs2_pattern_get_image( hpatterns[i], &pat_img );
if( F_ERR_NONE != ret ) goto EXIT;;
x += fnFIE_img_get_width( pat_img );
y += fnFIE_img_get_height( pat_img );
fnFIE_free_object( pat_img ); pat_img = NULL;
}
if( pitch_x == 0 )
*pitch_x = ( fnFIE_d4i5( x / (DOUBLE)pattern_num ) / 2 );
if( pitch_y == 0 )
*pitch_y = ( fnFIE_d4i5( y / (DOUBLE)pattern_num ) / 2 );
EXIT:
fnFIE_free_object( pat_img );
return ret;
}
static INT execute()
{
INT ret = F_ERR_UNKNOWN;
FHANDLE hgs = NULL;
FHANDLE himage = NULL;
FHANDLE *hpatterns = NULL;
INT pattern_num = PATTERN_NUM;
BOX_T search_window;
INT threshold_mid = 3500;
INT threshold_final = 4000;
INT edge_detect = TRUE;
INT reverse_mode = FALSE;
INT pitch_x = 0;
INT pitch_y = 0;
INT first_unit = 5;
INT last_unit = 0;
enum f_gs2_subpxl_neib subpxl_neib = F_GS2_SUBPXL_NEIB_4;
INT max_result_num = 100;
SMP_RESULT_MULTI *result = NULL;
INT result_num;
CHAR *filename[]=
{
"pattern_0.png",
"pattern_1.png",
"pattern_2.png",
"pattern_3.png"
};
PNT_T mark_offset[] =
{
0, 0,
0, 0,
0, 0,
0, 0
};
FHANDLE hmasks[] =
{
NULL,
NULL,
NULL,
NULL
};
ret = fnFIE_load_img_file( "gray_search_multi.png", &himage, F_COLOR_IMG_TYPE_UC8 );
if( F_ERR_NONE != ret ) goto EXIT;
ret = fnSMP_alloc_patterns( filename, mark_offset, hmasks,pattern_num, &hpatterns );
if( F_ERR_NONE != ret ) goto EXIT;
hgs = fnFIE_gs2_alloc( 0, 0, 0 );
search_window.st.x = 0;
search_window.st.y = 0;
search_window.ed.x = fnFIE_img_get_width( himage ) - 1;
search_window.ed.y = fnFIE_img_get_height( himage ) - 1;
ret = F_ERR_NOMEMORY;
result = (SMP_RESULT_MULTI*)fnOAL_calloc( max_result_num, sizeof(SMP_RESULT_MULTI) );
if( NULL == result ) goto EXIT;
ret = fnSMP_gray_search_multipattern(
hgs,
hpatterns,
pattern_num,
himage,
search_window,
threshold_mid,
threshold_final,
edge_detect,
reverse_mode,
pitch_x,
pitch_y,
first_unit,
last_unit,
subpxl_neib,
max_result_num,
result,
&result_num
);
if( F_ERR_NONE != ret ) goto EXIT;
PRINT_RESULT( result, result_num );
EXIT:
fnSMP_free_patterns( hpatterns, pattern_num );
fnFIE_free_object( himage );
fnFIE_free_object( hgs );
fnOAL_free( result );
{
INT i;
for( i = 0; i < pattern_num; i++)
{
fnFIE_free_object( hmasks[i] );
}
}
return ret;
}
INT main( )
{
INT ret = F_ERR_UNKNOWN;
fnFIE_setup();
ret = execute();
fnFIE_teardown();
return ret;
}
複数ワークの判別
#include <stdio.h>
#include "fie.h"
#include "oal_aloc.h"
#include <math.h>
typedef struct
{
INT x;
INT y;
INT score;
INT pattern_id;
}SMP_RESULT_MULTI;
#define SAMPLE_PRINT
#define PATTERN_NUM 4
#ifdef SAMPLE_PRINT
#define PRINT_RESULT( result, result_num, mat )\
{\
INT i,j;\
puts("result");\
for( i = 0; i < result_num; i++ )\
{\
printf("No.%2d : score %d, ( %d, %d ) pattarn_id:%d\n", \
i, result[i].score, result[i].x/100, result[i].y/100, result[i].pattern_id );\
}\
puts("");\
for( i = 0; i < result_num; i++ )\
{\
for( j = 0; j < result_num; j++)\
{\
printf(" %.3f,", mat->m[i][j]);\
}\
puts("");\
}\
}
#else
#define PRINT_RESULT( result, result_num, mat )
#endif
INT fnSMP_gray_search_multipattern_mat(
FHANDLE hgs,
FHANDLE *hpatterns,
INT pattern_num,
FHANDLE himage,
BOX_T search_window,
INT threshold_mid,
INT threshold_final,
INT edge_detect,
INT reverse_mode,
INT pitch_x,
INT pitch_y,
INT first_unit,
INT last_unit,
enum f_gs2_subpxl_neib subpxl_neib,
INT max_result_num,
SMP_RESULT_MULTI *result,
INT *result_num,
FMATRIX **result_comp_mat
);
static INT fnSMP_alloc_patterns( CHAR **filenames, PNT_T *mark_offset, FHANDLE *hmasks, INT pattern_num, FHANDLE **hpatterns );
static VOID fnSMP_free_patterns( FHANDLE *hpatterns, INT pattern_num );
static INT FVALGAPI fnSMP_comp_ex( VOID *search_result, const VOID *p_index1, const VOID *p_index2 );
static INT fnSMP_sort_result( FHANDLE hvarray, SMP_RESULT_MULTI *result, INT max_result_num, INT *result_num );
static INT fnSMP_result_add( F_GS_RESULT *result, FHANDLE hvarray, INT result_num, INT pattern_id );
static INT fnSMP_result_comp_matrix( SMP_RESULT_MULTI *result, FMATRIX *result_comp_mat, INT result_num, INT pitch_x, INT pitch_y );
static INT fnSMP_pitch_calc( FHANDLE *hpatterns, INT pattern_num, INT *pitch_x, INT *pitch_y );
INT fnSMP_gray_search_multipattern_mat(
FHANDLE hgs,
FHANDLE *hpatterns,
INT pattern_num,
FHANDLE himage,
BOX_T search_window,
INT threshold_mid,
INT threshold_final,
INT edge_detect,
INT reverse_mode,
INT pitch_x,
INT pitch_y,
INT first_unit,
INT last_unit,
enum f_gs2_subpxl_neib subpxl_neib,
INT max_result_num,
SMP_RESULT_MULTI *result,
INT *result_num,
FMATRIX **result_comp_mat
)
{
INT ret = F_ERR_UNKNOWN;
F_GS_RESULT *result_buff = NULL;
FHANDLE hvary = NULL;
ret = F_ERR_INVALID_PARAM;
if( NULL == result || NULL == hpatterns ) goto EXIT;
if( NULL != (*result_comp_mat) ) goto EXIT;
if( pitch_x < 0 || pitch_y < 0 ) goto EXIT;
ret = F_ERR_NOMEMORY;
result_buff = (F_GS_RESULT*)fnOAL_calloc( max_result_num, sizeof(F_GS_RESULT) );
if( NULL == result_buff ) goto EXIT;
hvary = fnFIE_vectarray_alloc( (enum f_objtag)0, sizeof(SMP_RESULT_MULTI), 0 );
if( NULL == hvary ) goto EXIT;
if( pitch_x == 0 || pitch_y == 0 )
{
ret = fnSMP_pitch_calc( hpatterns, pattern_num, &pitch_x, &pitch_y );
if( F_ERR_NONE != ret ) goto EXIT;
}
ret = F_ERR_UNKNOWN;
{
INT i;
FHANDLE himage_buff = himage;
for( i = 0; i < pattern_num; i++ )
{
ret = fnFIE_gs2_search_enforce2(
hgs,
hpatterns[i],
himage_buff,
search_window,
threshold_mid, threshold_final,
edge_detect,
reverse_mode,
pitch_x, pitch_y,
first_unit,
last_unit,
subpxl_neib,
result_buff,
max_result_num,
result_num
);
if( F_ERR_NONE != ret ) goto EXIT;
ret = fnSMP_result_add( result_buff, hvary, *result_num, i );
if( F_ERR_NONE != ret ) goto EXIT;
himage_buff = NULL;
}
ret = fnSMP_sort_result( hvary, result, max_result_num, result_num );
if( ret != F_ERR_NONE ) goto EXIT;
*result_comp_mat = fnFIE_mat_aalloc( *result_num, *result_num );
if( NULL == (*result_comp_mat) )
return F_ERR_NOMEMORY;
ret = fnSMP_result_comp_matrix( result, *result_comp_mat, *result_num, pitch_x, pitch_y );
if( F_ERR_NONE != ret ) goto EXIT;
}
EXIT:
fnOAL_free( result_buff );
fnFIE_vectarray_free( hvary );
return ret;
}
static INT fnSMP_alloc_patterns( CHAR **filenames, PNT_T *mark_offset, FHANDLE *hmasks, INT pattern_num, FHANDLE **hpatterns )
{
INT ret = F_ERR_UNKNOWN;
enum f_comp_filter comp_filter = F_COMP_MODE_SMOOTH;
FHANDLE *hpat_buff = NULL;
FHANDLE himg = NULL;
ret = F_ERR_INVALID_PARAM;
if( NULL == hpatterns || NULL != (*hpatterns) ) goto EXIT;
ret = F_ERR_NOMEMORY;
hpat_buff = (FHANDLE*)fnOAL_calloc( pattern_num, sizeof(FHANDLE) );
if( NULL == hpat_buff ) goto EXIT;
{
INT i;
for( i = 0; i < pattern_num; i++ )
{
ret = fnFIE_load_img_file( filenames[i], &himg, F_COLOR_IMG_TYPE_UC8 );
if( F_ERR_NONE != ret ) goto EXIT;
hpat_buff[i] = fnFIE_gs2_pattern_alloc( himg, hmasks[i], mark_offset[i].x, mark_offset[i].y, comp_filter, &ret );
if( F_ERR_NONE != ret ) goto EXIT;
}
}
EXIT:
if( F_ERR_NONE == ret )
*hpatterns = hpat_buff;
else
fnSMP_free_patterns( hpat_buff, pattern_num );
fnFIE_free_object( himg );
return ret;
}
static VOID fnSMP_free_patterns( FHANDLE *hpatterns, INT pattern_num )
{
INT i;
if( NULL == hpatterns ) return;
for( i =0; i < pattern_num; i++ )
{
fnFIE_free_object( hpatterns[i] );
}
fnOAL_free( hpatterns );
return;
}
static INT FVALGAPI fnSMP_comp_ex( VOID *search_result, const VOID *p_index1, const VOID *p_index2 )
{
SMP_RESULT_MULTI *result = (SMP_RESULT_MULTI*)search_result;
INT index1 = *(INT*)p_index1;
INT index2 = *(INT*)p_index2;
SMP_RESULT_MULTI *result1 = result + index1;
SMP_RESULT_MULTI *result2 = result + index2;
if( result1->score < result2->score )
return 1;
else if( result1->score > result2->score )
return -1;
else
return 0;
}
static INT fnSMP_sort_result(
FHANDLE hvarray,
SMP_RESULT_MULTI *result,
INT max_result_num, INT *result_num
)
{
INT ret = F_ERR_UNKNOWN;
SMP_RESULT_MULTI *p_hvarray = NULL;
INT ary_size;
INT *sort_indexes = NULL;
ret = F_ERR_INVALID_PARAM;
if( NULL == result ) goto EXIT;
ary_size = fnFIE_vectarray_getnum( hvarray );
ret = F_ERR_NOMEMORY;
sort_indexes = (INT*)fnOAL_malloc( sizeof(INT) * ary_size );
if( NULL == sort_indexes ) goto EXIT;
{
INT i;
for( i = 0; i < ary_size; i++ )
{
sort_indexes[i] = i;
}
}
p_hvarray = (SMP_RESULT_MULTI*)fnFIE_vectarray_getptr( hvarray );
fnFIE_qsort_ex( sort_indexes, ary_size, sizeof(INT), fnSMP_comp_ex, (SMP_RESULT_MULTI*)p_hvarray );
{
INT i;
if( max_result_num < ary_size )
ary_size = max_result_num;
for( i = 0; i < ary_size; i++ )
{
SMP_RESULT_MULTI result_buff = *( ( SMP_RESULT_MULTI* )fnFIE_vectarray_getat( hvarray, sort_indexes[i] ) );
result[i].score = result_buff.score;
result[i].x = result_buff.x;
result[i].y = result_buff.y;
result[i].pattern_id = result_buff.pattern_id;
}
*result_num = ary_size;
}
ret = F_ERR_NONE;
EXIT:
fnOAL_free( sort_indexes );
return ret;
}
static INT fnSMP_result_add( F_GS_RESULT *result, FHANDLE hvarray, INT result_num, INT pattern_id )
{
INT ret = F_ERR_UNKNOWN;
SMP_RESULT_MULTI result_buff;
INT i;
if( NULL == result || NULL == hvarray )
return F_ERR_INVALID_PARAM;
if( result_num < 0 )
return F_ERR_INVALID_PARAM;
for( i = 0; i < result_num; i++ )
{
result_buff.score = result[i].score;
result_buff.x = result[i].x;
result_buff.y = result[i].y;
result_buff.pattern_id = pattern_id;
ret = fnFIE_vectarray_push_back( hvarray, &result_buff );
if( F_ERR_NONE != ret ) return ret;
}
return F_ERR_NONE;
}
static INT fnSMP_result_comp_matrix( SMP_RESULT_MULTI *result, FMATRIX *result_comp_mat, INT result_num, INT pitch_x, INT pitch_y )
{
INT ret = F_ERR_UNKNOWN;
INT i, j;
ret = F_ERR_INVALID_PARAM;
if( pitch_x < 0 || pitch_y < 0 )
return ret;
if( result_num > result_comp_mat->col || result_num > result_comp_mat->row )
return ret;
pitch_x *= 100;
pitch_y *= 100;
for( i = 0; i < result_num; i++ )
{
SMP_RESULT_MULTI result_row = result[i];
INT score_row = result_row.score;
INT x= result_row.x;
INT y= result_row.y;
INT id_row = result_row.pattern_id;
for( j = 0; j < result_num; j++ )
{
SMP_RESULT_MULTI result_col = result[j];
INT score_col = result_col.score;
INT dx = abs( result_col.x - x );
INT dy = abs( result_col.y - y );
INT id_col = result_col.pattern_id;
if( ( dx < pitch_x ) && ( dy < pitch_y ) )
{
DOUBLE comp = (DOUBLE)score_col / (DOUBLE)score_row;
result_comp_mat->m[i][j] = comp;
}
else
result_comp_mat->m[i][j] = 0;
}
}
return F_ERR_NONE;
}
static INT fnSMP_pitch_calc( FHANDLE *hpatterns, INT pattern_num, INT *pitch_x, INT *pitch_y )
{
INT ret = F_ERR_UNKNOWN;
DOUBLE x = 0.0;
DOUBLE y = 0.0;
INT i;
FHANDLE pat_img = NULL;
for( i = 0; i < pattern_num; i++ )
{
ret = fnFIE_gs2_pattern_get_image( hpatterns[i], &pat_img );
if( F_ERR_NONE != ret ) goto EXIT;;
x += fnFIE_img_get_width( pat_img );
y += fnFIE_img_get_height( pat_img );
fnFIE_free_object( pat_img ); pat_img = NULL;
}
if( pitch_x == 0 )
*pitch_x = ( fnFIE_d4i5( x / (DOUBLE)pattern_num ) / 2 );
if( pitch_y == 0 )
*pitch_y = ( fnFIE_d4i5( y / (DOUBLE)pattern_num ) / 2 );
EXIT:
fnFIE_free_object( pat_img );
return ret;
}
static INT execute()
{
INT ret = F_ERR_UNKNOWN;
FHANDLE hgs = NULL;
FHANDLE himage = NULL;
FHANDLE *hpatterns = NULL;
INT pattern_num = PATTERN_NUM;
BOX_T search_window;
INT threshold_mid = 3500;
INT threshold_final = 4000;
INT edge_detect = TRUE;
INT reverse_mode = FALSE;
INT pitch_x = 0;
INT pitch_y = 0;
INT first_unit = 5;
INT last_unit = 0;
enum f_gs2_subpxl_neib subpxl_neib = F_GS2_SUBPXL_NEIB_4;
INT max_result_num = 100;
SMP_RESULT_MULTI *result = NULL;
INT result_num;
FMATRIX *result_comp_mat = NULL;
CHAR *filename[]=
{
"pattern_0.png",
"pattern_1.png",
"pattern_2.png",
"pattern_3.png"
};
PNT_T mark_offset[] =
{
0, 0,
0, 0,
0, 0,
0, 0
};
FHANDLE hmasks[] =
{
NULL,
NULL,
NULL,
NULL
};
ret = fnFIE_load_img_file( "gray_search_multi.png", &himage, F_COLOR_IMG_TYPE_UC8 );
if( F_ERR_NONE != ret ) goto EXIT;
ret = fnSMP_alloc_patterns( filename, mark_offset, hmasks,pattern_num, &hpatterns );
if( F_ERR_NONE != ret ) goto EXIT;
hgs = fnFIE_gs2_alloc( 0, 0, 0 );
search_window.st.x = 0;
search_window.st.y = 0;
search_window.ed.x = fnFIE_img_get_width( himage )-1;
search_window.ed.y = fnFIE_img_get_height( himage )-1;
ret = F_ERR_NOMEMORY;
result = (SMP_RESULT_MULTI*)fnOAL_calloc( max_result_num, sizeof(SMP_RESULT_MULTI) );
if( NULL == result ) goto EXIT;
ret = fnSMP_gray_search_multipattern_mat(
hgs,
hpatterns,
pattern_num,
himage,
search_window,
threshold_mid,
threshold_final,
edge_detect,
reverse_mode,
pitch_x,
pitch_y,
first_unit,
last_unit,
subpxl_neib,
max_result_num,
result,
&result_num,
&result_comp_mat
);
if( F_ERR_NONE != ret ) goto EXIT;
PRINT_RESULT( result, result_num, result_comp_mat );
EXIT:
fnSMP_free_patterns( hpatterns, pattern_num );
fnFIE_free_object( himage );
fnFIE_free_object( hgs );
fnOAL_free( result );
fnFIE_mat_afree( result_comp_mat );
{
INT i;
for( i = 0; i < pattern_num; i++)
{
fnFIE_free_object( hmasks[i] );
}
}
return ret;
}
INT main( )
{
INT ret = F_ERR_UNKNOWN;
fnFIE_setup();
ret = execute();
fnFIE_teardown();
return ret;
}