python:
'''
find all the linked areas in a binary image(0 or 255),and label all areas.
'''
import numpy as np
def solution(arr:np.array,thresh:int):
stack,used=[],[]
row,col=arr.shape
res_arr=np.zeros((row,col))
count=0
for i in range(row):
for j in range(col):
if [i,j] in used:
continue
if arr[i][j]>thresh:
count+=1
seed=[i,j]
stack.append(seed)
left=right=i
top=bottom=j
while len(stack):
r,c=seed
res_arr[r][c]=count
used.append(seed)
left=c-1
if left>=0 and arr[r][left]>thresh:
res_arr[r][left]=count
arr[r][left]=count
stack.append([r,left])
right=c+1
if right<col and arr[r][right]>thresh:
res_arr[r][right]=count
arr[r][right]=count
stack.append([r,right])
top=r-1
if top>=0 and arr[top][c]>thresh:
res_arr[top][c]=count
arr[top][c]=count
stack.append([top,c])
bottom=r+1
if bottom<row and arr[bottom][c]>thresh:
res_arr[bottom][c]=count
arr[bottom][c]=count
stack.append([bottom,c])
seed=stack[-1]
stack.pop()
return res_arr
#in place algorithm
def solution2(arr,thresh=100):
row,col=arr.shape
res_arr=np.zeros((row,col))
count=0 # count<thresh
stack=[]
for i in range(row):
for j in range(col):
# if [i,j] in stack:continue
if arr[i][j]>thresh:
count+=1
seed=[i,j]
stack.append(seed)
while len(stack):
r,c=seed
arr[r][c]=count
left,right=max(0,c-1),min(c+1,col-1)
top,bottom=max(0,r-1),min(r+1,row-1)
if arr[r][left]>thresh:
arr[r][left]=count
stack.append([r,left])
if arr[r][right]>thresh:
arr[r][right]=count
stack.append([r,right])
if arr[top][c]>thresh:
arr[top][c]=count
stack.append([top,c])
if arr[bottom][c]>thresh:
arr[bottom][c]=count
stack.append([bottom,c])
seed=stack[-1]
stack.pop()
print(arr)
# return arr
if __name__=="__main__":
thresh=100
array=[ [ 0,255,255, 0, 0,255],
[255, 0,255, 0,255,255],
[255,255, 0,255, 0, 0],
[ 0,255,255, 0,255,255]
]
arr=np.array(array)
print(arr)
# print(arr.shape)
res=solution2(arr,thresh)
# print(res)
# print(arr)
cpp:
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
typedef struct Point{
int x,y;
Point(int _x,int _y){
x=_x;y=_y;
}
}Point;
void print_matrix(const vector<vector<int> >& res){
for(auto& it:res){
for(auto& _it:it)
cout<<_it<<" ";
cout<<"\n";
}
}
vector<vector<int> > solution( vector<vector<int> >& array,const int thresh=100){
if(!array.size()) return vector<vector<int> >(0);
const int row=array.size();
const int col=array[0].size();
int count=0;
vector<vector<int> > res(row,vector<int>(col,0));
// print_matrix(res);
stack<Point> my_stack;
vector<Point> used;
Point seed(0,0);
for(int i=0;i<row;++i){
for(int j=0;j<col;++j){
bool flag=false;
for(int k=0;k<used.size();++k){
if(i==used[k].x && j==used[k].y)
flag=true;break;
}
if(flag) continue;
if(array[i][j]>thresh){
count+=1;
res[i][j]=count;
seed.x=i;seed.y=j;
my_stack.push(seed);
while(my_stack.size() ){
int r=seed.x,c=seed.y;
used.push_back(seed);
// cout<<"row="<<row<<",col="<<col<<",r="<<r<<",c="<<c<<",count="<<count<<"\n";
int left=max(0,seed.y-1),right=min(seed.y+1,col-1);
int top=max(0,seed.x-1),bottom=min(seed.x+1,row-1);
// cout<<"left="<<left<<",right="<<right<<",top="<<top<<",bottom="<<bottom<<"\n";
if(array[r][left]>thresh){
res[r][left]=count;
my_stack.push(Point(r,left));
// used.push_back(Point(r,left));
array[r][left]=0;
}
if(array[r][right]>thresh){
res[r][right]=count;
my_stack.push(Point(r,right));
// used.push_back(Point(r,right));
array[r][right]=0;
}
if(array[top][c]>thresh){
array[top][c]=0;
res[top][c]=count;
my_stack.push(Point(top,c));
// used.push_back(Point(c,top));
}
if(array[bottom][c]>thresh){
array[bottom][c]=0;
res[bottom][c]=count;
my_stack.push(Point(bottom,c));
// used.push_back(Point(c,bottom));
}
seed=my_stack.top();
my_stack.pop();
} //while
} // if
}
}
return res;
}
int main(){
int my_array[4][6]={
{ 0,255,255, 0, 0,255},
{255, 0,255, 0,255,255},
{255,255, 0,255, 0, 0},
{ 0,255,255, 0,255,255}
};
vector<vector<int> > array(4,vector<int>(6,0));
for(int i=0;i<4;++i){
for(int j=0;j<6;++j)
array[i][j]=my_array[i][j];
}
for(auto& it:array){
for(auto& _it:it)
cout<<_it<<" ";
cout<<"\n";
}
cout<<"\nres==>\n";
const int thresh=100;
vector<vector<int> > res= solution(array,thresh);
for(auto& it:res){
for(auto& _it:it)
cout<<_it<<" ";
cout<<"\n";
}
return 0;
}