我有随机颜色发生器。正如你在照片中看到的,它会随机生成一种颜色(R - 红色,G - 绿色,Y - 黄色)。
我需要找到占据最大空间的颜色。但有一个条件。我可以算出那个颜色最大的空间,它有很多相同的邻居。我不知道怎么说,英语不是我的主要语言。
例如,RGYRGYRGRGRGRGRGR红色不会占据最大的空间,因为它彼此分开。但是RRRRRRRRGYGYG很好,因为所有的R颜色都在附近。
我该怎么办?起初我认为我需要使用广度优先搜索算法。但是我的教授说我可以“扫描”行或列。所以我不知道该怎么做。哪种方式最简单?
答案 0 :(得分:5)
您是否正在寻找相邻同色元素的最大斑点?在这种情况下,与https://en.wikipedia.org/wiki/Flood_fill相反的东西可能是最简单的。从每个位置开始,看看在到达边界之前可以走多远。您之前已经添加的地点" fill"不需要再次检查。
答案 1 :(得分:2)
有connected-component labeling个算法,它们旨在解决此类问题 Wiki页面主要用于二进制大小写,但也存在用于从多色图片中提取blob的算法实现。
答案 2 :(得分:0)
这是我几个月前写的一个用C编写的算法,如果我有时间,我会转换成C#。
#include <stdio.h>
int find_root(int index, int *roots) {
// index = i * height + j
if (roots[index] == index) return index;
else {
int root = find_root(roots[index], roots);
roots[index] = root;
return root;
}
}
void process(char matrix[], long width, long height) {
long number_of_pixels = height * width;
int *roots = (int *)malloc(number_of_pixels * sizeof(int));
// roots[width * i + j] points the root of area where i, j belongs to
int *connectivities = (int *)malloc(number_of_pixels * sizeof(int));
// connectivities explain:
// 1 -> isolated,
// 0 -> non-isolated, non-root,
// >1 -> non-isolated, root
// only consider left and upper sides!!!
const int connects[2][2] = {
{-1, 0},
{0, -1}
};
for (long i = 0; i < number_of_pixels; ++i) {
roots[i] = i;
connectivities[i] = 1;
}
for (long i = 0; i < height; ++i) {
for (long j = 0; j < width; ++j) {
for (int k = 0; k < 2; ++k) {
long neighbor_j = j + connects[k][0];
long neighbor_i = i + connects[k][1];
if (neighbor_j >= 0 && neighbor_j < width
&& neighbor_i >= 0 && neighbor_i < height
&& matrix[width * neighbor_i + neighbor_j] == matrix[width * i + j]) {
// join it to neighbor group
long root = find_root(i * width + j, roots);
long neighbor_root
= find_root(width * neighbor_i + neighbor_j, roots);
if (root == neighbor_root) continue;
roots[root] = neighbor_root;
connectivities[neighbor_root] += connectivities[root];
connectivities[root] = 0;
}
}
}
}
// Now we gonna print the root of area each point belongs to
for (long i = 0; i < height; ++i) {
for (long j = 0; j < width; ++j) {
long index = i * width + j;
printf("%3d", find_root(index, roots));
}
printf("\n");
}
// Now we gonna print the space of area each point belongs to
for (long i = 0; i < height; ++i) {
for (long j = 0; j < width; ++j) {
long index = i * width + j;
printf("%3d", connectivities[find_root(index, roots)]);
}
printf("\n");
}
free(connectivities);
free(roots);
}
int main() {
char mat[] = "YYYYYYYYYRGYRGYRGRGRGRGRGR"
"YYYYYYYYYRGYRGYRGRGRGRGRGR"
"YYYYYYYYRGYRGYRGRGRGRGRGRY";
int width = 26;
int height = 3;
for (long i = 0; i < height; ++i) {
for (long j = 0; j < width; ++j) {
long index = i * width + j;
printf(" %c", mat[index]);
}
printf("\n");
}
process(mat, width, height);
}
输出结果为:
Y Y Y Y Y Y Y Y Y R G Y R G Y R G R G R G R G R G R
Y Y Y Y Y Y Y Y Y R G Y R G Y R G R G R G R G R G R
Y Y Y Y Y Y Y Y R G Y R G Y R G R G R G R G R G R Y
0 0 0 0 0 0 0 0 0 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
0 0 0 0 0 0 0 0 0 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
0 0 0 0 0 0 0 0 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
26 26 26 26 26 26 26 26 26 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
26 26 26 26 26 26 26 26 26 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
26 26 26 26 26 26 26 26 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
基本上,它会将空间节省到连接数组中。此算法只需要扫描一次。