【问题标题】:Get the character dominant from a string从字符串中获取占主导地位的字符
【发布时间】:2014-09-02 23:38:24
【问题描述】:

好的..根据标题,我试图找出一种方法-返回在字符串中占主导地位的字符的函数。我也许能弄清楚..但我的逻辑似乎有问题,我在这方面失败了。如果有人能毫无问题地提出这个问题,我将非常高兴,谢谢。

我说“在一个字符串中”是为了使其更加简化。我实际上是从包含 BMP 图像的缓冲数据中做到这一点的。正在尝试输出基色(主要像素)。

我现在拥有的是我开始的未完成的功能:

RGB
bitfox_get_primecolor_direct
(char *FILE_NAME)
{
    dword size = bmp_dgets(FILE_NAME, byte);
    FILE* fp = fopen(convert(FILE_NAME), "r");
    BYTE *PIX_ARRAY = malloc(size-54+1), *PIX_CUR = calloc(sizeof(RGB), sizeof(BYTE));
    dword readed, i, l;
    RGB color, prime_color;

    fseek(fp, 54, SEEK_SET); readed = fread(PIX_ARRAY, 1, size-54, fp);
    for(i = 54; i<size-54; i+=3)
    {
        color = bitfox_pixel_init(PIXEL_ARRAY[i], PIXEL_ARRAY[i+1], PIXEL_ARRAY[i+2);
        memmove(PIX_CUR, color, sizeof(RGB));
        for(l = 54; l<size-54; l+=3)
        {
            if (PIX_CUR[2] == PIXEL_ARRAY[l] && PIX_CUR[1] == PIXEL_ARRAY[l+1] && 
                PIX_CUR[0] == PIXEL_ARRAY[l+2])
                {

}

请注意,RGB 是一个包含 3 个字节(R、G 和 B)的结构。 我知道那没什么,但..这就是我现在所拥有的。 有什么办法可以完成吗?

【问题讨论】:

  • 占主导地位,你是指图像中出现频率最高的颜色吗?
  • 我会将您的 rgb 值转换为单个 32 位值,只要您保持一致,字节顺序就无关紧要,这使它们更易于比较。然后我只计算我看到每个值的次数并返回计数最多的那个。
  • @thurizas 是的。这就是我的意思。
  • @Retired Ninja 我使用的颜色配置文件不支持 32 位 bmp。它是 BMPx24 .. 怎么把我的 rgb 值转换成一个 32 位的值,这是不可能的。
  • 因此,使用 32 位中的 24 位,其余为 0。

标签: c bitmap output pixels


【解决方案1】:

如果您希望快速完成此操作,请向它扔一个 RAM 堆栈(当然,如果有的话)。您可以使用带有 RGB 三重奏的大型直接查找表将 24 位索引序列制造成连续的计数器数组。在部分伪、部分代码中,如下所示:

// create a zero-filled 2^24 array of unsigned counters.
uint32_t *counts = calloc(256*256*256, sizeof(*counts));
uint32_t max_count = 0

// enumerate your buffer of RGB values, three bytes at a time:
unsigned char rgb[3];
while (getNextRGB(src, rgb)) // returns false when no more data.
{
    uint32_t idx = (((uint32_t)rgb[0]) << 16) | (((uint32_t)rgb[1]) << 8) | (uint32_t)rgb[2];
    if (++counts[idx] > max_count)
        max_count = idx;
}

R = (max_count >> 16) & 0xFF;
G = (max_count >> 8) & 0xFF;
B = max_count & 0xFF;

// free when you have no more images to process. for each new
//  image you can memset the buffer to zero and reset the max
//  for a fresh start.
free(counts);

就是这样。如果你能负担得起在这个 a 上投入大量内存(在这种情况下为 64MB,在 16.7M 条目中每个条目 4 个字节),那么执行此操作将变为 O(N)。如果您有一系列图像要处理,您可以简单地将memset() 数组归零,清除max_count,然后对每个附加文件重复此操作。最后,完成后不要忘记释放内存。

祝你好运。

【讨论】:

  • 谢谢你,非常有趣,投票。我买得起 /64 MB/ 它之所以快是因为 shift 运算符。它比算术更快。和正则表达式数字。
  • 它很快,因为除了增量和测试之外,您不必为击球手排序任何东西,也不需要任何其他东西。为每个可能的 RGB 三重奏索引唯一计数器的能力使其工作,并且索引只是线性缓冲区的偏移量。我不相信有可能有一个更快的算法(我的实现是有问题的,一如既往,但算法是合理的),只要你有内存就可以了。
  • 哦,与我开始的相比,它肯定更快。在第一种观点上,很容易做出这样的陈述。我仍然不明白你的想法,我将如何在一个返回最常出现的像素的 RGB(作为结构)的函数中实现它。但我会再次审查它。
  • 最终像素 RGB 值在循环之后。在循环中使用 RGB 字节三重奏为查找表创建索引,然后将它们从循环后具有最高初始计数的“获胜”索引中提取出来(不考虑平局)。
  • src 参数是为了什么?它看起来没用过。
猜你喜欢
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-14
  • 2012-11-30
  • 1970-01-01
相关资源
最近更新 更多