I'm trying to create a connected components labeling prototype to use in my graduation project. it works mostly, only it results in using large numbers for labels while skipping the smaller ones.
my code connects similar values from the given array (similarity measured via chi-square), and then there are some threshold to decide how much should the central array value be compared to its 8 neighbors. then, according to that I created a new array "cluster" which sums the value of the central value with its similar neighbor and divide by 2. then according to that, all similar values must be labeled.
as you can see, there are 4 objects, only the highest number us 26 not 4. so how can I fix this issue?
#include<iostream>
#include<math.h>
#include "timer.h"
#include <openacc.h>
using namespace std;
int main()
{
#if _OPENACC
acc_init(acc_device_nvidia);
#endif
double array[8][8]=
{
{33,30,30,0,28,27,25,22}
,{32,30,29,0,26,25,23,21}
,{31,29,28,0,27,24,22,20}
,{30,28,27,0,25,23,20,19}
,{30,27,25,0,24,22,18,15}
,{27,25,21,0,22,4,16,13}
,{25,23,22,0,20,25,17,12}
,{24,23,22,0,19,17,15,11}
} ;
int height = 8;
int width = 8;
double cc[9][9];
double top_right[9][9]= {};
double thresh_array[9][9]= {};
double top[9][9]= {};
double top_left[9][9]= {};
double left[9][9]= {};
double center[9][9]= {};
double right[9][9]= {};
double bot_right[9][9]= {};
double bot[9][9]= {};
double bot_left[9][9]= {};
int label [9][9] = {} ;
double cluster[9][9] = {};
double cluster_v;
// Dis-Similarity Check via Chi-Square equation to find the similarity between central pixel and 8-neighbors
// i+2 so it would only compare central pixels with its neighbors,to reduce the calculations needed
for (int i=1; i<8; i+=2)
{
for (int j=0; j <( width); j++)
{
if (array[i][j]!= 0)
{
top_left[i-1][j] = ( (pow((array[i][j] - array[i-1][j-1]),2.0)) / (array[i][j] + array[i-1][j-1]) );
top[i-1][j] = ( (pow((array[i][j]-array[i-1][j]),2.0)) / (array[i][j] + array[i-1][j]) );
top_right[i-1][j] = ( (pow((array[i][j]- array[i-1][j+1]),2.0)) / (array[i][j] + array [i-1][j+1]) );
left[i-1][j] = ( (pow((array[i][j]-array[i][j-1]),2.0)) / (array[i][j] + array[i][j-1]) );
right[i-1][j] = ( (pow((array[i][j]-array[i][j+1]),2.0))/(array[i][j] + array[i][j+1]));
bot_left [i-1][j] = ((pow((array[i][j]-array[i+1][j-1]),2.0)) / (array[i][j] + array[i+1][j-1]));
bot [i-1][j] = ( (pow((array[i][j]-array[i+1][j]),2.0))/(array[i][j] + array[i+1][j]));
bot_right [i-1][j] = ( (pow((array[i][j]-array[i+1][j+1]),2.0))/(array[i][j] + array[i+1][j+1]));
}
}
}
double threshold=1000;
// calculating the smallest threshold to construct a new array with only similar neighbors showing
for (int i=1; i<(height); i+=2)
{
for (int j=0; j < (width); j++)
{
threshold = 1000;
(threshold <= top_left[i-1][j])? : threshold = top_left[i-1][j];
(threshold <= top[i-1][j])? : threshold = top[i-1][j];
(threshold <= top_right[i-1][j])? : threshold = top_right[i-1][j];
(threshold <=left[i-1][j])? : threshold = left[i-1][j];
(threshold <= right[i-1][j])? : threshold = right[i-1][j];
(threshold <= bot[i-1][j])? : threshold = bot[i-1][j];
(threshold <= bot_left[i-1][j])? : threshold = bot_left[i-1][j];
(threshold <=bot_right[i-1][j])? : threshold = bot_right[i-1][j];
thresh_array[i-1][j] = threshold;
}
}
// constructing the new array "cluster"
// if the pixels are less that a threshold of 0.016, it is summed with the central pixel and divided by 2
for (int i=1; i<height; i+=2)
{
for (int j=0; j < (width); j++)
{
if ( thresh_array[i-1][j] <0.016 && array[i-1][j] !=0)
{
cluster_v =0;
if(top_left[i-1][j] == thresh_array[i-1][j])
{
cluster_v = ((array[i-1][j-1] + array[i][j])/2);
cluster[i-1][j-1] = cluster_v;
cluster[i][j] = cluster_v;
}
if (top[i-1][j] == thresh_array[i-1][j])
{
cluster_v = ((array[i-1][j] + array[i][j])/2);
cluster[i-1][j] = cluster_v;
cluster[i][j] = cluster_v;
}
if (top_right[i-1][j] == thresh_array[i-1][j])
{
cluster_v = ((array[i-1][j+1] + array[i][j])/2);
cluster[i-1][j+1] = cluster_v;
cluster[i][j] = cluster_v;
}
if (left[i-1][j] == thresh_array[i-1][j])
{
cluster_v = ((array[i][j-1] + array[i][j])/2);
cluster[i][j-1] = cluster_v;
cluster[i][j] = cluster_v;
}
if (right[i-1][j] == thresh_array[i-1][j])
{
cluster_v = ((array[i][j+1] + array[i][j])/2);
cluster[i][j+1] = cluster_v;
cluster[i][j] = cluster_v;
}
if (bot_left[i-1][j] == thresh_array[i-1][j])
{
cluster_v = ((array[i+1][j-1] + array[i][j])/2);
cluster[i+1][j-1] = cluster_v;
cluster[i][j] = cluster_v;
}
if (bot[i-1][j] == thresh_array[i-1][j])
{
cluster_v = ((array[i+1][j] + array[i][j])/2);
cluster[i+1][j] = cluster_v;
cluster[i][j] = cluster_v;
}
if (bot_right[i-1][j] == thresh_array[i-1][j])
{
cluster_v = ((array[i+1][j+1] + array[i][j])/2);
cluster[i+1][j+1] = cluster_v;
cluster[i][j] = cluster_v;
}
}
}
}
// First pass of connected components labeling, checks the current pixel with top and left pixels from the new array
// according to conditions
int x=1, y=0;
for (int i=0; i<height; i++)
{
for(int j=0; j<width; j++)
{
if(cluster[i][j] >0)
{
if(cluster[i-1][j] >0 )
label[i][j] = x;
if (cluster[i-1][j+1] >0)
label[i][j] = x;
if(cluster[i-1][j-1] >0)
label[i][j] = x;
if(cluster [i][j-1] >0)
label[i][j] = x;
if (cluster[i+1][j] >0)
label[i][j] = x;
if(cluster [i][j+1] >0)
label[i][j] = x;
if(cluster [i+1][j+1] >0)
label[i][j] = x;
if(cluster [i+1][j-1] >0)
label[i][j] = x;
x+=1;
}
if(cluster[i][j] ==0)
label[i][j]=0;
cout << cluster[i][j] <<" ";
}
cout << endl;
}
cout << endl;
cout << "First pass" << endl;
for (int i=0; i<8; i++)
{
for (int j=0; j<8; j++)
{
cout << label[i][j] <<" " ;
}
cout << endl;
}
cout << endl;
// second pass of connected components labeling
int z=0;
while (z<(1000))
{
for(int j=0; j<height; j++)
{
for(int i=(width-1); i>=0; i--)
{
if(label[i][j] >0 )
{
if(label[i-1][j] >0 )
label[i][j] = min(label[i][j],label[i-1][j]);
if (label[i-1][j+1] >0)
label[i][j] = min(label[i][j],label[i-1][j+1]);
if(label[i-1][j-1] >0)
label[i][j] = min(label[i][j],label[i-1][j-1]);
if(label [i][j-1] >0)
label[i][j] = min(label[i][j],label[i][j-1]);
if (label[i+1][j] >0)
label[i][j] = min(label[i][j], label[i+1][j]);
if(label [i][j+1] >0)
label[i][j] = min(label[i][j], label[i][j+1]);
if(label [i+1][j+1] >0)
label[i][j] = min(label[i][j], label[i+1][j+1]);
if(label [i+1][j-1] >0)
label[i][j] = min(label[i][j], label[i+1][j-1]);
}
}
}
z+=1;
}
cout << "Second Pass" << endl;
for (int i=0; i<8; i++)
{
for (int j=0; j<8; j++)
{
cout << label[i][j] <<" " ;
}
cout << endl;
}
}
notice, that I loop the second pass to get the best possible result.