【发布时间】:2017-12-06 06:22:21
【问题描述】:
我正在尝试优化联合查找算法以查找图像中的连接组件。我的图像可以是 2d 或 3d 文件,由 0 和 1 组成。我在这个线程中找到了一个实现:Connected Component Labelling,用户 Dukering 给出了答案。
我根据我的目的调整了该代码。代码有效,但执行时间很快变得过长。我不明白这个问题。
我的代码如下所示。我正在测试它的文件链接在这里:https://utexas.box.com/s/k12m17rg24fw1yh1p21hytxwq5q8959u 那是一个 2223x2223 大小的文件(在下面的程序中定义)。
正如原用户所说,这是 union-find 的基本实现,可以提高效率。我不明白怎么做。另外,我在Matlab中测试过这张图,Matlab的速度要快很多。例如,上面链接的图像在我的计算机上大约需要 1.5 分钟,但 Matlab 使用 bwlabel 只需一秒钟。我检查了 bwlabel 使用的算法,它似乎是 union-find 的一些变体,这就是我首先开始这项工作的原因。如何让我的代码尽可能快地工作?我还应该提到,我希望在更大的图像(大至 1000^3)上运行我的代码。我当前的版本无法做到这一点。
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#define w 2223
#define h 2223
void writeArrayInt(int *data, int dims[], char *filename)
{
FILE *fp;
fp = fopen(filename,"w");
/* write grid dimensions */
fwrite(dims, sizeof(int), 3, fp);
/* write data array */
fwrite(data, sizeof(int), w*h, fp);
fclose(fp);
}
void readArrayInt(int *data, int dims[], char *filename)
{
FILE *fp;
fp = fopen(filename,"r");
/* read grid dimensions */
fread(dims, sizeof(int), 3, fp);
/* read data array */
fread(data, sizeof(int), w*h, fp);
fclose(fp);
}
void doUnion(int a, int b, int *component)
{
// get the root component of a and b, and set the one's parent to the other
while (component[a] != a)
a = component[a];
while (component[b] != b)
b = component[b];
component[b] = a;
}
void unionCoords(int x, int y, int x2, int y2, int *component, int *input)
{
int ind1 = x*h + y;
int ind2 = x2*h + y2;
if (y2 < h && x2 < w && input[ind1] && input[ind2] && y2 >= 0 && x2 >= 0)
doUnion(ind1, ind2, component);
}
int main()
{
int i, j;
int *input = (int *)malloc((w*h)*sizeof(int));
int *output = (int *)malloc((w*h)*sizeof(int));
int dims[3];
char fname[256];
sprintf(fname, "phi_w_bin");
readArrayInt(input, dims, fname);
int *component = (int *)malloc((w*h)*sizeof(int));
for (i = 0; i < w*h; i++)
component[i] = i;
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
{
unionCoords(x, y, x+1, y, component, input);
unionCoords(x, y, x, y+1, component, input);
unionCoords(x, y, x-1, y, component, input);
unionCoords(x, y, x, y-1, component, input);
unionCoords(x, y, x+1, y+1, component, input);
unionCoords(x, y, x-1, y+1, component, input);
unionCoords(x, y, x+1, y-1, component, input);
unionCoords(x, y, x-1, y-1, component, input);
}
for (int x = 0; x < w; x++)
{
for (int y = 0; y < h; y++)
{
int c = x*h + y;
if (input[c] == 0)
{
output[c] = input[c];
continue;
}
while (component[c] != c) c = component[c];
int c1 = x*h + y;
output[c1] = component[c];
}
}
sprintf(fname, "outputImage2d");
writeArrayInt(output, dims, fname);
free(input);
free(output);
free(component);
}
【问题讨论】:
-
如果您的代码正在运行并且您希望获得有关如何提高其性能的建议,那么Code Review 是这个问题的更合适的地方。
-
请缩进您的代码。如果你使用 tab 键缩进,现在是时候去寻找如何告诉你的 IDE 插入空格了......
-
您的缩进确实需要帮助:修复它会帮助您获得帮助。