图像分割中分水岭算法的流程是什么我论文答辩要做10分钟左右的讲解,给的越多越好,谢谢

图像分割中分水岭算法的流程是什么我论文答辩要做10分钟左右的讲解,给的越多越好,谢谢,第1张

分水岭算法的概念及原理

分水岭分割方法,是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭。分水岭的概念和形成可以通过模拟浸入过程来说明。在每一个局部极小值表面,刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部极小值的影响域慢慢向外扩展,在两个集水盆汇合处构筑大坝,即形成分水岭。

分水岭的计算过程是一个迭代标注过程。分水岭比较经典的计算方法是L Vincent提出的。在该算法中,分水岭计算分两个步骤,一个是排序过程,一个是淹没过程。首先对每个像素的灰度级进行从低到高排序,然后在从低到高实现淹没过程中,对每一个局部极小值在h阶高度的影响域采用先进先出(FIFO)结构进行判断及标注。

分水岭变换得到的是输入图像的集水盆图像,集水盆之间的边界点,即为分水岭。显然,分水岭表示的是输入图像极大值点。因此,为得到图像的边缘信息,通常把梯度图像作为输入图像,即

g(x,y)=grad(f(x,y))={[f(x,y)-f(x-1,y)]2[f(x,y)-f(x,y-1)]2}05

式中,f(x,y)表示原始图像,grad{}表示梯度运算。

分水岭算法对微弱边缘具有良好的响应,图像中的噪声、物体表面细微的灰度变化,都会产生过度分割的现象。但同时应当看出,分水岭算法对微弱边缘具有良好的响应,是得到封闭连续边缘的保证的。另外,分水岭算法所得到的封闭的集水盆,为分析图像的区域特征提供了可能。

为消除分水岭算法产生的过度分割,通常可以采用两种处理方法,一是利用先验知识去除无关边缘信息。二是修改梯度函数使得集水盆只响应想要探测的目标。

为降低分水岭算法产生的过度分割,通常要对梯度函数进行修改,一个简单的方法是对梯度图像进行阈值处理,以消除灰度的微小变化产生的过度分割。即

g(x,y)=max(grad(f(x,y)),gθ)

式中,gθ表示阈值。

程序可采用方法:用阈值限制梯度图像以达到消除灰度值的微小变化产生的过度分割,获得适量的区域,再对这些区域的边缘点的灰度级进行从低到高排序,然后在从低到高实现淹没的过程,梯度图像用Sobel算子计算获得。对梯度图像进行阈值处理时,选取合适的阈值对最终分割的图像有很大影响,因此阈值的选取是图像分割效果好坏的一个关键。缺点:实际图像中可能含有微弱的边缘,灰度变化的数值差别不是特别明显,选取阈值过大可能会消去这些微弱边缘。

/1、 编程解决如下数学问题:有12升水,怎样利用一个8升和一个5升的容器将水分为两个6升?要求以如下格式打印出分水步骤。(20分)

a12 b8 c5

12 0 0

( ""表示当前状态下每个容器的盛水量)

......

6 6 0

# include <stdioh>

# include <stdlibh>

void move(int x,int y,int aMax,int bMax)

{

if(aMax>bMax)

{

if(x+y>bMax)

{

x = x-(bMax-y);

y = y+(bMax-y);

}

else

{

y = y+x;

x = x-x;//如果颠倒两个的顺序就会造成无法输出

}

}

else

{

y = y + x;

x = x - x;

}

}

main()

{

int aMax=12,bMax=8,cMax=5;

int a=12,b=0,c=0;

int i=1;

printf(" a12 b8 c5:\n");

printf("%7d%7d%7d\n",a,b,c);

while(i)

{

move(&a,&b,aMax,bMax);

printf("%7d%7d%7d\n",a,b,c);

if(a==6&&b==6)

goto step2;

move(&b,&c,bMax,cMax);

printf("%7d%7d%7d\n",a,b,c);

if(a==6&&b==6)

goto step2;

move(&c,&a,cMax,aMax);

printf("%7d%7d%7d\n",a,b,c);

if(a==6&&b==6)

goto step2;

move(&b,&c,bMax,cMax);

printf("%7d%7d%7d\n",a,b,c);

if(a==6&&b==6)

goto step2;

}

step2:

printf("the water has been sorted!\n");

return 0;

}/

/2、 编程实现:有二维数组a[3][3]={{54,32,8},{6,4,33},{7,3,13}},

将数组a的每一行元素均除以该行上的主对角元素(第1行同除以a[0][0],第2行同除以a[1][1],),

按行输出新数组。(20分)

# include <stdioh>

main()

{

double a[3][3]={{54,32,8},{6,4,33},{7,3,13}}; //可以在定义时初始化,在后来就不行了

int i,j;

for(i=0;i<3;i++)

{

for(j=0;j<3;j++)

{

if(i==j)

a[i][j]=a[i][j];

else

a[i][j]=a[i][j]/a[i][i];

}

a[i][i]=1;

}

for(i=0;i<3;i++)

{

for(j=0;j<3;j++)

printf("%62f",a[i][j]);

printf("\n");

}

}/

/3、编程:设x取值为区间[1,20]的整数,求函数f(x)=x-sin(x)- cos(x)的最大值,

要求使用自定义函数实现f(x)功能。(20分)

#include <stdioh>

#include <mathh>

double f(long double x);

main()

{

double a[50];

int i,index,j;

long double temp;

for(i=0;i<20;i++)

a[i] = f(i+1);

for(i=0;i<19;i++)

{

index = i;

for(j=i+1;j<20;j++)

if(a[j]>a[index])

index = j;

temp = a[index];

a[index] = a[i];

a[i] = temp;

}

printf("the max is %62f",a[0]);

printf("\n");

return 0;

}

double f(long double x)

{

x = x - sin(x) - cos(x); //他输入的是弧度数,而我用计算器算的是角度值,所以结果会不一样

return x;

}/

//冒泡排序

/# include <stdioh>

# include <mathh>

void swap(int x,int y);

main()

{

int i,j;

int a[50];

printf("please input the num:");

printf("\n");

for(i=0;i<10;i++)

scanf("%d",&a[i]);

for(i=1;i<10;i++)

for(j=0;j<10-i;j++)

if(a[j]>a[j+1])

swap(&a[j],&a[j+1]);

printf("after sorted the num is:");

printf("\n");

for(i=0;i<10;i++)

printf("%4d",a[i]);

printf("\n");]

return 0;

}

void swap(int x,int y)

{

int p;

p = x;

x = y;

y = p;

}

/

//选择排序

/# include <stdioh>

# include <stdlibh>

main()

{

int i,j,temp,index;

int a[50];

printf("input the num :");

printf("\n");

for(i=0;i<10;i++)

scanf("%d",&a[i]);

for(i=0;i<9;i++)

{

index = i;

for(j=i+1;j<10;j++)

{

if(a[j]<a[index])

index = j;

temp = a[index];

a[index] = a[i];

a[i] = temp;

}

}

for(i=0;i<10;i++)

printf("%4d",a[i]);

printf("\n");

return 0;

}/

/编写函反向。

要求主函数输入字符串,通过调用函数fun实数fun,通过指针实现将一个字符串现输入字符串反向。(20分)

# include<stdioh>

# include<stdlibh>

# include<stringh>

char fun(char q)

{

char temp;

int len=strlen(q);

int i;

for(i=0;len-i-1>i;i++)

{

temp = (q+i);

(q+i) = (q+len-i-1);

(q+len-i-1) = temp;

}

return q;

}

main()

{

char q;

q=(char )malloc(200sizeof(char));

printf("please input the string:\n");

scanf("%s",q);

fun(q);

printf("after reverse the string is:\n");

printf("%s\n",q);

return 0;

}/

/5、已知学生三门课程基本信息如下。请使用结构体编程,计算学生三门课程平均成绩后,

列表输出学生的姓名、数学、英语、计算机、平均分信息,并按平均分排序。(20分)

姓名 数学 英语 计算机

Mary 93 100 88

Jone 82 90 90

Peter 91 76 71

Rose 100 80 92

#include <stdioh>

#include <stdlibh>

#include <stringh>

struct student{

char name[20];

int math;

int english;

int computer;

double average;

};

main()

{

int i,j,index;

struct student a[4];

struct student temp;

strcpy(a[0]name,"mary"),a[0]math=93,a[0]english=100,a[0]computer = 88;

strcpy(a[1]name,"jone"),a[1]math=82,a[1]english=90,a[1]computer = 90;

strcpy(a[2]name,"peter"),a[2]math=91,a[2]english=76,a[2]computer = 71;

strcpy(a[3]name,"rose"),a[3]math=100,a[3]english=80,a[3]computer = 92;

for(i=0;i<4;i++)

a[i]average =(a[i]computer +a[i]english +a[i]math)/3 ;

for(i=0;i<3;i++)

{

index = i;

for(j=i;j<4;j++)

if(a[j]average <a[index]average )

index = j;

temp = a[i];

a[i] = a[index];

a[index] = temp;

}

printf("姓名 数学 英语 计算机 平均分\n");

for(i=0;i<4;i++)

{

printf("%6s%6d%6d%9d%91f",a[i]name ,a[i]math ,a[i]english ,a[i]computer ,a[i]average );

printf("\n");

}

}/

/6、附加题:编程实现输入一串英文,统计其中各单词出现的个数(不区分大小写字母),

以"000"作为字符串输入结束标志,例如:

Twinkle twinkle little star 000(回车)

twinkle little star

2 1 1 (50分)

#include<stdioh>

#include<stdlibh>

#include<stringh>

#include<ctypeh>

void main()

{

char string[400]; //装载输入的原始字符串

char temp[20][20]; //装载string中的各个子字符串

char str[20][20]; //装在string中的各个子字符串,不过不包括重复的字符串,只是把不同的字符串收录在str中

int num=0; //记录空格的个数

int order[20]; //记录各个空格的位置

int i,j,k;

int sum[20]; //记录子字符串出现的个数

int flag=0; //判断是否把子字符串输入到str中

for(i=0;i<20;i++)

memset(temp[i],'\0',20); //把那里面的元素清零,如果不清零会产生乱码

for(i=0;i<20;i++)

memset(str[i],'\0',20); //把那里面的元素清零,如果不清零会产生乱码

printf("please input the string:\n");

gets(string); //把字符串输入到字符数组string[400]中

for(i=0;string[i]!='0';i++)

string[i]=tolower(string[i]); //将字符串中的大写字母转化成小写字母

for(i=0;string[i]!='0';i++)

if(string[i]==' ')

{

order[num]=i; //记录空格的位置

num++; //空格的数目加1

}

for(i=0;i<order[0];i++)

temp[0][i]=string[i];//记录了第一个空格前的字符串,把它输入到temp[0][]中

for(j=0;j<num;j++)

for(k=0,i=order[j]+1;i<order[j+1];i++)

temp[j+1][k++] = string[i]; //将string字符串分开后存在temp中,也就是把第一个空格之后的字符串分别存放在temp中。

//第一个字符串为temp[0],第二个字符串为temp[1],往后就一次类推了

for(k=0,i=0;i<num;i++)

{

flag=0;

for(j=0;j<k;j++)

if(!strcmp(temp[i],str[j]))

{

flag=1;

break;

}

if(flag==0)

strcpy(str[k++],temp[i]);//关于他的实现举例,第一遍时temp[0]=hello,str[0]=hello;但是当temp[1]=hello时,str[1]中不会

//在存储temp的值,而是把这个忽略掉,接着往下找。

}

for(i=0;i<k;i++) //k决定了输出的字符串的个数,从而避免了相同字符串的重复输入,通过flag的变化来实现

{

sum[i]=0;

for(j=0;j<num;j++)

if(!strcmp(str[i],temp[j]))

sum[i]++;

printf("%s %d\n",str[i],sum[i]);

}

}/

以下是一段MATLAB程序,经运行没问题。有注释,有分水岭算法。

afm = imread('cameramantif');figure, imshow(afm);

se = strel('disk', 15);

Itop = imtophat(afm, se); % 高帽变换

Ibot = imbothat(afm, se); % 低帽变换

figure, imshow(Itop, []); % 高帽变换,体现原始图像的灰度峰值

figure, imshow(Ibot, []); % 低帽变换,体现原始图像的灰度谷值

Ienhance = imsubtract(imadd(Itop, afm), Ibot);% 高帽图像与低帽图像相减,增强图像

figure, imshow(Ienhance);

Iec = imcomplement(Ienhance); % 进一步增强图像

Iemin = imextendedmin(Iec, 20); figure,imshow(Iemin) % 搜索Iec中的谷值

Iimpose = imimposemin(Iec, Iemin);

wat = watershed(Iimpose); % 分水岭分割

rgb = label2rgb(wat); figure, imshow(rgb); % 用不同的颜色表示分割出的不同区域

以上就是关于图像分割中分水岭算法的流程是什么我论文答辩要做10分钟左右的讲解,给的越多越好,谢谢全部的内容,包括:图像分割中分水岭算法的流程是什么我论文答辩要做10分钟左右的讲解,给的越多越好,谢谢、怎样编程序、寻找分水岭,canny边缘检测的matlab程序~等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/10093569.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存