www.pudn.com > B-spline.zip > bsplineinter.cpp, change:2012-03-20,size:6283b


#include<cv.h> 
#include<cxcore.h> 
#include<highgui.h> 
 
#include<math.h> 
#include"bsplineinter.h" 
#include"intFIFO.h" 
 
#pragma comment (lib,"cv210.lib") 
#pragma comment (lib,"cxcore210.lib") 
#pragma comment (lib,"highgui210.lib") 
 
B_SPLineInter::B_SPLineInter(int k ) 
{ 
	int tmp; 
	m_K=k; 
	tmp=(k+1)*(k+2)/2; 
	m_Niku=new float[tmp]; 
} 
 
B_SPLineInter::~B_SPLineInter() 
{ 
	delete [] m_Niku; 
} 
 
void B_SPLineInter::CalcNiku(int u) 
{ 
	int k,l; 
	float *pN; 
	float tmp1,tmp2; 
		 
	pN=m_Niku; 
	*pN=1; 
	++pN; 
	for(k=1;k<=m_K;++k) 
	{ 
		for(l=0;l<=k;++l) 
		{ 
			if(l==0) 
			{ 
				tmp1=GetNiku(0,k-1); 
				*pN=tmp1*u/k/m_Scale; 
			} 
			else if(l==k) 
			{ 
				tmp1=GetNiku(l-1,k-1); 
				*pN=tmp1*(m_Scale-u)/k/m_Scale; 
			} 
			else 
			{ 
				tmp1=GetNiku(l,k-1); 
				tmp2=GetNiku(l-1,k-1); 
				*pN=(u+l*m_Scale)*tmp1+(m_Scale*(k-l+1)-u)*tmp2; 
				*pN/=k*m_Scale; 
			} 
			//printf("l--%d,k--%d,%f\n",l,k,*pN); 
			//getchar(); 
			++pN; 
		} 
	} 
} 
 
float B_SPLineInter::GetNiku(int l,int k) 
{ 
	//索引为(l,k)----(0,0),(0,1),(1,1)... 
	if(k>m_K||l>k) 
		return 0; 
	int tmp; 
	float *p; 
	p=m_Niku; 
	tmp=k*(k+1)/2; 
	p=p+tmp; 
	return *(p+l); 
} 
 
bool B_SPLineInter::Interpolate(IplImage *imgin,IplImage *imgout,int scale)			//B样条插值,scale为放大倍数 
{ 
	int x,y,u,i,ch; 
	unsigned char *pin,*pout,*pinstart,*poutstart; 
	unsigned char *p; 
	intFIFO cpfifo(m_K+1);				//控制点队列 
	float newvalue,*pN; 
	float newvalues[CH_NUM]; 
	int tmp; 
	 
	if(scale<1) 
		return FALSE; 
	if(imgin->width*scale!=imgout->width||imgin->height*scale!=imgout->height||imgin->nChannels!=imgout->nChannels) 
	{ 
		return FALSE; 
	} 
 
	m_Scale=scale; 
	//y方向插值 
	pinstart=(unsigned char *)(imgin->imageData); 
	poutstart=(unsigned char *)(imgout->imageData); 
	for(x=0;x<imgin->width;++x) 
	{ 
		pin=pinstart; 
		pout=poutstart; 
		for(y=0;y<imgin->height;++y,pin+=imgin->widthStep) 
		{ 
			if(imgin->nChannels==1) 
			{ 
				cpfifo.pushFIFO(*pin); 
				if(y<m_K) 
				{ 
					for(u=0;u<m_Scale;++u,pout+=imgout->widthStep) 
					{ 
						//计算Niku 
						CalcNiku(u); 
						//计算插值的值 
						newvalue=0; 
						i=(y+1)*y/2; 
						pN=m_Niku+i+y; 
						for(i=y;i>=0;--i,pN--) 
						{ 
							tmp=cpfifo.ReadFIFOElement(m_K-i); 
							newvalue+=tmp**pN; 
						} 
						*pout=(int)(newvalue); 
					} 
				} 
				else 
				{ 
					for(u=0;u<m_Scale;++u,pout+=imgout->widthStep) 
					{ 
						//计算Niku 
						CalcNiku(u); 
						//计算插值的值 
						newvalue=0; 
						i=(m_K+1)*m_K/2; 
						pN=m_Niku+i+m_K; 
						for(i=0;i<=m_K;i++,pN--) 
						{ 
							tmp=cpfifo.ReadFIFOElement(i); 
							newvalue+=tmp**pN; 
							//printf("%f,",*pN); 
						} 
						*pout=(int)(newvalue); 
					} 
				} 
			} 
			else 
			{ 
				cpfifo.pushFIFO(*((int *)pin)); 
				if(y<m_K) 
				{ 
					for(u=0;u<m_Scale;++u,pout+=imgout->widthStep) 
					{ 
						//计算Niku 
						CalcNiku(u); 
						//计算插值的值 
						for(ch=0;ch<CH_NUM;++ch) 
						{ 
							newvalues[ch]=0; 
						} 
						i=(y+1)*y/2; 
						pN=m_Niku+i+y; 
						for(i=y;i>=0;--i,pN--) 
						{ 
							tmp=cpfifo.ReadFIFOElement(m_K-i); 
							p=(unsigned char *)(&tmp); 
							for(ch=0;ch<CH_NUM;++ch,++p) 
							{ 
								newvalues[ch]+=*p**pN; 
							} 
						} 
						for(ch=0;ch<CH_NUM;++ch) 
						{ 
							pout[ch]=(int)(newvalues[ch]); 
						} 
					} 
				} 
				else 
				{ 
					for(u=0;u<m_Scale;++u,pout+=imgout->widthStep) 
					{ 
						//计算Niku 
						CalcNiku(u); 
						//计算插值的值 
						for(ch=0;ch<CH_NUM;++ch) 
						{ 
							newvalues[ch]=0; 
						} 
						i=(m_K+1)*m_K/2; 
						pN=m_Niku+i+m_K; 
						for(i=0;i<=m_K;i++,pN--) 
						{ 
							tmp=cpfifo.ReadFIFOElement(i); 
							p=(unsigned char *)(&tmp); 
							for(ch=0;ch<CH_NUM;++ch,++p) 
							{ 
								newvalues[ch]+=*p**pN; 
							} 
						} 
						for(ch=0;ch<CH_NUM;++ch) 
						{ 
							pout[ch]=(int)(newvalues[ch]); 
						} 
					} 
				} 
			} 
		} 
		pinstart+=imgin->nChannels; 
		poutstart+=scale*imgout->nChannels; 
	} 
 
	//x方向插值 
	poutstart=(unsigned char *)(imgout->imageData); 
	for(y=0;y<imgout->height;++y) 
	{ 
		pout=poutstart; 
		for(x=0;x<imgin->width;++x) 
		{ 
			if(imgin->nChannels==1) 
			{ 
				cpfifo.pushFIFO(*pout); 
				if(x<m_K) 
				{ 
					for(u=0;u<m_Scale;++u,pout+=imgout->nChannels) 
					{ 
						//计算Niku 
						CalcNiku(u); 
						//计算插值的值 
						newvalue=0; 
						i=(x+1)*x/2; 
						pN=m_Niku+i+x; 
						for(i=x;i>=0;--i,pN--) 
						{ 
							tmp=cpfifo.ReadFIFOElement(m_K-i); 
							newvalue+=tmp**pN; 
						} 
						*pout=(int)(newvalue); 
					} 
				} 
				else 
				{ 
					for(u=0;u<m_Scale;++u,pout+=imgout->nChannels) 
					{ 
						//计算Niku 
						CalcNiku(u); 
						//计算插值的值 
						newvalue=0; 
						i=(m_K+1)*m_K/2; 
						pN=m_Niku+i+m_K; 
						for(i=0;i<=m_K;i++,pN--) 
						{ 
							tmp=cpfifo.ReadFIFOElement(i); 
							newvalue+=tmp**pN; 
						} 
						*pout=(int)(newvalue); 
					} 
				} 
			} 
			else 
			{ 
				cpfifo.pushFIFO(*((int *)pout)); 
				if(x<m_K) 
				{ 
					for(u=0;u<m_Scale;++u,pout+=imgout->nChannels) 
					{ 
						//计算Niku 
						CalcNiku(u); 
						//计算插值的值 
						for(ch=0;ch<CH_NUM;++ch) 
						{ 
							newvalues[ch]=0; 
						} 
						i=(x+1)*x/2; 
						pN=m_Niku+i+x; 
						for(i=x;i>=0;--i,pN--) 
						{ 
							tmp=cpfifo.ReadFIFOElement(m_K-i); 
							p=(unsigned char *)(&tmp); 
							for(ch=0;ch<CH_NUM;++ch,++p) 
							{ 
								newvalues[ch]+=*p**pN; 
							} 
						} 
						for(ch=0;ch<CH_NUM;++ch) 
						{ 
							pout[ch]=(int)(newvalues[ch]); 
						} 
					} 
				} 
				else 
				{ 
					for(u=0;u<m_Scale;++u,pout+=imgout->nChannels) 
					{ 
						//计算Niku 
						CalcNiku(u); 
						//计算插值的值 
						for(ch=0;ch<CH_NUM;++ch) 
						{ 
							newvalues[ch]=0; 
						} 
						i=(m_K+1)*m_K/2; 
						pN=m_Niku+i+m_K; 
						for(i=0;i<=m_K;i++,pN--) 
						{ 
							tmp=cpfifo.ReadFIFOElement(i); 
							p=(unsigned char *)(&tmp); 
							for(ch=0;ch<CH_NUM;++ch,++p) 
							{ 
								newvalues[ch]+=*p**pN; 
							} 
						} 
						for(ch=0;ch<CH_NUM;++ch) 
						{ 
							pout[ch]=(int)(newvalues[ch]); 
						} 
					} 
				} 
			} 
		} 
		poutstart+=imgout->widthStep; 
	} 
	 
	return TRUE; 
}