红苹果的圆度、直径大小标定

news2024/11/17 14:25:06
function fruitImageProcessingGUI
    % 创建主窗口和控件
    mainFigure = figure('Units', 'normalized', 'Position', [0.3, 0.3, 0.4, 0.4]);
    instructionText = uicontrol('Style', 'text', 'String', '请点击按钮执行相应的图像处理步骤', ...
        'Units', 'normalized', 'Position', [0.1, 0.7, 0.8, 0.2], 'FontSize', 12);
    readImageBtn = uicontrol('Style', 'pushbutton', 'String', '读取图像', ...
        'Units', 'normalized', 'Position', [0.2, 0.4, 0.6, 0.1], 'FontSize', 12, ...
        'Callback', @readImageBtn_Callback);
    thresholdBtn = uicontrol('Style', 'pushbutton', 'String', '阈值化', ...
        'Units', 'normalized', 'Position', [0.2, 0.3, 0.6, 0.1], 'FontSize', 12, ...
        'Enable', 'off', 'Callback', @thresholdBtn_Callback);
    % 在这里继续添加其他按钮和控件
    
    % 存储GUI数据的结构体
    handles = struct();
    
    % 读取图像按钮的回调函数
    function readImageBtn_Callback(~, ~)
        % 读取图像
        rgb = imread('fruit.jpg');
        [m, n, d] = size(rgb);

        % 更新说明文本框
        set(instructionText, 'String', '图像已读取');
        
        % 将图像保存到GUI数据中,以便其他按钮功能使用
        handles.rgb = rgb;
        handles.m = m;
        handles.n = n;
        handles.d = d;
        
        % 启用下一个按钮
        set(thresholdBtn, 'Enable', 'on');
        
        % 更新GUI数据
        guidata(mainFigure, handles);
    end

    % 阈值化按钮的回调函数
    function thresholdBtn_Callback(~, ~)
        % 获取GUI数据中的图像和尺寸信息
        rgb = handles.rgb;
        m = handles.m;
        n = handles.n;
        d = handles.d;

        % 阈值设置
        level1 = [255 * 0.2, 255 * 0.3];

        % 转换数据类型,图像输出类型只能是uint型
        rgb = uint8(rgb);

        % 剔除r-g < level1(1), r-g < level1(2)的部分
        r = rgb;
        for i = 1:m
            for j = 1:n
                if (rgb(i, j, 1) - rgb(i, j, 2)) < level1(1) && (rgb(i, j, 1) - rgb(i, j, 3)) < level1(2)
                    r(i, j, 1) = 0;
                    r(i, j, 2) = 0;
                    r(i, j, 3) = 0;
                end
            end
        end

        % 更新说明文本框
        set(instructionText, 'String', '图像阈值化完成');

        % 在此处可以添加显示阈值化后的图像的代码,例如使用imshow函数显示r

        % 更新GUI数据
        handles.rgb = r;
        guidata(mainFigure, handles);
    end

    % 在这里继续添加其他按钮的回调函数

end
function imageSegmentationGUI()
    % 创建GUI窗口
    fig = figure('Name', '目标与背景的分割与提取', 'NumberTitle', 'off', 'Position', [200, 200, 900, 600]);

    % 创建UI组件
    btnSelectImage = uicontrol('Style', 'pushbutton', 'String', '选择图像', 'Position', [50, 500, 100, 30], 'Callback', @selectImage);
    btnMeanFilter = uicontrol('Style', 'pushbutton', 'String', '均值滤波', 'Position', [50, 450, 100, 30], 'Callback', @applyMeanFilter);
    btnThresholding = uicontrol('Style', 'pushbutton', 'String', '二值图像', 'Position', [50, 400, 100, 30], 'Callback', @applyThresholding);
    btnOpening = uicontrol('Style', 'pushbutton', 'String', '开启运算', 'Position', [50, 350, 100, 30], 'Callback', @applyOpening);
    btnClosing = uicontrol('Style', 'pushbutton', 'String', '闭合运算', 'Position', [50, 300, 100, 30], 'Callback', @applyClosing);
    btnEdgeDetection = uicontrol('Style', 'pushbutton', 'String', '提取边缘', 'Position', [50, 250, 100, 30], 'Callback', @applyEdgeDetection);
    btnShowResult = uicontrol('Style', 'pushbutton', 'String', '显示结果', 'Position', [50, 200, 100, 30], 'Callback', @showResult);
    btnSegmentation = uicontrol('Style', 'pushbutton', 'String', '分割图像', 'Position', [50, 150, 100, 30], 'Callback', @performSegmentation);
    btnExit = uicontrol('Style', 'pushbutton', 'String', '退出', 'Position', [50, 100, 100, 30], 'Callback', @exitGUI);
    

    axesHandle1 = axes('Parent', fig, 'Position', [0.3, 0.1, 0.6, 0.8]);

    % 全局变量
    rgb = [];
    r=[];
    grayImage = [];
    thresholdedImage = [];
    openedImage = [];
    closedImage = [];
    edgeImage = [];
    resultImage = [];

    % 图像处理函数
    function selectImage(~, ~)
        [fileName, pathName] = uigetfile({'*.jpg;*.png;*.bmp', '图像文件 (*.jpg, *.png, *.bmp)'}, '选择图像');

        if isequal(fileName, 0) || isequal(pathName, 0)
            return;
        end

        % 读取图像
        rgb = imread(fullfile(pathName, fileName));

        % 显示原图像
        imshow(rgb, 'Parent', axesHandle1);
    end

    function applyMeanFilter(~, ~)
        if isempty(rgb)
            errordlg('请先选择图像!', '错误');
            return;
        end

        % 均值滤波
        r2=rgb;
        grayImage = rgb2gray(r2);
        n = 3;
        template = ones(n) / (n * n);
        filteredImage = imfilter(double(grayImage), template, 'replicate');

        % 显示均值滤波后的图像
        imshow(filteredImage, 'Parent', axesHandle1);
    end

    function applyThresholding(~, ~)
        if isempty(grayImage)
            errordlg('请先进行均值滤波!', '错误');
            return;
        end

        % 二值图像
        threshold = graythresh(grayImage);
        thresholdedImage = imbinarize(grayImage, threshold);

        % 显示二值图像
        imshow(thresholdedImage, 'Parent', axesHandle1);
    end

    function applyOpening(~, ~)
        if isempty(thresholdedImage)
            errordlg('请先进行二值图像处理!', '错误');
            return;
        end

        % 开启运算
        se = strel('disk', 12);
        openedImage = imopen(thresholdedImage, se);

        % 显示开启运算后的图像
        imshow(openedImage, 'Parent', axesHandle1);
    end

    function applyClosing(~, ~)
        if isempty(openedImage)
            errordlg('请先进行开启运算!', '错误');
            return;
        end

        % 闭合运算
        se = strel('disk', 5);
        closedImage = imclose(openedImage, se);

        % 显示闭合运算后的图像
        imshow(closedImage, 'Parent', axesHandle1);
    end

    function applyEdgeDetection(~, ~)
        if isempty(closedImage)
            errordlg('请先进行闭合运算!', '错误');
            return;
        end

        % 提取边缘
        edgeImage = edge(closedImage, 'canny');

        % 显示边缘图像
        imshow(edgeImage, 'Parent', axesHandle1);
    end

    function showResult(~, ~)
        if isempty(edgeImage)
            errordlg('请先进行边缘提取!', '错误');
            return;
        end

        % 分割完成的图像
        resultImage = edgeImage; % 这里将边缘图像作为分割结果,您可以根据需要修改这部分代码

        % 显示分割结果
        imshow(resultImage, 'Parent', axesHandle1);
    end

    function performSegmentation(~, ~)
        if isempty(rgb)
            errordlg('请先选择图像!', '错误');
            return;
        end

        % 在这里执行分割任务
        % 根据您的代码进行相应的处理
        % ...

        % 显示分割结果
        resultImage = rgb; % 这里将原图像作为分割结果,您可以根据需要修改这部分代码

        % 显示分割结果
        imshow(resultImage, 'Parent', axesHandle1);
    end

    function exitGUI(~, ~)
        choice = questdlg('确定要退出吗?', '退出', '是', '取消', '取消');

        if strcmp(choice, '是')
            close(fig);
        end
    end
end

GUI界面设计如下
在这里插入图片描述
实现目标与背景的分割和提取

clear
clc
close all

h = 0.002; % 步长
x1 = 100;
x0 = 0:h:x1;
y0 = [2; 2; 2; 2]; % 初始条件,对应 x, y, z, w
% 不同的 c
c = 1:1:500;
N_c = length(c);
N_P = 300; % 假设穿过截面的共有 300 个点
BF = nan(N_c, N_P);
for k = 1:N_c
    c_k = c(k);
    disp(c_k)
    % 计算轨迹
    [y1, ~] = ODE_RK4_hyh(0:10*h:x1, 10*h, y0, [c_k, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]); % 先粗略的计算前几步,然后排除初始点的影响,舍弃不要
    [y1, ~] = ODE_RK4_hyh(x0 + x1, h, y1(:, end), [c_k, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]);
    % 计算 Poincare 平面
    Plane = [1; -1; 0; 0]; % x - y = 0 平面 (正方向)
    [tP_List, yP_List] = Solve_Poincare(x0, y1, Plane); % 计算 Poincare 平面
    % 对于混沌系统再加一条,如果系统稳定了,则将稳定点也记录在最终分岔图内:
    if isempty(tP_List) && abs(y1(1, end) - y1(2, end)) < 1e-2 % 如果最后 x 和 y 足够接近,则认为收敛了
        tP_List = x0(end - 1:end);
        yP_List = y1(:, end - 1:end);
    end
    % 储存 y 值作为待会分岔图的点
    N_P_temp = size(tP_List, 2);
    if N_P_temp > N_P
        BF(k, 1:N_P) = yP_List(2, 1:N_P);
    else
        BF(k, 1:N_P_temp) = yP_List(2, 1:N_P_temp);
    end
end

% 绘制分岔图
figure()
hold on
for k = 1:N_P
    c_k = c(k);
    plot(c_k * ones(1, N_P), BF(k, 1:N_P), ...
        'LineStyle', 'none', 'Marker', '.', 'MarkerFaceColor', 'k', 'MarkerEdgeColor', 'k', ...
        'MarkerSize', 1)
end
hold off

function [tP_List, yP_List] = Solve_Poincare(t, y, Plane)
    % 截面方程 z = 0
    % Plane = [0; 0; 1; 0]; % 一般情况下是个垂直某个轴的平面
    % 一般只记录从负到正穿越。如果想反向也记录,可以设置 Plane = -Plane.

    % 第二步,插值得到线与面的交点
    yP_List = [];
    tP_List = [];
    Dis = DistancePlane(y, Plane);
    N = size(y, 2);
    for k = 1:N - 1
        if Dis(k) <= 0 && Dis(k + 1) > 0
            t0 = t(k);
            t1 = t(k + 1);
            yP0 = y(:, k);
            yP1 = y(:, k + 1);
            Dis0 = Dis(k);
            Dis1 = Dis(k + 1);
            % 一维线性插值,求 Dis = 0 时的 t 和 y
            yP = yP0 + (yP1 - yP0) / (Dis1 - Dis0) * (0 - Dis0);
            tP = t0 + (t1 - t0) / (Dis1 - Dis0) * (0 - Dis0);
            % 储存
            yP_List = [yP_List, yP];
            tP_List = [tP_List, tP];
        end
    end
end

% 点到平面的距离
function Dis = DistancePlane(xk, Plane)
    % xk,坐标点,如果是 3 维坐标,大小就是 3*N 的矩阵。
    % Plane,平面,形如 Ax + By + Cz + D = 0 形式的平面。

    N = size(xk, 2); % 计算总共多少个点
    xk2 = [xk; ones(1, N)];
    Dis = dot(xk2, Plane * ones(1, N), 1) / norm(Plane(1:end - 1));
end

function [F, Output] = Fdydx(x, y, Input)
    % 形式为 Y' = F(x, Y) 的方程,参见数值分析求解常系数微分方程相关知识
    % 高次用列向量表示,F = [dy(1); dy(2)]; y(1) 为函数,y(2) 为函数导数
    % 给定混沌系统的微分方程
    a = Input(1);
    b = Input(2);
    c = Input(3);
    d = Input(4);
    e = Input(5);
    f = Input(6);
    g = Input(7);
    h = Input(8);
    
    dxdt = a * y(3) * y(2) + c * y(4) * cos(y(2));
    dydt = -y(1) * y(3) + b * y(2) + e * y(1) + f * y(2);
    dzdt = y(1) * y(2) - c * y(3) + f * y(3);
    dwdt = y(2) * y(3) - d * y(4) + g * y(1) * cos(y(2)) + h * y(2) * sin(y(3));

    F = [dxdt; dydt; dzdt; dwdt];
    Output = [];
end

function [y, Output] = ODE_RK4_hyh(x, h, y0, Input)
    % 4阶RK方法
    % h 间隔为常数的算法
    y = zeros(size(y0, 1), size(x, 2));
    y(:, 1) = y0;
    for ii = 1:length(x) - 1
        yn = y(:, ii);
        xn = x(ii);
        [K1, ~] = Fdydx(xn, yn, Input);
        [K2, ~] = Fdydx(xn + h / 2, yn + h / 2 * K1, Input);
        [K3, ~] = Fdydx(xn + h / 2, yn + h / 2 * K2, Input);
        [K4, ~] = Fdydx(xn + h, yn + h * K3, Input);
        y(:, ii + 1) = yn + h / 6 * (K1 + 2 * K2 + 2 * K3 + K4);
    end
    Output = [];
end

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述 使用matlab对图像进行去噪处理、对彩色图像 进行目标和背景分析,通过阈值法将图像进行分割,提取特征参数,并对圆度和直径进行标定。使用均值滤波等一系列方法实现了对苹果的分割提取以及特征参数的标定。但是本次设计存在不足之处,对于重叠区域的分割与提取暂未处理好。
[1]陈贝文,陈淦.水果分类识别与成熟度检测技术综述[J].计算机时代,2022(07):62-65.DOI:10.16644/j.cnki.cn33-1094/tp.2022.07.016.
[2]王运祥,马本学,贾艳婷等.采用夹持果梗方法的水果检测分级机设计[J].食品与机械,2015,31(05):107-110.DOI:10.13652/j.issn.1003-5788.2015.05.027.
[3]苗玉彬,王浙明,刘秦.水果轮廓特征提取的Zernike矩分水岭分割方法[J].农业工程学报,2013,29(01):158-163.
[4]应义斌.水果图像的背景分割和边缘检测技术研究[J].浙江大学学报(农业与生命科学版),2000(01):37-40.
[5]徐琳,吕宇玲,王晓娟.水果的分割算法研究[J].数字通信世界,2018(05):274-275.
[6]苗玉彬,王浙明,刘秦.水果轮廓特征提取的Zernike矩分水岭分割方法[J].农业工程学报,2013,29(01):158-163.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1713587.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos 进阶篇---Nacos服务下线做了哪些事情 ?(八)

一、引言 本章节是第一阶段最后一篇&#xff0c;那么我们今天要学习的源码内容是 “服务下线”. 当Nacos客户端下线的时候&#xff0c;是要去通知服务端&#xff0c;告诉服务端 “ 我已经下线&#xff0c;不可用了 ”。并且在服务下线时&#xff0c;还要去通知其他客户端服务更…

uni-app解决表格uni-table样式问题

一、如何让表格文字只显示一行&#xff0c;超出部分用省略号表示 步骤 &#xff1a; 给table设置table-layout:fixed; 列宽由表格宽度和列宽度设定。&#xff08;默认是由单元格内容设定&#xff09;让表格元素继承父元素宽度固定table-layout: inherit;overflow: hidden;超过…

STM32-电灯,仿真

目录 1.配置vscode 2.新创建软件工程 3.仿真 4.源码 5.运行效果 1.配置vscode http://t.csdnimg.cn/BvCLx 安装 C/C Extension Pack 安装 Embedded IDE 安装 Keil MDK 配置路径 2.新创建软件工程 下拉找到对应的 输入项目名字,选择项目所在文件夹即可 3.仿真 一路新…

机器视觉分析在加油站安全中的应用:使用手机检测、打电话行为识别

在加油站等高危场所&#xff0c;禁止使用手机是为了防止潜在的火灾和爆炸风险。手机在使用过程中可能产生电火花&#xff0c;而在加油站这种易燃易爆环境中&#xff0c;任何电火花都可能引发严重的安全事故。因此&#xff0c;加油站禁止使用手机是保障安全生产的重要措施。基于…

【好书分享第十三期】AI数据处理实战108招:ChatGPT+Excel+VBA

文章目录 一、内容介绍二、内页插图三、作者简介四、前言/序言五、目录 一、内容介绍 《AI数据处理实战108招&#xff1a;ChatGPTExcelVBA》通过7个专题内容、108个实用技巧&#xff0c;讲解了如何运用ChatGPT结合办公软件Excel和VBA代码实现AI办公智能化、高效化。随书附赠了…

深入解析多维数组与主对角线元素之和

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;多维数组的奥秘 二、多维数组的基本概念 1. 定义与创建 2. 维度与形…

(文章复现)分布式电源接入配电网承载力评估方法研究

参考文献&#xff1a; [1]郝文斌,孟志高,张勇,等.新型电力系统下多分布式电源接入配电网承载力评估方法研究[J].电力系统保护与控制,2023,51(14):23-33. 1.摘要 随着光伏和风电等多种分布式电源的接入&#xff0c;使得传统配电网的结构及其运行状态发生了较大改变。因此&…

Tableau解包与版本兼容性

Tableau解包与版本兼容性 1、背景描述2、Tableau解包3、Tableau版本兼容性 1、背景描述 有时&#xff0c;在使用Tableau Desktop打开.twbx打包工作簿时&#xff0c;可能会出现如下弹框&#xff1a; 通常考虑以下两种处理情况 2、Tableau解包 解包打包的.twbx工作簿&#xff0c…

会议管理系统(含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 会议管理系统拥有两种角色 管理员&#xff1a;部门管理、员工管理、会议管理、会议室管理、预订会议、添加员工、注册员工审批等 用户&#xff1a;个人通知中心、预订会议、查看所有会议…

强化学习——学习笔记3

一、强化学习都有哪些分类&#xff1f; 1、基于模型与不基于模型 根据是否具有环境模型&#xff0c;强化学习算法分为两种&#xff1a;基于模型与不基于模型 基于模型的强化学习(Model-based RL)&#xff1a;可以简单的使用动态规划求解&#xff0c;任务可定义为预测和控制&am…

文心智能体平台 | 想象即现实

目录 文心智能体平台介绍平台简介通过平台能做什么平台的优势智能体介绍智能体类型AI 插件介绍 动手创建一个智能体访问平台并进行账号注册根据适合的方式选择智能体类型快速创建智能体智能体个性化模块配置 总结注意事项我的智能体 文心智能体平台介绍 平台简介 文心智能体平…

ArcGIS常规操作-带你创建正确的空间数据库

ArcGIS常规操作-带你创建正确的空间数据库 ArcGIS一词在各行业中出现得越来越多&#xff0c;尤其在国土空间规划中&#xff0c;依赖大量GIS工具和技术的应用&#xff0c;ArcGIS成为了必备的技能之一。今天讲解一下ArcGIS的基础操作&#xff0c;让大家可以快速地上手ArcGIS&…

这有一封“数字赋能 强农兴村”的邀请函,请查收→

2024年6月5日至7日&#xff0c;以“数字赋能 强农兴村”为主题的2024中国&#xff08;南京&#xff09;数字乡村博览会暨第八届中国&#xff08;南京&#xff09;国际智慧农业博览会将在江苏南京举办。珈和科技在农业AI大数据展区的H16展位与您相约&#xff0c;共襄盛会。 私信…

祝贺!阿里云PolarDB斩获数据库国际顶会ICDE 2024工业赛道最佳论文

5月17日消息&#xff0c;在荷兰举行的国际顶级数据库学术会议ICDE 2024上&#xff0c;阿里云斩获工业和应用赛道的“最佳论文奖”&#xff0c;这也是中国企业首次获此殊荣。阿里云PolarDB创新性地解决了数据库Serverless中跨机事务迁移的核心难题&#xff0c;将跨机迁移时间压缩…

消费者组到底是什么?no.15

Kafka的消费者组。 消费者组&#xff0c;即Consumer Group&#xff0c;应该算是Kafka比较有亮点的设计了。那么何谓Consumer Group呢&#xff1f;用一句话概括就是&#xff1a;Consumer Group是Kafka提供的可扩展且具有容错性的消费者机制。既然是一个组&#xff0c;那么组内必…

LLM - 模型下载与 git-lfs 安装

目录 一.引言 二.安装 git lfs 1.使用 apt-get 安装 2.使用 Brew 安装 3.LFS 验证 三.总结 一.引言 在 HuggingFace 上下载模型时提供一个 git clone 的指令&#xff0c;执行后可以下载对应模型的模型文件: 但是本机还没有 git lfs 命令: git: lfs is not a git comman…

从这些原理中,读懂迅软DSE加密系统

加密技术是保护信息安全的系统&#xff0c;通过对原始数据进行加密&#xff0c;使得未经授权的人无法读取这些信息。 一、迅软DSE加密系统干什么用的&#xff1f; ★保护隐私&#xff1a;加密确保个人、机构的敏感信息在传输和存储过程中不被未授权的人访问。 ★防止数据泄露…

从简单到复杂,红酒配餐的层次感与变化

红酒配餐是一种艺术&#xff0c;通过不同层次的搭配&#xff0c;可以呈现出丰富的味觉变化&#xff0c;使每一口都充满惊喜。云仓酒庄雷盛红酒以其卓着的品质和与众不同的口感&#xff0c;为红酒配餐提供了无限可能。从简单到复杂&#xff0c;红酒配餐的层次感与变化如下&#…

CAD石墨烯生成器 V1.0 渊鱼

插件介绍 CAD石墨烯生成器插件可用于在AutoCAD软件内参数化建立石墨烯几何模型。插件建立石墨烯的球棍模型&#xff0c;可控制模型的尺寸、碳原子环的尺寸、原子直径、化学键直径&#xff0c;并可控制模型的起伏形态。插件生成的实体模型可进行修改或绘图渲染&#xff0c;用于…

flutter开发实战-类似微博帖子列表及下拉刷新上拉加载效果

flutter开发实战-类似微博帖子列表及下拉刷新上拉加载效果 在之前处理类似微博帖子列表及下拉刷新上拉加载效果&#xff0c;刷新使用的是EasyRefresh 一、引入EasyRefresh与likeButton 在工程的pubspec.yaml中引入插件 # 下拉刷新、上拉更多easy_refresh: ^3.3.21pull_to_re…