⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 segmenterms.cpp

📁 这是一个分水岭程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	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 + -