如何学习一个图像处理算法

天助自助者 2013-08-23 04:27:05
真这么难吗?或许的方法不当。

我学习图像处理算法的步骤是:先看论文或者书上的算法原理,然后下载别人写的代码,然后把代码拿来测试。按理说这个流程下来就可以掌握这个算法的应用了,可是我却困难重重,搞得我好没自信呀,又不傻又不呆,为什么我愣是没学会?

困难一: 找不到好的算法说明原理,网上的很多文章都是转的,对于算法原理基本都是简而言之;论文中总是改进的**算法,我想看最基础的最原始的那个算法呀,这个都还没懂看改进的也不会看懂呀;书上的算法原理也有些地方不明白;

困难二:看懂了算法原理,代码的实现又看不懂了,根据原理能推出哪一大段代码是什么作用,但是为什么编还是没搞懂;更可气的是看懂了的代码,运行出来却没有应有的效果,哭了,好郁闷。

昨天今天都在搞这个图像细化算法:
重点学习了 Hilditch细化算法
Hilditch 细化算法的步骤为:

对图像从左向右从上向下迭代每个像素,是为一个迭代周期。在每个迭代周期中,对于每一个像素p,如果它同时满足6个条件,则标记它。在当前迭代周期结束时,则把所有标记的像素的值设为背景值。如果某次迭代周期中不存在标记点(即满足6个条件的像素),则算法结束。假设背景值为0,前景值为1,则:

6个条件为:

(I):p 为1,即p不是背景;

(2):x1,x3,x5,x7不全部为1(否则把p标记删除,图像空心了);

(3):x1~x8 中,至少有2个为1(若只有1个为1,则是线段的端点。若没有为1的,则为孤立点);

(4):p的8连通联结数为1;

联结数指在像素p的3*3邻域中,和p连接的图形分量的个数:

image

上图中,左图的4连通联结数是2,8连通联结数是1,而右图的4联通联结数和8联通联结数都是2。





4连通联结数计算公式是:

image

8连通联结数计算公式是:

image其中,

image

至于公式怎么来的就不管了,直接用就行了。

(5)假设x3已经标记删除,那么当x3为0时,p的8联通联结数为1;

(6)假设x5已经标记删除,那么当x5为0时,p的8联通联结数为1。

/////////////////////////////////////////////////////////////////////////
//Hilditch细化算法
//功能:对图象进行细化
//参数:image:代表图象的一维数组
// lx:图象宽度
// ly:图象高度
// 无返回值
void ThinnerHilditch(void *image, unsigned long lx, unsigned long ly)
{
char *f, *g;
char n[10];
unsigned int counter;
short k, shori, xx, nrn;
unsigned long i, j;
long kk, kk11, kk12, kk13, kk21, kk22, kk23, kk31, kk32, kk33, size;
size = (long)lx * (long)ly;
g = (char *)malloc(size);

if(g == NULL)
{
printf("error in allocating memory!\n");
return;
}

f = (char *)image;
for(i=0; i<lx; i++)
{
for(j=0; j<ly; j++)
{
kk=i*ly+j;
if(f[kk]!=0)
{
f[kk]=1;
g[kk]=f[kk];
}
}
}

counter = 1;

do
{
printf("%4d*",counter);
counter++;
shori = 0;

for(i=0; i<lx; i++)
{
for(j=0; j<ly; j++)
{
kk = i*ly+j;
if(f[kk]<0)
f[kk] = 0;
g[kk]= f[kk];
}
}

for(i=1; i<lx-1; i++)
{
for(j=1; j<ly-1; j++)
{
kk=i*ly+j;

if(f[kk]!=1) //
continue;

kk11 = (i-1)*ly+j-1;
kk12 = kk11 + 1;
kk13 = kk12 + 1;
kk21 = i*ly+j-1;
kk22 = kk21 + 1;
kk23 = kk22 + 1;
kk31 = (i+1)*ly+j-1;
kk32 = kk31 + 1;
kk33 = kk32 + 1;

if((g[kk12]&&g[kk21]&&g[kk23]&&g[kk32])!=0)//不全为1
continue;

nrn = g[kk11] + g[kk12] + g[kk13] + g[kk21] + g[kk23] +
g[kk31] + g[kk32] + g[kk33];

if(nrn <= 1) //8邻域的点至少两个是1
{
f[kk22] = 2;//?标记什么
continue;
}

n[4] = f[kk11];
n[3] = f[kk12];
n[2] = f[kk13];
n[5] = f[kk21];
n[1] = f[kk23];
n[6] = f[kk31];
n[7] = f[kk32];
n[8] = f[kk33];
n[9] = n[1];//?
xx = 0;
//************************************为什么这个for循环代表8联通连接数公式*********************
for(k=1; k<8; k=k+2)
{
if((!n[k])&&(n[k+1]||n[k+2]))
xx++;
}


if(xx!=1) //p的8联通连接数是1
{
f[kk22] = 2;
continue;
}

if(f[kk12] == -1)//图像不是二值图吗 为啥f[kk12]能取到-1,取到-1 //代表该点被标记删除了吗?假设x3已经标记删除,则x3=0时,8联通连接数为1
{
f[kk12] = 0;
n[3] = 0;
xx = 0;

for(k=1; k<8; k=k+2)
{
if((!n[k])&&(n[k+1]||n[k+2]))
xx++;
}

if(xx != 1)
{
f[kk12] = -1;
continue;
}

f[kk12] = -1;
n[3] = -1;
}

if(f[kk21]!=-1)//假设x5已经标记删除,则x5=0时,8联通连接数为1
{
f[kk22] = -1;
shori = 1;
continue;
}

f[kk21] = 0;
n[5] = 0;
xx = 0;

for(k=1; k<8; k=k+2)
{
if((!n[k])&&(n[k+1]||n[k+2]))
{
xx++;
}
}

if(xx == 1)
{
f[kk21] = -1;
f[kk22] = -1;//最终p点标记为删除点
shori =1;
}
else
f[kk21] = -1;
//**********************************************
}
}
}while(shori);

free(g);
}
一个迭代周期是指一次循环吗?

更可气的是,这段代码,我测试了一个二值图像,根本运行不出效果来,但是网上的代码大部分都是这样的。

我想努力学好图像处理算法,同事我也知道自己存在很多问题,只是难于发现自己到底是哪里有问题,希望这个领域的前辈能指导一下我,多谢啦。非常勿扰啦。偶已经很伤心啦。
...全文
16816 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
change_byte 2014-12-19
  • 打赏
  • 举报
回复
我也在学图像处理,但我刚开始。你学的怎么样了?
天助自助者 2014-01-24
  • 打赏
  • 举报
回复
引用 7 楼 libralibra 的回复:
[quote=引用 6 楼 hyr731 的回复:] [quote=引用 3 楼 libralibra 的回复:] 看书,看原理,查资料/查网页找算法介绍 >>>>>>>>>>>>>>然后不要下载别人的代码<<<<<<<<<<<<<<< 对照原理与书籍资料,自己把算法实现一遍:编码/调试/优化. 这个流程下来就变成你自己的知识了. 看别人的代码一下子就晕乎了,因为同一个问题,不同的人写出来的代码也不一样,理解别人的代码远比自己实现一遍费的功夫多的多.
去哪里找原理呀 比如 Rosenfeld 细化算法 根本找不到原理介绍呀 [/quote] 没有吗?随手一个就是啊 http://cgm.cs.mcgill.ca/~godfried/student_projects/laleh_pat_rec/rosen_alg.html[/quote] 太感谢啦 ,对我帮助太大了。我已经大体明白了Rosenfeld细化原理了,正在尝试自己编个代码试试。原来是在谷歌搜 英文就可以了 ,以前老用百度+中文关键词 出来一堆没用的 ,嘿嘿 太高兴啦 。好人好运来!
libralibra 2014-01-21
  • 打赏
  • 举报
回复
引用 6 楼 hyr731 的回复:
[quote=引用 3 楼 libralibra 的回复:] 看书,看原理,查资料/查网页找算法介绍 >>>>>>>>>>>>>>然后不要下载别人的代码<<<<<<<<<<<<<<< 对照原理与书籍资料,自己把算法实现一遍:编码/调试/优化. 这个流程下来就变成你自己的知识了. 看别人的代码一下子就晕乎了,因为同一个问题,不同的人写出来的代码也不一样,理解别人的代码远比自己实现一遍费的功夫多的多.
去哪里找原理呀 比如 Rosenfeld 细化算法 根本找不到原理介绍呀 [/quote] 没有吗?随手一个就是啊 http://cgm.cs.mcgill.ca/~godfried/student_projects/laleh_pat_rec/rosen_alg.html
天助自助者 2014-01-21
  • 打赏
  • 举报
回复
引用 3 楼 libralibra 的回复:
看书,看原理,查资料/查网页找算法介绍 >>>>>>>>>>>>>>然后不要下载别人的代码<<<<<<<<<<<<<<< 对照原理与书籍资料,自己把算法实现一遍:编码/调试/优化. 这个流程下来就变成你自己的知识了. 看别人的代码一下子就晕乎了,因为同一个问题,不同的人写出来的代码也不一样,理解别人的代码远比自己实现一遍费的功夫多的多.
去哪里找原理呀 比如 Rosenfeld 细化算法 根本找不到原理介绍呀
天助自助者 2014-01-21
  • 打赏
  • 举报
回复
引用 2 楼 u012999069 的回复:
我也是硬着头皮学习。没办法。
去哪里找原理呀 比如 Rosenfeld 细化算法 根本找不到原理介绍呀
yue_pan_pan 2013-11-30
  • 打赏
  • 举报
回复
看懂了并不代表着就会了。。慢慢想,要学会自己去理解,,,
libralibra 2013-11-29
  • 打赏
  • 举报
回复
看书,看原理,查资料/查网页找算法介绍 >>>>>>>>>>>>>>然后不要下载别人的代码<<<<<<<<<<<<<<< 对照原理与书籍资料,自己把算法实现一遍:编码/调试/优化. 这个流程下来就变成你自己的知识了. 看别人的代码一下子就晕乎了,因为同一个问题,不同的人写出来的代码也不一样,理解别人的代码远比自己实现一遍费的功夫多的多.
pcblei 2013-11-29
  • 打赏
  • 举报
回复
我也是硬着头皮学习。没办法。
Fred_Yang2013 2013-09-25
  • 打赏
  • 举报
回复
同是天涯沦落人 相逢何必曾相识 只要功夫深 铁杵磨成针 成功的道路上没有捷径可以走

4,446

社区成员

发帖
与我相关
我的任务
社区描述
图形图像/机器视觉
社区管理员
  • 机器视觉
  • 迪菲赫尔曼
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧