数字图像处理项目——模糊图像边缘检测算法设计及实现(论文/代码)

完整的论文代码见文章末尾 以下为部分内容

摘要

本研究旨在针对大脑核磁图像中的黑色腔体进行有效分割,以提供可靠的腔体定位和分析。为此,采用了三种常用的图像分割方法:8邻域区域生长法、Canny算子边缘检测和8邻域边界跟踪法。

首先,应用8邻域区域生长法来识别具有相似性质的像素,并将其合并为腔体区域。该方法基于种子点的选择和与相邻像素的相似性判断,能够快速而准确地生成初步的腔体分割结果。

其次,运用Canny算子边缘检测方法,通过计算图像梯度和非极大值抑制,实现对腔体边缘的精细检测。该算法能够提取出清晰的边缘信息,对于复杂的腔体结构有较好的适应性。

最后,采用8邻域边界跟踪法对初步分割得到的腔体边缘进行追踪,从起始点开始形成闭合的边界线。该方法通过遍历邻域像素点,递归地跟踪边界,并生成完整的腔体轮廓。

通过对比实验结果,本文对三种方法在黑色腔体分割方面的优劣进行了分析。基于分割准确性、计算效率和鲁棒性等因素,我们提出了最佳的分割策略,以获得最优的黑色腔体分割结果。

本研究的成果对于大脑核磁图像的进一步分析和诊断具有重要意义,为相关领域的研究和应用提供了有力支持。

关键词: 大脑核磁图像、分割、8邻域区域生长法、Canny算子边缘检测、8邻域边界跟踪法、优化策略

实现原理

邻域区域生长法

区域生长是指从某个像素出发,按照一定的准则,逐步加入邻近像素,当满足一定的条件时,区域生长终止。区域生长的好坏决定于1.初始点(种子点)的选取。2.生长准则。3.终止条件。区域生长是从某个或者某些像素点出发,最后得到整个区域,进而实现目标的提取。

简单来说下三个法则,对出需要分割的图像:

  • 选取图像中的一点为种子点(种子点的选取需要具体情况具体分析)。
  • 在种子点处进行8邻域或4邻域扩展,判定准则是:如果考虑的像素与种子像素灰度值差的绝对值小于某个门限T,则将该像素包括进种子像素所在的区域。
  • 当不再有像素满足加入这个区域的准则时,区域生长停止。

在这里插入图片描述

canny算子边缘检测

Canny边缘检测算法可以分为以下5个步骤:

  1. 使用高斯滤波器,以平滑图像,滤除噪声。
  2. 计算图像中每个像素点的梯度强度和方向。
  3. 应用非极大值(Non-MaximumSuppression)抑制,以消除边缘检测带来的杂散响应。
  4. 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
  5. 通过抑制孤立的弱边缘最终完成边缘检测。

为了尽可能减少噪声对边缘检测结果的影响,所以必须滤除噪声以防止由噪声引起的错误检测。为了平滑图像,使用高斯滤波器与图像进行卷积,该步骤将平滑图像,以减少边缘检测器上明显的噪声影响。大小为(2k+1)x(2k+1)的高斯滤波器核的生成方程式由下式给出:

在这里插入图片描述

本节代码展示:

clear;
img_src = imread("brain.jpg");
img_gray = rgb2gray(img_src);
img_int = img_gray(600:1000,700:1400); %截取图片
imshow(img_int);
img_int = smoothdata(img_int,'gaussian',10);

his = imhist(img_int);          %统计灰度直方图
[x,y] = size(img_int);
thd = getOSTUThreshold(his);    %获取大津法阈值
img_bw = zeros(x,y);        
for i = 1:x                     %二值化
    for k = 1:y
        if img_int(i,k) > thd
            img_bw(i,k) = 255;
        else
            img_bw(i,k) = 0;
        end
    end
end 

SE = strel('rectangle',[50 50]);    %创建结构矩阵
img_bw = imdilate(img_bw,SE);       %图像腐蚀´
img_bw = imerode(img_bw,SE);        %图像膨胀
img_bw = 255 - img_bw;              %图像反转
img_bw = bwareaopen(img_bw,10000,8);% 去除小面积连通域
img_edge = edge(img_bw,'canny');    %canny算子检测边界
SE = strel('rectangle',[5 5]);
img_edge = imerode(img_edge,SE);   %对边界进行膨胀
imshow(img_edge);
 
for i = 1:x                         %在原图中显示
    for k = 1:y
        if img_edge(i,k) == 1
            img_src(i + 600,k + 700) = 255;
        end
    end
end
imshow(img_src);
function thd = getOSTUThreshold(his)
sum = 0;        %个数和
valueSum = 0;   %值的和
g = 0;          %类间方差
g_per = 0;
low = 0;        %w1小于阈值的点数占比
high = 0;
ave_low = 0;     %u1小于阈值的值的平均
ave_high = 0;
min = 1;         %存在的最小灰度值
max = 256;
sum_low = zeros(256);       %存放低于阈值的像素点数总和,用于计算平均灰度

sum_low_val = zeros(256);   %存放低于阈值的像素值总和
 
for i = 1:256               %寻找存在的最小灰度值
    if his(i) == 0
        min = i;
    else
        break;
    end
end
 
for i = 0:255            %寻找存在的最大灰度值
    if his(256 - i) == 0
        max = 256 - i;
    else
        break;
    end
end
 
for i = min+1:max
    sum = sum + his(i - 1);
    valueSum = valueSum + his(i - 1)*(i - 1);
    sum_low(i) = sum;
    sum_low_val(i) = valueSum;
end
 
for i = min+1:max
    low = sum_low(i) / sum;
    high = 1- low;
    ave_low = (sum_low_val(i) / sum_low(i));
    ave_high = ((valueSum - sum_low_val(i)) / (sum - sum_low(i)));
    g = (low * high * (ave_low - ave_high) * (ave_low - ave_high));
    if g >= g_per
        g_per = g;
        thd = i;
    else
        break;
    end
    
end

end

邻域边界跟踪法

该算法基于以下原理:边界像素通常具有与其邻域像素明显不同的属性,例如亮度、颜色或纹理等。通过比较像素之间的差异,我们可以识别出边界。

下面是邻域边界跟踪法的基本步骤:

选择一个起始点作为边界的一部分。

检查当前像素的邻域像素(例如,上、下、左、右四个方向)。
根据预定义的条件判断当前像素是否属于边界。这些条件可以是像素灰度差异、颜色差异或梯度值等。

如果当前像素符合条件,则将其标记为边界点,并将其添加到边界集合中。

移动到下一个邻域像素,重复步骤3和步骤4,直到回到起始点或无法找到满足条件的邻域像素。

如果回到起始点,则边界跟踪完成;否则,选择一个新的起始点并重复步骤2到步骤5,直到图像中的所有边界都被跟踪完毕。

通过这种方式,我们可以在图像中获取连通的边界像素,并将它们组织成边缘。通常,边界跟踪算法会将边界像素连接起来,形成封闭的边缘。

在这里插入图片描述

结果对比

在方法1中,原本的思路是每次在灰度图中选去一个点来进行种子生长,但每次选取的位置不同,会出现意料之外的事,比如选择了腔体内的点,结果,生长的区域却在腔体外。因此为了实现功能,最后选择了一个固定的点来进行种子生长,相应地,种子生长在错误区域的情况也并没有发生,较好地完成了实验。

在方法2中,采用传统的图像处理方法,先对原图像进行一系列图像增强的操作,再利用图像形态学的知识对其进行分割,最后用边缘检测算子提取边界。对比二者结果来看,区域生长方法提取的边界更贴合目标,但边缘相对来说不够平滑,还是有待改进,而传统算子提取的边界由于一些部分的灰度值是缓慢变化的,效果不够理想,如粉色圈出的部分。

传统算子提取的边界

在这里插入图片描述
区域生长提取的边界
在这里插入图片描述

方法三中,由于二值化后没有进行平滑滤波以及闭操作,出来的边界也呈现出锯齿状。但因为二值化阈值为人工选取,所以不会出现区域不连通等情况,且边界与原图的匹配性也很好。而且可以发现,对模糊大图像进行处理时,先将图像缩小进行计算,再将结果进行放大是没有什么影响的,反而可以提高计算的效率。

论文 代码 获取方式

点这里 只需要一点点辛苦费。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ES13:类的新增特性、最外层的await、at...

1-类的新增特性 类私有属性和方法:# class Person{// 不需要传参、一开始就需要初始化的,就可以在类的最外面直接声明这个成员state{a:1,b:2}constructor(name,age){this.namename;this.ageage;}}在属性和方法前加#表示私有 #obj{} #prest(){}静态成员…

数据结构--链式栈

一.链式栈的栈顶在哪里? 二.链栈的结构: typedef struct LSNode{ int data; struct LSNode* next; }LSNode ,*PLStack; //链栈的节点.由于栈顶在第一个数据节点,所以不需要top指针 三.链式栈的实现: //初始化LSNode* p (LSNode*)malloc(sizeof(LSNode));assert(p ! NULL)…

C语言调用Python

目录 1.直接调用python语句 头文件引用 2.调用无参有参函数 1、调用无参函数 1.建立nopara.py文件 2.使用c语言根据上面流程进行调用 2、调用有参函数 1.建立nopara.py文件 2.使用c语言根据上面流程进行调用 C语言调用python需要我们已经安装好了libpython3的 dev依赖…

【Shell语言学堂】数组练习题

数组练习 1、使用数组和循环实现冒泡排序2、将冒泡排序的代码重构为2个函数,2个关系是a函数调用b函数自定义数组参数: 3、声明一个存储的全整数数组,对其中的每一个值进行10处理4、对硬盘使用空间占比的排序5、对当前目录的文件大小进行排序 …

小型企业网络安全指南

许多小型企业刚刚起步,没有大公司所拥有的相同资源来保护其数据。他们不仅可能没有资金来支持多样化的安全计划,而且也可能没有人力或时间。 网络犯罪分子知道小型企业缺乏这些资源,并利用这些资源来谋取利益。遭受网络攻击后,小…

7、configMap

1、configMap是什么 类似与pod的配置中心,不会因为pod的创建销毁,相关配置发生改变 pod定义硬编码意味着需要有效区分⽣产环境与开发过程中的pod 定义。为了能在多个环境下复⽤pod的定义,需要将配置从pod定义描 述中解耦出来。 2、向容器中…

2024年MathorCup数模竞赛C题超详细解题思路

妈妈杯本次比赛报名队伍号高达12500,这也就意味着大概一万只队伍参加报名,仅仅在报名人数这一项,妈妈杯已经成为美赛国赛之后的第三大竞赛。C题作为本次竞赛最简单也最容易获奖的题目,本文将给大家带来手把手超详细解题思路。 注…

【Git教程】(十二)工作流之项目设置 — 何时使用工作流,工作流的结构,项目设置概述、执行过程及其实现 ~

Git教程 工作流之项目设置 1️⃣ 何时使用工作流2️⃣ 工作流的结构3️⃣ 概述4️⃣ 使用要求5️⃣ 执行过程及其实现5.1 基于项目目录创建一个新的版本库5.2 以文件访问的方式共享版本库5.3 用 Git daemon 来共享版本库5.4 用 HTTP 协议来共享版本库5.5 用 SSH 协议来共享版…

KubeSphere 社区双周报|2024.03.29-04.11

KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。 本次双周报涵盖时间为:2024.03.29-04.11…

【服务器部署篇】Linux下Jenkins安装和配置

作者介绍:本人笔名姑苏老陈,从事JAVA开发工作十多年了,带过刚毕业的实习生,也带过技术团队。最近有个朋友的表弟,马上要大学毕业了,想从事JAVA开发工作,但不知道从何处入手。于是,产…

✌2024/4/1—力扣—按摩师✌

代码实现&#xff1a; 思路&#xff1a;打家劫舍题 int massage(int *nums, int numsSize) {if (nums NULL || numsSize 0) {return 0;}if (numsSize 1) {return nums[0];}int dp[numsSize];memset(dp, 0, sizeof(dp));dp[0] nums[0];dp[1] (nums[0] < nums[1] ? nums…

【网络初识】网络相关概念详解

一.局域网VS广域网 局域网 局域网:Local Area Network~简称LAN.指在某一特定区域内由多台计算机组成的互联网组。局域网内的主机之间能方便的进行网络通信&#xff0c;又称为内网.局域网和局域网之间在没有连接的情况下&#xff0c;是无法通信的。局域网的组建方式: 基于网线…

Docker 集成 redis,并在nacos进行配置时需要注意点

安装redis镜像 docker pull redis:6.0.6redis配置文件 创建相关配置文件 mkdir /apps/redis cd /apps/redis touch redis.conf vim redis.confredis.conf内容&#xff1a; #开启保护 protected-mode yes #开启远程连接 bind 0.0.0.0 #自定义密码 port 6379 timeout 0 # 900s内…

网络协议学习——以太网协议

目录 ​编辑 一&#xff0c;以太网简介 二&#xff0c;以太网通信的过程 为什么不用IP地址&#xff1f; 过程 MAC帧 MAC帧的字段介绍 ARP协议 传输过程的一些问题 RARP协议 提高效率 三&#xff0c;其他问题 ARP诈骗问题 URL解析过程 一&#xff0c;以太网简介 …

【优选算法专栏】专题十:哈希表(一)

本专栏内容为&#xff1a;算法学习专栏&#xff0c;分为优选算法专栏&#xff0c;贪心算法专栏&#xff0c;动态规划专栏以及递归&#xff0c;搜索与回溯算法专栏四部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn个人主页&#xff1a;小…

【线段树 有序映射】715. Range 模块

算法可以发掘本质&#xff0c;如&#xff1a; 一&#xff0c;若干师傅和徒弟互有好感&#xff0c;有好感的师徒可以结对学习。师傅和徒弟都只能参加一个对子。如何让对子最多。 二&#xff0c;有无限多1X2和2X1的骨牌&#xff0c;某个棋盘若干格子坏了&#xff0c;如何在没有坏…

谷歌pixel6/7pro等手机WiFi不能上网,显示网络连接受限

近期在项目中遇到一个机型出现的问题,先对项目代码进行排查,发现别的设备都能正常运行,就开始来排查机型的问题,特意写出来方便后续查看,也方便其它开发者来自查。 设备机型:Pixel 6a 设备安卓版本:13 该方法无需root,只需要电脑设备安装adb(即Android Debug Bridge…

计算机网络---第九天

以太网交换机的工作原理 以太网定义&#xff1a; 定义&#xff1a;输出标准Ethernet2类型帧的网络 以太网特征&#xff1a; 特征&#xff1a;多路访问&#xff0c;广播式的网络 mac地址: 每台设备都有一个唯一的物理地址&#xff0c;全球唯一 48位长度&#xff0c;16禁止…

数显IC/点阵数显驱动芯片/抗干扰数显驱动-VK1Q60 QFN16L 8×4点阵

产品品牌&#xff1a;永嘉微电/VINKA 产品型号&#xff1a;VK1Q60 封装形式&#xff1a;QFN16L 概述 VK1Q60是一种带键盘扫描电路接口的 LED 驱动控制专用芯片&#xff0c;内部集成有数据锁存 器、LED 驱动、键盘扫描等电路。SEG脚接LED阳极&#xff0c;GRID脚接LED阴极&…

GPT-4 Turbo with Vision 提高‮写了‬作、数学、逻‮推辑‬理和编码能力

新版 GPT-4 Turbo 今‮开天‬始现‮向已‬所有付费 ChatGPT 用‮开户‬放。GPT-4 Turbo提高‮写了‬作、数学、逻‮推辑‬理和编码能力。具有128k上下文窗口&#xff0c;可以处理超过300页的文本&#xff0c;输出‮度速‬更快。 现‮已在‬经开始‮续陆‬推送&#xff0c;如果…