提问人:ImDaronned 提问时间:11/2/2023 最后编辑:genpfaultImDaronned 更新时间:11/2/2023 访问量:78
使用 SDL 在 C 语言中设置 Sauvola 阈值
Sauvola thresholding in C using SDL
问:
我尝试使用局部阈值和 sauvola 算法对图像进行二值化。
我按照以下步骤操作:
- 遍历图像中的所有像素
- 计算局部均值 (μ(x, y))
- 计算局部标准差 (σ(x, y))
- 计算局部阈值 [使用此 T(x, y) = μ(x, y) * (1 + k * ((σ(x, y) / R) - 1))]
- 像素二值化
这是我的代码:
float average_neighbors(SDL_Surface* surface, int x, int y, int w, int h) {
float sum = 0.;
int count = 0;
int min_dimension = (w < h) ? w : h;
int size;
if (min_dimension < 1250)
size = 1;
else
size = 2;
for (int i = -size; i <= size; i++) {
for (int j = -size; j <= size; j++) {
int nX = x+i, nY = y+j;
if (nX >= 0 && nX < w && nY >= 0 && nY < h) {
Uint32 pixel = get_pixel(surface, nX, nY);
Uint8 pixel_color = pixel & 0xFF;
sum += pixel_color;
count++;
}
}
}
return sum/count;
}
float std_deviation(SDL_Surface* surface, int x, int y, float av) {
float sum = 0.;
int count = 0;
for (int i = y -2; i <= y +2; i++) {
//printf("i: %i\n", i);
for (int j = x -2; j <= x +2; j++) {
//printf("j: %i\n", j);
Uint8 pixel = get_pixel(surface, j, i) & 0xFF;
sum += (pixel - av) * (pixel - av);
count ++;
}
}
return sqrt(sum / count);
}
int dynamic_range(SDL_Surface* surface, int w, int h) {
int min = 255;
int max = 0;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
Uint8 color = get_pixel(surface, x, y) & 0xFF;
if (color < min)
min = color;
if (color > max)
max = color;
}
}
return max - min;
}
SDL_Surface* binarize_image(SDL_Surface* surface) {
int w = surface->w;
int h = surface->h;
float k = 0.2;
int R = dynamic_range(surface, w, h);
SDL_Surface* res = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0);
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
float av = average_neighbors(surface, x, y, w, h);
//printf("av: %f\n", av);
float deviation = std_deviation(surface, x, y, av);
//printf("dv: %f\n", deviation);
float pixel = (float)(get_pixel(surface, x, y) & 0xFF);
float sauvola_t = av * (1 + k * (deviation / R - 1));
if (pixel > sauvola_t) {
Uint32 nPixel = SDL_MapRGB(res->format, 255, 255, 255);
put_pixel(res, x, y, nPixel);
}
else {
Uint32 nPixel = SDL_MapRGB(res->format, 0, 0, 0);
put_pixel(res, x, y, nPixel);
}
}
}
free_surface(surface);
return res;
}
功能get_pixel和put_pixel正在工作。
我的函数结果在这里
我不明白我做错了什么。
当我调试时,我似乎是正确的:去泡
关于如何去做的任何想法?
答: 暂无答案
评论