运动模糊

#include"stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include "cv.h"
#include "highgui.h"

using namespace std;
using namespace cv;

IplImage * oimage, * nimage;
int Distance,angle;
int Iscale;
double scale;
void MoveImage(IplImage * src,IplImage * dstimage,double scale)
{
	int x,y,newx,newy;
	int radius,distance;
	int a,b;
	int x0,y0;
	x0 = src->width/2;
	y0 = src->height/2;
	//以图像中心为基点
	uchar * p;
	int bpos,gpos,rpos,count;
	for(y = 0; y < src->height; y++)
		for(x = 0; x < src->width; x++)
		{
			if(x0 > x)
			{a = (x0 - x);}
			else
			{a = (x - x0);}
			if(y0 > y)
			{b = (y0 -y);}
			else{
			b = (y -y0);}
			radius =(int) sqrt( (double)(a*a + b*b) );
			distance = radius * scale;
			bpos = gpos = rpos = count = 0;
			
			if(a > b)
			{
				for(int i = 0;i < distance; i++)
				{
					if(x < x0)
					{
						newx = x + i;
					}else 
					{
						newx = x - i;
					}
					if(y < y0)
					{newy = y + i*b/a;}
					else{
						newy = y - i*b/a;}

					if(  newy >= y0*2 || newx <  0 || newx > 2*x0 || newy < 0)
						break;
					count++;
					p = (uchar*) (src->imageData + newy*src->widthStep + newx*src->nChannels);
					bpos += p[0];
					gpos += p[1];
					rpos += p[2];
				}
				
				p = (uchar*) (dstimage->imageData + y*dstimage->widthStep + x*dstimage->nChannels);
				if(count != 0)
				{
				p[0] = bpos / count;
				p[1] = gpos / count;
				p[2] = rpos / count;
				}
				else
				{
				p[0] = *(src->imageData + y*src->widthStep + x*src->nChannels + 0);
				p[1] = *(src->imageData + y*src->widthStep + x*src->nChannels + 1);
				p[2] = *(src->imageData + y*src->widthStep + x*src->nChannels + 2);
				}
			}
			else
			{
					for(int i = 0;i < distance; i++)
				{
					if(y < y0)
					{	newy = y + i;}
					else{
						newy = y - i;}
					if(x < x0){
						newx = x + i*a/b;}
					else{
						newx = x - i*a/b;}

				if(newy >= y0*2 || newx <  0 || newx > 2*x0 || newy < 0)
						break;
					count++;
					p = (uchar*) (src->imageData + newy*src->widthStep + newx*src->nChannels);
					bpos += p[0];
					gpos += p[1];
					rpos += p[2];
				}
				
				p = (uchar*) (dstimage->imageData + y*dstimage->widthStep + x*dstimage->nChannels);
				if(count != 0)
				{
				p[0] = bpos / count;
				p[1] = gpos / count;
				p[2] = rpos / count;
				}
				else
				{
				p[0] = *(src->imageData + y*src->widthStep + x*src->nChannels + 0);
				p[1] = *(src->imageData + y*src->widthStep + x*src->nChannels + 1);
				p[2] = *(src->imageData + y*src->widthStep + x*src->nChannels + 2);
				}
			}
		}




		
}
void MoveImage(IplImage * src,IplImage * dstimage)//让花开得更灿烂
{
	int x,y,newx,newy,channel;
	int sumb,sumg,sumr;
	uchar * p = 0;
	for(y = 0; y < dstimage->height; y++)
		for(x = 0; x < dstimage->width; x++)
			{
				newx = x;
				newy = y;
				sumb = sumg = sumr = 0;

				for(int i = 0;i <= Distance; i++)
				{
					double f = (double)i / Distance;
					scale = 1 - scale*f;
					newx = x + i*cos((double)angle);
					newx = newx*scale + dstimage->width*0.5*(1.0-scale);
					newy = y + i*sin((double)angle);
					newy = newy*scale + dstimage->height*0.5*(1.0-scale);
					
					if(newx < 0 || newx >= src->width || newy < 0 || newy >= src->height)
					{
						break;
					}
										
					p = (uchar*) (src->imageData + newy*src->widthStep + newx*src->nChannels);
					sumb += (int)p[0];
					sumg += (int)p[1];
					sumr += (int)p[2];
				}
				sumb = sumb / (Distance+1);
				sumg = sumg / (Distance+1);
				sumr = sumr / (Distance+1);
				if(sumb < 0)
				{sumb = 0;}
				else if(sumb > 255)
				{
					sumb = 255;
				}
				if(sumg < 0)
				{sumg = 0;}
				else if(sumg > 255)
				{
					sumg = 255;
				}
				if(sumr < 0)
				{sumr = 0;}
				else if(sumr > 255)
				{
					sumr = 255;
				}
				p = (uchar*) (dstimage->imageData + y*dstimage->widthStep + x*dstimage->nChannels);
				p[0] = sumb;
				p[1] = sumg;
				p[2] = sumr;
			}
}
void onTrackerSlid1(int pos)
{
		MoveImage(oimage,nimage);
	cvShowImage("new",nimage);
}
void onTrackerSlid(int pos)
{  
	
	MoveImage(oimage,nimage);
	cvShowImage("new",nimage);
}
void onTrackerSlid2(int pos)
{  
	scale = (double)(pos) / 10.0;
	if(scale < 0.0001 )
	{	scale = 0.0001;}
	MoveImage(oimage,nimage);
	cvShowImage("new",nimage);
}
void onTrackerSlid3(int pos)
{  
	double scale = (double)(pos) / 10.0;

	MoveImage(oimage,nimage,scale);
	cvShowImage("F",nimage);
}
int main()
{
	
	oimage= cvLoadImage("G:\\360data\\重要数据\\桌面\\常用标准图\\follow.jpg");	//读入测试图片
	nimage = cvCreateImage(cvGetSize(oimage),oimage->depth,oimage->nChannels);	//开辟数据
	
	Distance = 1;	//初始值
	angle = 0;
	Iscale = 4;
	cvNamedWindow("old",1);
	cvNamedWindow("new",1);
	cvNamedWindow("F",1);

	cvShowImage("old",oimage);
	
	cvCreateTrackbar("dis","new",&Distance,60,onTrackerSlid);	//创建滑块
	cvCreateTrackbar("angle","new",&angle,360,onTrackerSlid1);	//创建滑块
	cvCreateTrackbar("Iscale","new",&Iscale,20,onTrackerSlid2);	//创建滑块
	onTrackerSlid2(Iscale);
 	onTrackerSlid1(angle);
	onTrackerSlid(Distance);

	int SCALE = 4;
	cvCreateTrackbar("SCALE","F",&SCALE,100,onTrackerSlid3);	//创建滑块
	onTrackerSlid3(SCALE);
	
	cvWaitKey();
	cvDestroyWindow("old");
	cvDestroyWindow("new");
	cvReleaseImage(&oimage);
	cvReleaseImage(&nimage);

	return -1;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值