【图像处理】从点云数据中提取边界(识别和追踪)(Matlab代码实现)

 👨‍🎓个人主页:研学社的博客 

💥💥💞💞欢迎来到本博客❤️❤️💥💥

🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。

⛳️座右铭:行百里者,半于九十。

📋📋📋本文目录如下:🎁🎁🎁

目录

💥1 概述

📚2 运行结果

🎉3 参考文献

🌈4 Matlab代码、数据、文章讲解


【图像处理】从点云数据中提取边界(识别和追踪)(Matlab代码实现)

💥1 概述

从建筑的点集中生成直线建筑轮廓通常分为三个步骤。首先确定构成建筑轮廓的边界。然后从边缘开始跟踪一系列点来定义建筑边界。最后,从点的序列中生成线条,并进行调整以形成规则的建筑轮廓。现有的解决方案在以下一种或多种情况下存在缺陷:沿凹形状识别细节,单独识别形状内的“洞”,适当的边界跟踪,以及沿正则化建筑轮廓保存详细信息。本文针对这三个步骤提出了新的解决方案。通过使用输入数据中的最大点对点距离,识别步骤的解决方案正确地检测任何类型形状的边界边缘,并单独识别形状内部的孔(如果有的话)。所提出的跟踪算法将边界边划分为段,准确获取每个段的点序列,并在必要时将它们合并,以生成每个形状的单一边界。正则化步骤提出了一种改进的角线提取算法,并根据自动确定的建筑物主方向对提取的线进行调整。为了评价其性能,还提出了一种将提取的建筑轮廓线与参考轮廓线进行角对应的评价系统。实验结果表明,即使在低密度输入数据中,所提出的解决方案也能保持建筑边界的细节,并提供较高的基于像素的完整性和几何精度。

1) 从输入点集中分别提取(识别和跟踪)外部边界和内部边界,

2) 处理任何类型的输入点集,

3) 从大型和/或密集点集的每个子集中单独提取边界。可以分割原始输入点集(用户定义如何分割),然后可以从组合的子集边界中提取(内部和外部)边界。这大大降低了大型和/或密集点集的计算成本。

这些算法还能够在单个输入数据集中为多个对象提取多个边界。在这种情况下,两个对象之间的距离应至少是输入点云中最大点对点距离的 2 倍。

详细文章见第4部分。

📚2 运行结果

【图像处理】从点云数据中提取边界(识别和追踪)(Matlab代码实现)

部分代码:

function [bndry bndryin] = delaunay_boundary02_fig(X,Fd,Plns)

[bndry E Ne] = find_delaunay_boundary03(X,Fd);

%Fd = Fd-0.2;

aThresh = 22.5/2; %standard 45 degree

dFd = 2*Fd;

msd = dFd*dFd;

msd1 = Fd*Fd;

(Ner(j,k) > 1 || Ner(k,j) > 1)) ||…

                                    (chk2(1,1) == 0 && chk2(2,1) == 0 && (Ner(j,k) > 0 || Ner(k,j) > 0)))%if (j,k) is from the same plane j,k should not be the consecutive points along plane boundary

                                if j < k

                                    Ner(j,k) = Ner(j,k)-1;

                                    Q = [Q; [j k chk2(2,1)]];                                

                                else

                                    Ner(k,j) = Ner(k,j)-1;

                                    Q = [Q; [k j chk2(2,1)]];

                                end

                                %plot([X(j,1) X(k,1)], [X(j,2) X(k,2)],’-b’); hold on; 

                                if Ner(j,k) == 0 && Ner(k,j) == 0

                                    here = 1;

her vertics with edge (i,j)

                    for v = 1:size(vs,2)

                        here = 1;

                        k = vs(1,v);                          

                        %for edge (i,k)

                        %check if (i,k) is already in Q

                        chk2 = checkEdgeInGaps03(X,i,k,Plns); %check if the edge (i,k) is within a gap in between two planes

                        %if chk2 == 1

                        fik = 0;

                        if size(Q,1)>0

                            if sum(Q(:,1) == i & Q(:,2) == k) == 1 || sum(Q(:,1) == k & Q(:,2) == i) == 1

                                %it is alreday inlcuded into a previous

                                %iteration, so do not add it anymore

                                %Er(i,k) = 0;

                                %Er(k,i) = 0;

                                %Ner(i,k) = 0;

                                %Ner(k,i) = 0;

                                %plot([X(i,1) X(k,1)], [X(i,2) X(k,2)],’-m’); hold on;

                                fik = 1;

                            end

                        end

                        if fik == 0 && (Ner(i,k) == 2 || Ner(k,i) == 2) %&& (chk2(1,1) == 1 ||…

                                    %(chk2(1,1) == 0 && chk2(2,1) == 1 && (Ner(i,k) > 1 || Ner(k,i) > 1)) ||…

                                [mn id] = min(dks);

                                k = k(1,id);

        end

        else

            Q = [];

            Qactive = [];

        end

        B = [];

        while size(Q,1)>0

            found = 0;

            for qc = 1:size(Q,1)

                q = Q(qc,1);%struct number

                if Qactive(qc,1) == 1%if this sturct is not marked inactive

                    found = 1;

                    break;

                end

            end

            if found == 0

                Q = [];

                Qactive = [];

                break;

            end

            e = S{q}.f1;%starting edge

            pv = e(1,1);%previous and current vertices

            cv = e(1,2);

            plot([X(pv,1) X(cv,1)], [X(pv,2) X(cv,2)],’-g’, ‘linewidth’, 2); hold on;

            PVs = pv;%previous vertics, which are left column of S{q}.f1

            %explore the current struct

            while(1)

                vs = find(Er(cv,:) == 1); %all vertices that are connected to cv

                %find all vertices, other than pv, which are along boundary (remove non

                %boundary vertices

                bv = [];

                if cv == 1628 || cv == 156

                    here = 1;

                end

                for m = 1:size(vs,2)

                    k = vs(1,m);

                            if fv > 0

                                break;

                            end

                        end

                        if fv > 0% a new edge is found

                            count = count+1;

                            S{count} = s;

                            El = [El;[i j count 1]];

                            chkV(i,j) = 0;

                            chkV(j,i) = 0;

                            is = i;

                            js = j;

                            Q = [Q;count];%queue for structs to explore

                            Qactive = [Qactive; 1];

                        end

                    end

                    break;

                elseif size(bv,1) == 1

                    %only 1 option, so go forward tracking boundary

                    k = bv(1,1);

                    chkV(cv,k) = 0;

                    chkV(k,cv) = 0;

                    S{q}.f1 = [S{q}.f1; [cv k]];%update edge list for S{q}

                    S{q}.f2 = [S{q}.f2; k];%update vertices list for S{q}

                    El = [El; [cv k q size(S{q}.f1,1)]];

                    pv = cv;

                    cv = k;

                    plot([X(pv,1) X(cv,1)], [X(pv,2) X(cv,2)],’-m’, ‘linewidth’, 2); hold on;

                    if cv == 2935

                        here = 1;

                    end

                    PVs = [PVs;pv];            

                    if sum(PVs == cv)==1 %current vertext has already been visited in an earlier iteration, possibly a loop, so break

                        %self-loop! Update B

                        loopid = find(PVs == cv);

                        B = [B; [q size(S{q}.f1,1) q loopid]];%record the boundary

                        S{q}.f3 = [S{q}.f3; q];%update child list (a previuos paranet becomes a child, so a loop)

                        break;

                    end

                    %{

                    Vi(end,1) = k;

                    Vc = [Vc; pv];

                    if k == fv % aboundary is found

                        Vi = [];

                        Vc = [Vc; fv];

                        count = count + 1;

                        Vb{count,1} = Vc;

                        Vc = [];

                    end

                    %}            

                else%more than one option, generate new structs to explore latter

                    for l = 1:size(bv,1)

                        k = bv(l,1);

                        chkV(cv,k) = 0;

                        chkV(k,cv) = 0;

                        count = count+1;

                        %create a new struct and set q as a parent of new, and new

                        %as a child of q

                        S{count} = struct(‘f0’, q, ‘f1’, [cv k], ‘f2’, [cv;k], ‘f3’, []);

                        El = [El; [cv k count 1]];

                        S{q}.f3 = [S{q}.f3; count];

                        Q = [Q; count]; 

                        Qactive = [Qactive; 1];

                    end

                    break;

                end

            end

            if size(Q,1) > qc

                Q = Q(qc+1:end,:);

                Qactive = Qactive(qc+1:end,:);

                if sum(Qactive,1) == 0

                    Q = [];

                    Qactive = [];

                end

            end

            if size(Q,1) <= qc || size(Q,1) == 0

                Q = [];

                Qactive = [];

                %look for another boundary edge, if any

                    fv = 0;

                    bm = (Er & chkV) & (Ner == 1);

                    hasB = sum(sum(bm));

                    if hasB > 0

                        for i = is:nP

                            for j = js:nP

                                if i < j && bm(i,j)

                                    s = struct(‘f0’, [], ‘f1’, [i j], ‘f2’, [i;j], ‘f3’, []);%f0: parent struct, f1: edges, f2: vertices list, f3: children structs

                                    fv = i;%first vertex

                                    cv = j;%current vertex

                                    pv = i;%previous vertex

                                    %show

                                    %plot(X(fv,1), X(fv,2), ‘og’); hold on;

                                    %plot(X(pv,1), X(pv,2), ‘sy’); hold on;

            while(cur_num ~= first_num)%if they are different

                %then backtrach the edges and nodes

                cur_num = S{last_num}.f0; %take parents

                if size(cur_num,1) == 0 || sum(sids1 == cur_num) == 1

                    %the first sturcture was visited in previous iteration and it does not have a parent (cur_num is empty),

                    % or cur_num is alreday a visited strcuture, so break the loop

                    found = 0;

                    break;

                end

                if cur_num == first_num%loop found, so break the loop

                    joints = [joints; size(bids1,1)];

                    bids1 = [[S{first_num}.f1(first_num_edges:end,:) S{first_num}.f2(first_num_edges:end-1,:)]; bids1];

                    sids1 = [sids1;first_num];

                else

                    joints = [joints; size(bids1,1)];

                    bids1 = [[S{cur_num}.f1 S{cur_num}.f2(1:end-1,:)]; bids1];

                    sids1 = [sids1;cur_num];

                    last_num = cur_num;

                end

            end

            %check joints if they confirm a loop

            if found == 1

                fJoint = 1;

                for j = 1:size(joints,1)

                    jid = joints(j,1);

                    if bids1(jid,2) ~= bids1(jid+1,1)

                        fJoint = 0;

                        break;

                    end

                end

                if cur_num == first_num && fJoint == 1 && bids1(1,1) == bids1(end,2)

                    bcount = bcount + 1;

                    bids{bcount} = bids1;

                    sids{bcount} = sids1;

                    plot(X(bids1(:,1),1),X(bids1(:,1),2),’-c’, ‘linewidth’, 2); hold on;

                end

            end

        end

        end%if bigWholeFound == 1 

    end

    bndryin{bn} = bids;

end

end

🎉3 参考文献

部分理论来源于网络,如有侵权请联系删除。

[1]M. Awrangjeb, “Using point cloud data to identify,trace, and regularize the outlines of buildings” International Journal of Remote Sensing, Volume 37, Issue 3, February 2016, pages 551-579;

🌈4 Matlab代码、数据、文章讲解

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/dfdd1c6bbc.html