签到

06月20日
尚未签到

共有回帖数 0

    做月子

    等级:
    准备写一个高斯模糊算法
    (依靠高斯分布来进行加权,高斯分布即正态分布,创造正态分布的是德国数学家高斯,高中概率知识,要学以致用。。。。。)
    但是大餐准备留在最后,先手写了一个二次模糊(使用1/r^2来进行加权,当r = 0时,加权为1防止除0错误)
    但是存在问题…………
    我只是看了百度百科的介绍自己摸索的算法,大多数使用不同的图形库和语言(主要是JAVA),所以干脆用SDL2自己写。。。由Surface像素操作实现。。
    处理前:

    处理后,图片明显变得模糊了,模糊半径为3,但是图片发暗,可能是误差原因造成的。。。

    但是根据不同的算法的对比图来看,二次加权处理的图像像近视眼一样,看起来很晕,但是我的结果感觉和正态分布加权(高斯模糊)差不多。。。原因尚不明确。等明天问题解决了,准备出一篇教程如何进行模糊图像处理。。。。
    #includeSDL2/SDL.h
    #includeSDL2/SDL_ttf.h
    #includestdio.h
    #includestdlib.h
    #includemath.h


    const int SCREEN_WIDTH = 500;
    const int SCREEN_HEIGHT = 750;
    const int FPS = 20;
    SDL_Window * window;
    SDL_Renderer * render;
    SDL_Texture * text = NULL;


    unsigned int frame = 0;
    Uint8 quit = 0;


    /*合并surface*/
    void apply_surface(int x, int y, SDL_Surface * source, SDL_Surface * destination)
    {
    SDL_Rect offset;
    offset.x = x;
    offset.y = y;
    SDL_BlitSurface(source, NULL, destination, &offset);
    }


    /*将纹理渲染到指定位置和大小*/
    void RenderTexture_pos(SDL_Texture * tex, SDL_Renderer * ren, int x, int y,
    int w, int h)
    {
    SDL_Rect dst;
    dst.x = x;
    dst.y = y;
    dst.w = w;
    dst.h = h;
    SDL_RenderCopy(ren, tex, NULL, &dst);
    }


    /*将纹理渲染到指定坐标*/
    void RenderTexture_pos_auto(SDL_Texture * tex, SDL_Renderer * ren, int x, int y)
    {
    int w, h;
    SDL_QueryTexture(tex, NULL, NULL, &w, &h);
    RenderTexture_pos(tex, ren, x, y, w, h);
    }


    void print_sdl_error()
    {
    printf("SDL_ERROR:%sn", SDL_GetError());
    }


    /*绘制像素*/
    void set_pixel(SDL_Surface * sur, int x, int y, Uint8 r, Uint8 g, Uint8 b)
    {
    Uint32 * pixmem32;
    Uint32 color;
    color = SDL_MapRGB(sur-format, r, g, b);
    pixmem32 = (Uint32 *)(sur-pixels) + (y * sur-w) + x;
    *pixmem32 = color;
    }


    /*获得相对半径,这个并不是圆,是一个正方形
    毕竟是模糊处理,所以把一个正方形近似看作一个圆*/
    int getradius(int x, int y, int x1, int y1)
    {
    if(abs(x1 - x)  abs(y1 - y))
    {
    return abs(x1 - x);
    }
    else
    {
    return abs(y1 - y);
    }
    }


    /*获得相应的权*/
    double getwidth(int r)
    {
    if(r == 0)
    return 1;
    return 1 / (double)(2 * r * r);
    }


    /*权的综合*/
    double getwidthsum(int r)
    {
    double sum = 0;
    while(r = 0)
    {
    sum += getwidth(r);
    r--;
    }
    return sum;
    }


    /*模糊处理*/
    void gauss(SDL_Surface * sur, SDL_Surface * des, int radius)
    {
    double R1; //累计红的
    double G1; //累计lvse
    double B1; // 累计蓝色
    Uint8 R;
    Uint8 G;
    Uint8 B;
    Uint32 * pixmem32;
    int x;
    int y;
    int x1;
    int y1;
    int r; //临时处理半径
    int s = (radius + 1) * (radius + 1); //模糊半径内像素总数
    double widthsum; //权总和
    double width; //权
    for(y = 0; y  SCREEN_HEIGHT; y++)
    {
    for(x = 0; x  SCREEN_WIDTH; x++)
    {
    R1 = G1 = B1 = 0;
    y1 = y - radius;
    while(y1 = y + radius)
    {
    x1 = x - radius;
    while(x1 = x + radius)
    {
    r = getradius(x,y, x1, y1);
    width = getwidth(r);
    pixmem32 = (Uint32 *)(sur-pixels) + (y1 * sur-w) + x1;
    SDL_GetRGB(*pixmem32, sur-format, &R, &G, &B);
    /*加权累计*/
    R1 += (double)R * width;
    G1 += (double)G * width;
    B1 += (double)B * width;
    x1++;
    }
    y1++;
    }
    widthsum = getwidthsum(radius);


    /*如果RGB大于255,则以255计入*/
    if(R1 / widthsum / s = 255)
    {
    R = (Uint8)(R1 / widthsum / s);
    }
    else
    {
    R = 255;
    }


    if(G1 / widthsum / s = 255)
    {
    G = (Uint8)(G1 / widthsum / s);
    }
    else
    {
    G = 255;
    }
    if(B1 / widthsum / s = 255)
    {
    B = (Uint8)(B1 / widthsum / s);
    }
    else
    {
    B = 255;
    }
    set_pixel(des, x,y,R,G,B);
    }
    }




    }


    int show(void * data)
    {
    while(quit == 0)
    {
    SDL_SetRenderDrawColor(render, 250, 250, 250, 255);
    SDL_RenderClear(render);
    RenderTexture_pos_auto(text, render, 0,0);
    SDL_RenderPresent(render);
    frame++;
    SDL_Delay(1000 / FPS);
    }


    return 0;
    }


    void sdl_clean()
    {
    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(render);
    SDL_DestroyTexture(text);
    SDL_Quit();
    TTF_Quit();
    }


    int main(int argc, char * arg[])
    {
    SDL_Event event;


    if(SDL_Init(SDL_INIT_VIDEO) != 0 || TTF_Init() != 0)
    {
    print_sdl_error();
    }
    else
    {
    window = SDL_CreateWindow("SDL_GUI", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    SDL_CreateThread(show, "show", (void *)NULL);
    SDL_Surface * bmp = SDL_LoadBMP("h.bmp");
    SDL_Surface * sur = SDL_CreateRGBSurface(0, bmp-w, bmp-h, 32, 0,0,0,0);
    SDL_Surface * des = SDL_CreateRGBSurface(0, bmp-w, bmp-h, 32, 0,0,0,0);
    apply_surface(0,0,bmp, sur);
    gauss(sur, des, 2);
    text = SDL_CreateTextureFromSurface(render, des);
    while(quit == 0)
    {
    SDL_WaitEvent(&event);
    switch(event.type)
    {
    case SDL_QUIT:
    quit = 1;
    break;
    }
    }
    }


    sdl_clean();
    return 0;
    }

    楼主 2015-07-28 08:25 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知