共有回帖数  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 回复 
 
 
   
             
                  
                  
 
 
 
     
	 
  
	Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
	
	意见反馈 | 
	关于直线 | 
	版权声明 | 
	会员须知