比较两段代码:计算图像的灰度共生矩阵

ptsntwsz 2011-08-26 12:07:45
网上找到一段代码,其中计算(对称)灰度共生矩阵的部分如下:
	/*--------------------------------------------------------------------------
3.计算四个共生矩阵P,取距离为1,角度分别为0,45,90,135
--------------------------------------------------------------------------*/
CvMat* mat_co[4];
for (dim=0;dim<4;dim++)
{
mat_co[dim] = cvCreateMat(16,16,CV_64FC1);
cvZero(mat_co[dim]);
}

for(m=0;m<16;m++)//灰度级
{
for(n=0;n<16;n++)
{
for(j=0;j<nH;j++)//图像大小尺寸
{
for(i=0;i<nW;i++)
{
uchar temp = CV_MAT_ELEM(*mat_low_uchar,uchar,j,i);
double tempmatvalue;

if (i<(nW-1)&&temp==m&&(CV_MAT_ELEM(*mat_low_uchar,uchar,j,i+1)==n))
{
tempmatvalue = cvGetReal2D(mat_co[0],m,n);
cvSetReal2D(mat_co[0],m,n,(tempmatvalue+1.0));
cvSetReal2D(mat_co[0],n,m,(tempmatvalue+1.0));
}
if (j>0&&i<(nW-1)&&temp==m&&(CV_MAT_ELEM(*mat_low_uchar,uchar,j-1,i+1))==n)
{
tempmatvalue = cvGetReal2D(mat_co[1],m,n);
cvSetReal2D(mat_co[1],m,n,(tempmatvalue+1.0));
cvSetReal2D(mat_co[1],n,m,(tempmatvalue+1.0));
}
if (j<(nH-1)&&temp==m&&(CV_MAT_ELEM(*mat_low_uchar,uchar,j+1,i))==n)
{
tempmatvalue = cvGetReal2D(mat_co[2],m,n);
cvSetReal2D(mat_co[2],m,n,(tempmatvalue+1.0));
cvSetReal2D(mat_co[2],n,m,(tempmatvalue+1.0));
}
if (j<(nH-1)&&i<(nW-1)&&temp==m&&(CV_MAT_ELEM(*mat_low_uchar,uchar,j+1,i+1))==n)
{
tempmatvalue = cvGetReal2D(mat_co[3],m,n);
cvSetReal2D(mat_co[3],m,n,(tempmatvalue+1.0));
cvSetReal2D(mat_co[3],n,m,(tempmatvalue+1.0));
}
}
}
if(m==n)
for (dim=0;dim<4;dim++)
{
double tempmatvalue1 = cvGetReal2D(mat_co[dim],m,n);
cvSetReal2D(mat_co[dim],m,n,(tempmatvalue1*2));
}
}
}

感觉这个四层循环复杂度有点高的,运行的时候一幅图片要好几秒钟(后面还有进一步的规范化、计算熵等),而且它那个计算方法没怎么看懂,于是自己按照定义又写了一段代码:
	int delta[4][2] = {{0,1}, {-1,1}, {1,0}, {1,1}};
int p = 0;
int x, y;
for (j = 0; j < nH; j++) {
for (i = 0; i < nW; i++) {
x = CV_MAT_ELEM(*mat_low_uchar, uchar, j, i);
for (p = 0; p < 4; p++) {
if (j + delta[p][0] < nH && j + delta[p][0] >= 0 && i + delta[p][1] < nW && i + delta[p][1] >= 0) {
y = CV_MAT_ELEM(*mat_low_uchar, uchar, j + delta[p][0], i + delta[p][1]);
cvSetReal2D(mat_co[p], x, y, cvGetReal2D(mat_co[p], x, y) + 1.0);
cvSetReal2D(mat_co[p], y, x, cvGetReal2D(mat_co[p], y, x) + 1.0);
}
}
}
}

检查发现,二者得出的结果是完全一样的。
但是,运行的时候发现,似乎我的代码也需要花比较多的时间。。。没有精确比较二者的运行时间,只是感觉上都得等上3、4秒钟。
麻烦分析一下上述两段代码,比较一下优劣,还有就是说下第一段代码计算的原理,感觉没怎么明白的。
谢谢了!
...全文
310 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
guanyuechen 2012-05-24
  • 打赏
  • 举报
回复
从循环次数就可以知道,第一种思路循环了16*16*nw*nh次,第二种则只循环了nw*nh次,正如我上面说的,循环次数第一种为第二种的256倍。
正常情况下,求一张图(假设1024*1024)的GLCM也就不到0.001秒
guanyuechen 2012-05-24
  • 打赏
  • 举报
回复
一般是用第二种代码
第一种的思想是遍历共生矩阵,对于共生矩阵的每个值,都查找一遍全图,然后确定共生矩阵的值;
第二种的思路是遍历全图,对于每找到一对像素,都在共生矩阵相应的地方加上1,就像我们用“正”来计数一样。
前者的时间复杂度是后者的256倍(假设你的共生矩阵式16*16的),而且还有判断的过程,所以所耗时间是后者的256倍以上。
类似地,计算直方图,也是按第二种思路,要是用第一种,太慢了!!

4,445

社区成员

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

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