使用边界法进行分割得到分割图后,需要对没有赋label的边界进行赋值,本文使用的是基于二维的邻域搜索进行赋值,在二维分割图中找到离当前边界点最近的具有
label值的像素,然后将其label赋给当前边界点。
cv::Mat labelMat(cv::Size(640,480),CV_8UC1,cv::Scalar(0));
for(int i=0;i<480;i++)
{
for(int j=0;j<640;j++)
{
labelMat.at<uchar>(i,j)=labelColor[640*i+j];
}
}
labelColor为我的分割结果,以数组的形式存放,放到opencv的Mat中,这样后续处理简单点。
以下为完整代码,思路很简单,先设定搜索半径r,然后以边界点为中心,发散寻找最近的有效label
cv::Mat labelMat(cv::Size(640,480),CV_8UC1,cv::Scalar(0));
for(int i=0;i<480;i++)
{
for(int j=0;j<640;j++)
{
labelMat.at<uchar>(i,j)=labelColor[640*i+j];
}
}
cv::imshow("aaa",labelMat);
int r=4;
for(int i=0;i<480;i++)
{
for(int j=0;j<640;j++)
{
int label_temp=labelMat.at<uchar>(i,j);
if(label_temp==0) //等于0说明是没有赋值的边界点
{
for(int k=1;k<=r;k++)
{
int start,end;
bool leave=false;
//(i-k,j-k) -> (i-k,j+k)
if(i-k>0)
{
start=(j-k>=0)?j-k:0; //行的取值范围为0-479,列为0-639
end=(j+k<=639)?j+k:639;
for(int temp=start;temp<=end;temp++)
{
int aa=labelMat.at<uchar>(i-k,temp);
if(aa>0)
{
labelMat.at<uchar>(i,j)=aa;
labelColor[640*i+j]=aa;
leave=true;
break;
}
}
}
//(i-k,j-k) -> (i+k,j-k)
if(j-k>0)
{
start=(i-k>=0)?i-k:0;
end=(i+k<=479)?i+k:479;
for(int temp=start;temp<=end;temp++)
{
int aa=labelMat.at<uchar>(temp,j-k);
if(aa>0)
{
labelMat.at<uchar>(i,j)=aa;
labelColor[640*i+j]=aa;
leave=true;
break;
}
}
}
//(i-k,j+k) -> (i+k,j+k)
if(j+k<640)
{
start=(i-k>=0)?i-k:0;
end=(i+k<=479)?i+k:479;
for(int temp=start;temp<=end;temp++)
{
int aa=labelMat.at<uchar>(temp,j+k);
if(aa>0)
{
labelMat.at<uchar>(i,j)=aa;
labelColor[640*i+j]=aa;
leave=true;
break;
}
}
}
//(i+k,j-k) -> (i+k,j+k)
if(i+k<480)
{
start=(j-k>=0)?j-k:0;
end=(j+k<=639)?j+k:639;
for(int temp=start;temp<=end;temp++)
{
int aa=labelMat.at<uchar>(i+k,temp);
if(aa>0)
{
labelMat.at<uchar>(i,j)=aa;
labelColor[640*i+j]=aa;
leave=true;
break;
}
}
}
if(leave)
{break;}
}
}
}
}
cv::imshow("bbb",labelMat);
cv::waitKey(1);
实际测试时,发现,并不能将这种方法应用于三维,三维分割应该寻找距离当前边界点 欧氏距离最近的有效label,进行赋值,所以后续该考虑以什么规则在三维
上寻找最近的有效值。