You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言实现数独检测的Hough Transform负Rho索引问题求助

问题核心原因

  1. 角度单位不匹配:C标准库的cos()、sin()函数输入要求为弧度,你当前直接传入0-180的整数角度值,会导致三角函数计算结果完全错误,这是你得到异常负Rho值的主要诱因。
  2. Rho取值范围未做偏移处理:极坐标定义下,Rho的合法取值范围是[-max_rho, max_rho],其中max_rho为图像对角线长度,直接用原始Rho作为数组索引必然会出现负数越界问题。

具体解决方案

步骤1:修改累加器数组定义,增加偏移量

将累加器的Rho维度扩展为2 * max_rho + 1,偏移量固定为max_rho,计算得到的原始Rho值加上偏移量后,即可转换为0到2*max_rho的非负索引。

步骤2:角度转弧度后再传入三角函数计算

遍历角度时先将角度值转换为弧度,再代入Rho计算公式。

步骤3:调整Rho计算逻辑,避免类型溢出

先用浮点类型存储计算得到的原始Rho值,四舍五入后再加偏移得到最终的数组索引。

修正后的核心代码片段

#include <math.h> // 需引入数学库,编译时添加-lm参数

void hough(SDL_Surface* image_surface)
{
    unsigned int width = image_surface->w;
    unsigned int height = image_surface->h;
    
    double max_rho = sqrt(width * width + height * height);
    int rho_offset = (int)max_rho;
    int rho_size = 2 * rho_offset + 1; // 覆盖[-max_rho, max_rho]范围
    int theta_size = 180;

    // 建议用动态分配避免栈溢出,原可变长度数组兼容性差且栈空间有限
    unsigned int** acc_array = (unsigned int**)malloc(rho_size * sizeof(unsigned int*));
    for (int i = 0; i < rho_size; i++) {
        acc_array[i] = (unsigned int*)calloc(theta_size, sizeof(unsigned int));
    }

    Uint32 pixel;
    Uint8 r, g, b;

    //遍历所有像素
    for (size_t x = 0; x < width; x++)
    {
        for (size_t y = 0; y < height; y++)
        {
            pixel = get_pixel(image_surface, x, y);
            SDL_GetRGB(pixel, image_surface->format, &r, &g, &b);
                  
            //判断为白色像素
            if (r+g+b == 765)
            {
                //遍历所有角度,转弧度后计算
                for (int t = 0; t < theta_size;t++)
                {
                    double rad = t * M_PI / 180.0;
                    double raw_rho = x * cos(rad) + y * sin(rad);
                    int rho_idx = (int)round(raw_rho) + rho_offset;
                    // 做边界校验避免极端情况越界
                    if (rho_idx >=0 && rho_idx < rho_size) {
                        acc_array[rho_idx][t]++;
                    }
                }
            }
        }
    }

    // 后续逻辑处理完后记得释放动态分配的内存
    for (int i = 0; i < rho_size; i++) {
        free(acc_array[i]);
    }
    free(acc_array);
//后续代码省略...
}

额外注意点

  • 编译时需要添加-lm参数链接数学库,否则会找不到cos、sin、M_PI等定义。
  • 如果追求更高的检测精度,可以将角度步长缩小(比如0.5度一步),对应调整theta_size即可。

内容的提问来源于stack exchange,提问作者Hungry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 11:36:03