学习OpenCV:滤镜系列(5)——径向模糊:缩放&旋转

【原文:http://blog.csdn.net/yangtrees/article/details/9103935

==============================================

版权所有:小熊不去实验室CSDN博客

==============================================


原理来自:Game Render

这效果在鬼泣4中切换场景时见过, 极品飞车12的运动模糊也有这种感觉.

PS里称为 径向模糊->缩放, 还有一种 径向模糊->旋转。

缩放的原理:

确定一个中心点(如0.5, 0.5), 跟当前像素连一条线. 以当前像素为中心, 在线上的附近像素进行采样, 最后取一下平均值.

同样,旋转的原理相似,就是相同半径的一定邻域内的均值。

缩放时,半径变化,旋转时,角度变化。


使用OpenCV实现


原图:



径向模糊->缩放:



  1. #include <math.h>  
  2. #include <opencv/cv.h>  
  3. #include <opencv/highgui.h>  
  4.   
  5. using namespace cv;  
  6. using namespace std;  
  7.   
  8. int num=40;//num:均值力度;  
  9.   
  10. int main()  
  11. {  
  12.     Mat src = imread("D:/test3.jpg",1);  
  13.     Mat src1u[3];  
  14.     split(src,src1u);  
  15.   
  16.     int width=src.cols;  
  17.     int heigh=src.rows;  
  18.     Mat img;  
  19.     src.copyTo(img);  
  20.     Point center(width/2,heigh/2);  
  21.   
  22.   
  23.     for (int y=0; y<heigh; y++)  
  24.     {  
  25.           
  26.         uchar *imgP  = img.ptr<uchar>(y);  
  27.   
  28.         for (int x=0; x<width; x++)  
  29.         {  
  30.             int R = norm(Point(x,y)-center);  
  31.             double angle = atan2((double)(y-center.y),(double)(x-center.x));  
  32.   
  33.             int tmp0=0,tmp1=0,tmp2=0;  
  34.               
  35.             for (int i=0;i<num;i++)      //num:均值力度 ,i为变化幅度;  
  36.             {  
  37.                 int tmpR = (R-i)>0?(R-i):0;  
  38.                   
  39.                 int newX = tmpR*cos(angle) + center.x;  
  40.                 int newY = tmpR*sin(angle) + center.y;  
  41.                   
  42.                 if(newX<0)newX=0;  
  43.                 if(newX>width-1)newX=width-1;  
  44.                 if(newY<0)newY=0;  
  45.                 if(newY>heigh-1)newY=heigh-1;  
  46.   
  47.                 tmp0 += src1u[0].at<uchar>(newY,newX);  
  48.                 tmp1 += src1u[1].at<uchar>(newY,newX);  
  49.                 tmp2 += src1u[2].at<uchar>(newY,newX);  
  50.   
  51.             }  
  52.             imgP[3*x]=(uchar)(tmp0/num);  
  53.             imgP[3*x+1]=(uchar)(tmp1/num);  
  54.             imgP[3*x+2]=(uchar)(tmp2/num);  
  55.         }  
  56.           
  57.     }  
  58.     imshow("径向模糊",img);  
  59.     waitKey();  
  60.     imwrite("D:/径向模糊(缩放).jpg",img);  
  61. }  


径向模糊->旋转:



  1. #include <math.h>  
  2. #include <opencv/cv.h>  
  3. #include <opencv/highgui.h>  
  4.   
  5. using namespace cv;  
  6. using namespace std;  
  7.   
  8. int num=20; //均值力度;  
  9.   
  10. int main()  
  11. {  
  12.     Mat src = imread("D:/test3.jpg",1);  
  13.     Mat src1u[3];  
  14.     split(src,src1u);  
  15.   
  16.     int width=src.cols;  
  17.     int heigh=src.rows;  
  18.     Mat img;  
  19.     src.copyTo(img);  
  20.     Point center(width/2,heigh/2);  
  21.   
  22.   
  23.     for (int y=0; y<heigh; y++)  
  24.     {  
  25.   
  26.         uchar *imgP  = img.ptr<uchar>(y);  
  27.   
  28.         for (int x=0; x<width; x++)  
  29.         {  
  30.             int R = norm(Point(x,y)-center);  
  31.             double angle = atan2((double)(y-center.y),(double)(x-center.x));  
  32.   
  33.             int tmp0=0,tmp1=0,tmp2=0;  
  34.   
  35.             for (int i=0;i<num;i++)  //均值力度;  
  36.             {  
  37.   
  38.                 angle+=0.01;        //0.01控制变化频率,步长  
  39.   
  40.                 int newX = R*cos(angle) + center.x;  
  41.                 int newY = R*sin(angle) + center.y;  
  42.   
  43.                 if(newX<0)newX=0;  
  44.                 if(newX>width-1)newX=width-1;  
  45.                 if(newY<0)newY=0;  
  46.                 if(newY>heigh-1)newY=heigh-1;  
  47.   
  48.                 tmp0 += src1u[0].at<uchar>(newY,newX);  
  49.                 tmp1 += src1u[1].at<uchar>(newY,newX);  
  50.                 tmp2 += src1u[2].at<uchar>(newY,newX);  
  51.   
  52.             }  
  53.             imgP[3*x]=(uchar)(tmp0/num);  
  54.             imgP[3*x+1]=(uchar)(tmp1/num);  
  55.             imgP[3*x+2]=(uchar)(tmp2/num);  
  56.         }  
  57.   
  58.     }  
  59.     imshow("径向模糊",img);  
  60.     waitKey();  
  61.     imwrite("D:/径向模糊(旋转).jpg",img);  
  62. }  



原理Reference:

http://blog.csdn.net/xoyojank/article/details/5146297

http://bbs.9ria.com/thread-111831-1-1.html


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值