📄 segmenterms.cpp
字号:
memcpy(temp_rem,gen_remain,sizeof(int)*temp_contor);
n_remain=0;
for(i=0;i<temp_contor;i++)
if(!my_class[temp_rem[i]])
gen_remain[n_remain++]=temp_rem[i];
delete [] temp_rem;
memset(_col_remain,0,sizeof(int)*_n_col_remain);
memset(_m_col_remain,0,sizeof(int)*_n_colors);
_n_col_remain=0;
for(i=0;i<n_remain;i++)
_m_col_remain[_col_index[gen_remain[i]]]++;
for(i=0;i<_n_colors;i++)
if(_m_col_remain[i])
{
_col_remain[_n_col_remain]=i;
_n_col_remain++;
}
}
// if more than "how_many" neighbors, consider the point
void SegmenterMS::test_neigh(Octet* my_class, int *selected, int* my_contor, int how_many)
{
register int i,j,p,k;
register Octet* local_class=my_class;
register int temp_contor=*my_contor;
register int my_index;
if(auto_segm) my_index=n_remain;
else my_index=_ro_col;
for ( p = 0, i; p < my_index; p++ )
{
if(auto_segm) i=gen_remain[p];
else i=p;
if(!local_class[i])
{
int neigh_contor=0, no_neigh=1;
for(j=0;j<8;j++)
{
k=i+my_neigh[j];
if(k>=0 && k<_ro_col && local_class[k])
{
if(auto_segm && gen_class[k]!=255) continue;
neigh_contor++;
if(neigh_contor>how_many)
{
no_neigh=0;
break;
}
}
}
if(!no_neigh)
{
if(auto_segm) selected[*my_contor]=i;
*my_contor=*my_contor+1;
}
}
}
for(i=temp_contor;i<*my_contor;i++)
local_class[selected[i]]=1;
}
// Find the feature vectors inside the given window
// Use Improved Absolute Error Inequality Criterion
// when computing Euclidean distance
// See J.S.Pan el al, Fast Clustering Alg. for VQ, Pattern Recognition,
// Vol. 29, No. 3, pp. 511-518, 1996
void SegmenterMS::new_auto_loop(float *final_T, Octet *sel_col)
{
float L,U,V,RAD2,R;
register int TT0=0, TT1=0, TT2=0;
register int local_contor=0;
float final_T0=final_T[0]
, final_T1=final_T[1]
, final_T2=final_T[2];
float RADIUS_S2=(float) ( SQRT2*RADIUS )
, RADIUS_S3=(float) ( SQRT3*RADIUS );
for ( register int p=0, k; p<_n_col_remain; p++ )
{
k = _col_remain[p];
L = _col0[k]-final_T0; if((L=my_abs(L))>=RADIUS) continue;
U = _col1[k]-final_T1; if((R=my_abs(U)+L)>=RADIUS_S2) continue;
V = _col2[k]-final_T2; if(R+my_abs(V)>=RADIUS_S3) continue;
RAD2 = L*L+U*U+V*V;
if ( RAD2<RADIUS2 )
{
register int r = _m_col_remain[k];
TT0 += _col0[k]*r;
TT1 += _col1[k]*r;
TT2 += _col2[k]*r;
local_contor += r;
sel_col[k] = 1;
}
}
final_T[0]=(float)TT0/(float)local_contor;
final_T[1]=(float)TT1/(float)local_contor;
final_T[2]=(float)TT2/(float)local_contor;
}
// The same as above, but for non auto_segmentation
void SegmenterMS::nauto_loop(float *final_T, int *selected,
Octet *my_class, int *my_contor)
{
float L,U,V,RAD2,R;
register int local_contor=*my_contor;
float final_T0=final_T[0], final_T1=final_T[1], final_T2=final_T[2];
float RADIUS_S2=(float) ( SQRT2*RADIUS ), RADIUS_S3=(float) ( SQRT3*RADIUS );
for ( register int k = 0; k < _n_points; k++ )
{
L=_data[0][k]-final_T0; if((L=my_abs(L))>=RADIUS) continue;
U=_data[1][k]-final_T1; if((R=my_abs(U)+L)>=RADIUS_S2) continue;
V=_data[2][k]-final_T2; if(R+my_abs(V)>=RADIUS_S3) continue;
RAD2=L*L+U*U+V*V;
if(RAD2<RADIUS2)
{
selected[local_contor++]=k;
my_class[k]=1;
}
}
*my_contor=local_contor;
}
// Set the Radius of the window
void SegmenterMS::set_RADIUS(int gen_gen_contor, int final)
{
if(final==2) RADIUS=(float) ( final_RADIUS*1.26 );
else if(final==1) RADIUS=final_RADIUS;
else RADIUS=fix_RADIUS[gen_gen_contor];
RADIUS2=RADIUS*RADIUS;
}
// Test if the clusters have the same mean
int SegmenterMS::test_same_cluster(int rect, float T[][p_max])
{
float L,U,V,RAD2;
for(register int k=0; k<rect;k++)
{
L=T[k][0]-T[rect][0]; U=T[k][1]-T[rect][1]; V=T[k][2]-T[rect][2];
RAD2=L*L+U*U+V*V;
if(RAD2<1)
return 1;
}
return 0;
}
// First take only pixels inside the search windows at their final locations
// Then inflate windows to double volume and retain only pixels which are
// neighbors with the previous
void SegmenterMS::get_codeblock1(float T[][p_max], int n_rects)
{
float L,U,V,RAD2;//, R, by dzj;
float min_RAD2;
int min_ind;
register int i,k,u;
register int pres_class;//, my_flag;by dzj;
register float *ptr;
if(auto_segm) set_RADIUS(0,0);
else set_RADIUS(2,0);
for(k=0;k<_ro_col;k++)
{
min_RAD2=BIG_NUM; min_ind=0;
for(i=0;i<n_rects;i++)
{
ptr=T[i];
L=_data0[k]-ptr[0]; if(my_abs(L)>=RADIUS) continue;
U=_data1[k]-ptr[1]; if(my_abs(U)>=RADIUS) continue;
V=_data2[k]-ptr[2]; if(my_abs(V)>=RADIUS) continue;
RAD2=L*L+U*U+V*V;
if(RAD2<min_RAD2)
{
min_RAD2=RAD2;
min_ind=i;
}
}
if(min_RAD2<RADIUS2) gen_class[k]=min_ind;
else gen_class[k]=n_rects;
}
if(auto_segm) set_RADIUS(0,1);
else set_RADIUS(0,0);
for(k=0;k<_ro_col;k++)
if(gen_class[k]==n_rects)
for(i=0;i<8;i++)
{
u=k+my_neigh[i];
if(u>=0 && u<_ro_col)
if((pres_class=gen_class[u])!=n_rects)
{
ptr=T[pres_class];
L=_data0[k]-ptr[0]; if(my_abs(L)>=RADIUS) continue;
U=_data1[k]-ptr[1]; if(my_abs(U)>=RADIUS) continue;
V=_data2[k]-ptr[2]; if(my_abs(V)>=RADIUS) continue;
RAD2=L*L+U*U+V*V;
if(RAD2<RADIUS2) gen_class[k]=pres_class;
}
}
}
// Final allocation
void SegmenterMS::get_codeblock(float T[][p_max], int n_rects)
{
float L,U,V,RAD2, min_RAD2;
register int min_ind;
register int i,k;
register float *ptr;
for(k=0;k<_ro_col;k++)
{
min_RAD2=BIG_NUM;
min_ind=0;
for(i=0;i<n_rects;i++)
{
ptr=T[i];
L=_data0[k]-ptr[0]; U=_data1[k]-ptr[1]; V=_data2[k]-ptr[2];
RAD2=L*L+U*U+V*V;
if(RAD2<min_RAD2)
{
min_RAD2=RAD2;
min_ind=i;
}
}
gen_class[k]=min_ind;
}
}
// Compute the mean of feature vectors mapped into the same color
void SegmenterMS::new_codebook(float T[][p_max], int n_rects)
{
register int i,k;
register int *tab_contor = new int[n_rects];
register int prez_class;
register float *ptr;
memset(tab_contor,0,sizeof(int)*n_rects);
for(i=0;i<n_rects;i++)
{
T[i][0]=0.0; T[i][1]=0.0; T[i][2]=0.0;
}
for(k=0;k<_ro_col;k++)
if((prez_class=gen_class[k])!=n_rects)
{
ptr=T[prez_class];
ptr[0]+=_data0[k]; ptr[1]+=_data1[k]; ptr[2]+=_data2[k];
tab_contor[prez_class]++;
}
for(i=0;i<n_rects;i++)
{
T[i][0]/=tab_contor[i]; T[i][1]/=tab_contor[i]; T[i][2]/=tab_contor[i];
}
delete [] tab_contor;
}
// Determine the final feature palette
void SegmenterMS::optimize(float T[][p_max], int n_rects)
{
get_codeblock1(T, n_rects);
new_codebook(T, n_rects);
if (auto_segm)
{
get_codeblock(T,n_rects);
}
cerr<<":";
}
// Inverse of the mapping array used in color elimination
void SegmenterMS::reverse_map(Octet *inv_map, Octet *my_map, int *n_rects, Octet *valid_class, float T[][p_max])
{
float sec_T[Max_rects][p_max];
register int u=0, k, j;
for(j=0;j<*n_rects;j++)
{
if(valid_class[j])
{
for(k=0;k<3;k++)
sec_T[u][k]=T[j][k];
my_map[j]=u;
inv_map[u]=j;
u++;
}
}
my_map[*n_rects]=u;
inv_map[u]=*n_rects;
*n_rects=u;
for(j=0;j<*n_rects;j++)
for(k=0;k<3;k++)
T[j][k]=sec_T[j][k];
}
// Eliminate colors that have less than "my_lim" connected pixels
void SegmenterMS::eliminate_class(Octet *my_class,int *my_max_region, int *n_rects,int my_lim, Octet* inv_map, float T[][p_max], REGION *first_region)
{
register int j, k;
register Octet *valid_class;
register REGION *current_region=first_region;
valid_class=new Octet[*n_rects];
for(j=0;j<*n_rects;j++)
{
if(my_max_region[j]<my_lim) valid_class[j]=0;
else valid_class[j]=1;
}
while(1)
{
if((current_region->my_class<*n_rects &&
!valid_class[current_region->my_class]))
for(k=0;k<current_region->my_contor;k++)
gen_class[current_region->my_region[k]]=*n_rects;
if(current_region->next_region_str)
current_region=current_region->next_region_str;
else break;
}
Octet my_map[Max_rects];
reverse_map(inv_map,my_map,n_rects,valid_class,T);
for(k=0;k<_ro_col;k++)
my_class[k]=my_map[gen_class[k]];
delete [] valid_class;
memcpy(gen_class,my_class,_ro_col);
}
// Eliminate regions with less than "my_lim" pixels
void SegmenterMS::eliminate_region(int *n_rects,int my_lim, float T[][p_max], REGION* first_region)
{
register int j,u,k,p, pres_class, min_ind;
register REGION *current_region=first_region;
register int* region;
float *ptr;
float L,U,V,RAD2,minRAD2;
int increm;
while(1)
{
if(current_region->my_contor<my_lim)
{
set_RADIUS(0,0); increm=4;
region=current_region->my_region;
for(k=0;k<current_region->my_contor;k++)
gen_class[region[k]]=*n_rects;
while(1)
{
Boolean my_flag=0;
RADIUS+=increm; RADIUS2=RADIUS*RADIUS; increm+=4;
for(k=0;k<current_region->my_contor;k++)
if(gen_class[p=region[k]]==(*n_rects))
{
minRAD2=RADIUS2;
for(j=1;j<8;j+=2)
{
u=p+my_neigh[j];
if(u>=0 && u<_ro_col)
if((pres_class=gen_class[u])!=(*n_rects))
{
ptr=T[pres_class];
L=_data0[p]-ptr[0]; U=_data1[p]-ptr[1];
V=_data2[p]-ptr[2]; RAD2=L*L+U*U+V*V;
if(RAD2<minRAD2)
{
minRAD2=RAD2; min_ind=pres_class;
}
}
}
if(minRAD2<RADIUS2) gen_class[p]=min_ind;
my_flag=1;
}
if(!my_flag) break;
}
}
if(current_region->next_region_str)
current_region=current_region->next_region_str;
else break;
}
}
// Destroy the region list
void SegmenterMS::destroy_region_list(REGION *first_region)
{
register REGION *current_region=first_region;
while(1)
{
delete [] current_region->my_region;
first_region=current_region;
if(current_region->next_region_str)
{
current_region=current_region->next_region_str;
delete first_region;
}
else
{
delete first_region;
break;
}
}
}
// Connected component main routine
void SegmenterMS::find_other_neigh(int k, int *my_ptr_tab, REGION *current_region)
{
register int *ptr_tab=my_ptr_tab;
register int i,u, j=k, sec_signal;
register int contor=0;
register int region_contor=current_region->my_contor;
register int region_class=current_region->my_class;
ptr_tab[contor]=j;
while(1)
{
sec_signal=0;
for(i=1;i<9;i+=2)
{
u=j+my_neigh[i];
if(u>=0 && u<_ro_col)
if(gen_class[u]==region_class && !taken[u])
{
sec_signal=1;
conn_selected[region_contor++]=u;
taken[u]=1;
ptr_tab[++contor]=u;
}
}
if(sec_signal) j=ptr_tab[contor];
else
{
if(contor>1) j=ptr_tab[--contor];
else break;
}
}
current_region->my_contor=region_contor;
}
// Create the region list
REGION *SegmenterMS::create_region_list(int *my_max_region, int change_type)
{
register int k, local_label=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -