对象分割过程中,对没有赋label值的边界使用邻域查找的方式进行标记(2)

来源:互联网 发布:淘宝top100店铺 编辑:程序博客网 时间:2024/06/07 10:49

上一篇文章使用二维上最近的像素点对边界点进行赋值,本文使用的方法为寻找邻域内,与边界点三维距离最近的有效点进行赋值。

依然以边界点为中心,一圈圈发散寻找有效点,只要在内圈找到了有效点,就在该圈内寻找三维距离最近的点,(把leave设置为true)不

再去寻找外圈的最近点(一般内圈点的三维距离都比外圈小),以下为参考代码:

(vertexBuff存放的顶点数据和labelColor一一对应)

    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);
            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)
                    {
                        float cur_vert[3]={vertexBuff.at<Eigen::Vector4f>(i, j)(0),
                                           vertexBuff.at<Eigen::Vector4f>(i, j)(1),
                                           vertexBuff.at<Eigen::Vector4f>(i, j)(2)};  //当前边界点三维坐标
                        float min=10.0;//用于记录最小距离
                        int x=i,y=j;   //用于记录三维距离最近点的二维坐标
                        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;
                                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)
                                    {
                                        //calculate the distance
                                        float neigh_vert[3]={vertexBuff.at<Eigen::Vector4f>(i-k, temp)(0),
                                                             vertexBuff.at<Eigen::Vector4f>(i-k, temp)(1),
                                                             vertexBuff.at<Eigen::Vector4f>(i-k, temp)(2)};
                                        float dis=(neigh_vert[0]-cur_vert[0])*(neigh_vert[0]-cur_vert[0])+
                                                  (neigh_vert[1]-cur_vert[1])*(neigh_vert[1]-cur_vert[1])+
                                                  (neigh_vert[2]-cur_vert[2])*(neigh_vert[2]-cur_vert[2]);
                                        if(dis<min)
                                        {
                                            min=dis;
                                            x=i-k;
                                            y=temp;          //记录下min和位置
                                            leave=true;      //检测到有效值,在获取当前循环最近点坐标后,即可进行赋值操作
                                        }
                                    }
                                }
                            }
                            //(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)
                                    {
                                        float neigh_vert[3]={vertexBuff.at<Eigen::Vector4f>(temp,j-k)(0),
                                                             vertexBuff.at<Eigen::Vector4f>(temp,j-k)(1),
                                                             vertexBuff.at<Eigen::Vector4f>(temp,j-k)(2)};
                                        float dis=(neigh_vert[0]-cur_vert[0])*(neigh_vert[0]-cur_vert[0])+
                                                  (neigh_vert[1]-cur_vert[1])*(neigh_vert[1]-cur_vert[1])+
                                                  (neigh_vert[2]-cur_vert[2])*(neigh_vert[2]-cur_vert[2]);
                                        if(dis<min)
                                        {
                                            min=dis;
                                            x=temp;
                                            y=j-k;          //记录下min和位置
                                            leave=true;
                                        }
                                    }
                                }
                            }
                            //(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)
                                    {
                                        float neigh_vert[3]={vertexBuff.at<Eigen::Vector4f>(temp,j+k)(0),
                                                             vertexBuff.at<Eigen::Vector4f>(temp,j+k)(1),
                                                             vertexBuff.at<Eigen::Vector4f>(temp,j+k)(2)};
                                        float dis=(neigh_vert[0]-cur_vert[0])*(neigh_vert[0]-cur_vert[0])+
                                                  (neigh_vert[1]-cur_vert[1])*(neigh_vert[1]-cur_vert[1])+
                                                  (neigh_vert[2]-cur_vert[2])*(neigh_vert[2]-cur_vert[2]);
                                        if(dis<min)
                                        {
                                            min=dis;
                                            x=temp;
                                            y=j+k;          //记录下min和位置
                                            leave=true;
                                        }
                                    }
                                }
                            }
                            //(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)
                                    {
                                        float neigh_vert[3]={vertexBuff.at<Eigen::Vector4f>(i+k, temp)(0),
                                                             vertexBuff.at<Eigen::Vector4f>(i+k, temp)(1),
                                                             vertexBuff.at<Eigen::Vector4f>(i+k, temp)(2)};
                                        float dis=(neigh_vert[0]-cur_vert[0])*(neigh_vert[0]-cur_vert[0])+
                                                  (neigh_vert[1]-cur_vert[1])*(neigh_vert[1]-cur_vert[1])+
                                                  (neigh_vert[2]-cur_vert[2])*(neigh_vert[2]-cur_vert[2]);
                                        if(dis<min)
                                        {
                                            min=dis;
                                            x=i+k;
                                            y=temp;          //记录下min和位置
                                            leave=true;
                                        }
                                    }
                                }
                            }
                            if(leave)
                            {
                                labelColor[640*i+j]=labelMat.at<uchar>(x,y);
                                break;
                            }
                        }
                    }
                }
            }
            cv::imshow("bbb",labelMat);
            cv::waitKey(1);


下图是二维最近和三维最近的两张结果图,第一张是基于二维的,第二张是基于三维距离的




可以看出,基于三维距离的赋值方法,稍优于二维的效果,但是因为其他原因,分割的效果依然不是非常理想的状态。

此项目基于三维法向量的性质进行分割,系统计算出来的法向量图存在较大的噪声,导致分割出来的结果效果很差,后面应该会寻找方案,解决法向量图的滤波问题


阅读全文
0 0
原创粉丝点击