【植物检测】基于对称的作物田三维点云植物检测研究(Matlab代码实现)

该文章提出了一种基于3D点云的新方法,用于精准农业中单个植物的精确定位。这种方法利用植物间的几何相似性和播种模式,特别适用于规则排列的单一栽培种植园。实验表明,该方法在真实世界数据上的表现优于传统方法。文章还提供了Matlab代码示例,展示数据处理和评估过程。
摘要由CSDN通过智能技术生成

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

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

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

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

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

目录

💥1 概述

📚2 运行结果

🎉3 参考文献

🌈4 Matlab代码实现


💥1 概述

精准农业中使用的机器人系统的关键要求之一是能够检测单个植物的确切位置。 我们提出了一种基于从种植园获得的3D点云的新方法,该方法确定确切的植物位置,可用于基于地标的SLAM(同时定位) 和映射)在移动机器人上或用于引导工厂处理系统。 我们方法背后的关键思想是利用同一物种的单个植物之间的几何相似性以及它们播种的规则模式。 因此,我们的方法对于作物以规则模式排列的单一栽培种植园最有用。 在我们的实验研究中,我们表明所提出的方法优于对不同生长阶段记录的真实世界数据进行的传统平均偏移分析。

📚2 运行结果

 

 

 

 

 

 

部分代码:

%% plot examples from all days
for day = 1:nDays
    h = figure(day+798);
    datasets = days(day).datasets;
    data = load(strcat(basepathData, datasets{2}));
    pNorm = geometry.normalizePointCloud(data.mapFull);
    plot.pc(pNorm(:,1:2), data.mapColorFull, 'markersize', 20);
    ax = gca;
    ax.FontSize = 5;
    ax.XLim = [-3 3];
    ax.YLim = [-0.3 0.3];
    set(gcf, 'Position', [200.6040  713.8713  691.0099  120.7129])
    print(h, '-dpng', [basepathImages 'example_day' num2str(day) '.png'], '-r300')
end

%% do the evaluation for each error_threshold
for threshold_error = [0.01 0.02 0.04]

    %%
    for day = 1:nDays 
        %% evaluate each day individually
        datasets = days(day).datasets;
        
        % combine individual datasets for each day
        dayCombined.landmarksMeanshift = [];
        dayCombined.landmarksMeanshiftScores = [];
        dayCombined.landmarksApproach = [];
        dayCombined.landmarkScores = [];
        dayCombined.landmarksManual = [];
        dayCombined.map = [];
        dayCombined.mapColor = [];

        for j = 1:numel(datasets)
            datasetPath = [basepathData datasets{j}];
            data = load(datasetPath);
            %% plant soil segmentation 
            if ~isfield(data, 'map')
                [segmentation, extractorPolygon1, extractorPolygon2] = tools.greenextract(data.mapFull, data.mapColorFull);
                data.map = data.mapFull(segmentation,:);
                data.mapColor = data.mapColorFull(segmentation,:);
                save(datasetPath, '-struct', 'data', 'map', 'mapColor','-append')
            end
            %% manual landmarks
            if ~isfield(data, 'landmarksManual')
                h = figure(733);
                plot.pc(data.map, data.mapColor, 'markerSize', 20)
                datacursormode on
                dcm_obj = datacursormode(gcf);
                waitfor(msgbox('Click ok when finished labeling plants!'));
                cursor_info = getCursorInfo(dcm_obj);
                data.landmarksManual = vertcat(cursor_info.Position);
                if size(data.landmarksManual,2) == 3 
                    data.landmarksManual = data.landmarksManual(:,1:2);
                end
                save(datasetPath, '-struct', 'data', 'landmarksManual','-append')
            end
            if updateLandmarksManual
                figure(733);
                h = plot.pc(data.map(:,1:2), data.mapColor, 'markerSize', 20);
                datacursormode on
                dcm_obj = datacursormode(gcf);
                hTarget = handle(h);
                xdata = get(hTarget,'XData');
                ydata = get(hTarget,'YData');
                idx = knnsearch([xdata' ydata'], data.landmarksManual);

                for tipIdx = 1:size(data.landmarksManual, 1)
                    hDatatip = dcm_obj.createDatatip(hTarget);
                    propPointDataCursor = get(hDatatip,'Cursor'); 
                    % Move the datatip 
                    propPointDataCursor.DataIndex = idx(tipIdx); 
                    pos = [xdata(idx(tipIdx)) ydata(idx(tipIdx))];
                    propPointDataCursor.Position = pos;
                    set(hDatatip,'Position',pos)
                end
                waitfor(msgbox('Click ok when finished labeling plants!'));
                cursor_info = getCursorInfo(dcm_obj);
                data.landmarksManual = vertcat(cursor_info.Position);
                if size(data.landmarksManual,2) == 3 
                    data.landmarksManual = data.landmarksManual(:,1:2);
                end
                save(datasetPath, '-struct', 'data', 'landmarksManual','-append')
            end
            %% tf density approach on whole map
            if recalculateApproach && isfield(data, 'landmarksApproach')
                data = rmfield(data, 'landmarksApproach');
            end
            if ~isfield(data, 'landmarksApproach')
                [data.landmarksApproach, data.landmarkScores] = optimization.detectPlants(data.map, days(day).args{:});
                save(datasetPath, '-struct', 'data', 'landmarksApproach', 'landmarkScores', '-append')
            end
            %% mean shift baseline
            if recalculateMeanshift && isfield(data, 'landmarksMeanshift')
                data = rmfield(data, 'landmarksMeanshift');
            end
            if ~isfield(data, 'landmarksMeanshift')
                [data.landmarksMeanshift,~,clusterSizes] = clustering.meanshift(data.map', days(day).args{12});
                data.landmarksMeanshiftScores = vector.normalize(cellfun('length',clusterSizes));
                save(datasetPath, '-struct', 'data', 'landmarksMeanshift', 'landmarksMeanshiftScores', '-append')
            end

            %% combine 
            dayCombined.landmarksMeanshift = [dayCombined.landmarksMeanshift; data.landmarksMeanshift];
            dayCombined.landmarksMeanshiftScores = [dayCombined.landmarksMeanshiftScores; data.landmarksMeanshiftScores];
            dayCombined.landmarksApproach = [dayCombined.landmarksApproach; data.landmarksApproach];
            dayCombined.landmarkScores = [dayCombined.landmarkScores; data.landmarkScores]; 
            dayCombined.landmarksManual = [dayCombined.landmarksManual; data.landmarksManual]; 
            dayCombined.map = [dayCombined.map; data.map];
            dayCombined.mapColor = [dayCombined.mapColor; data.mapColor];
        end
        landmarksMeanshift = dayCombined.landmarksMeanshift;
        landmarksMeanshiftScores = dayCombined.landmarksMeanshiftScores;
        landmarksApproach = dayCombined.landmarksApproach;
        landmarkScores = dayCombined.landmarkScores;
        landmarksManual = dayCombined.landmarksManual;
        fprintf('day %d: %d labels\n', day,size(landmarksManual,1))

        %% calculate errors
        [errorMeanshiftVecidx, errorMeanshift] = knnsearch(landmarksManual, landmarksMeanshift(:,1:2));
        [errorApproachVecidx, errorApproach] = knnsearch(landmarksManual, landmarksApproach(:,1:2));
        errorMeanshiftVec = landmarksManual(errorMeanshiftVecidx,:) - landmarksMeanshift(:,1:2);
        errorApproachVec = landmarksManual(errorApproachVecidx,:) - landmarksApproach(:,1:2);

        %% eval approach
        figure(day); view(2)
        thresholds = [];
        rms = [];
        sizes =  [];
        for step = 1:100
            landmarksApproachSel = landmarksApproach(landmarkScores > ((step-1)/100),:);
            [errorApproachVecidx, errorApproach] = knnsearch(landmarksManual, landmarksApproachSel(:,1:2));
            sizes(step) = size(landmarksApproachSel,1);
            thresholds(step) =  step/100;
            rms(step) = sqrt(mean(errorApproach.^2));
            if thresholds(step) == 0.9
               fprintf('day %d, score threshold 0.9, rms %f, detection ratio %f\n', day, rms(step), sizes(step)/size(landmarksManual,1))
            end
        end
        yyaxis left
        plot(thresholds,1000*rms, '--b')
        xlabel('score threshold')

🎉3 参考文献

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

[1]Janosch Dobler, Alexander Schaefer, Wolfram Burgard (2018) Symmetry-Based Plant Detection in 3D Point Clouds from Crop Fields

🌈4 Matlab代码实现

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荔枝科研社

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值