Texture Synthesis

/*
Reference:
Texture synthesis by non-parametric sampling.pdf
http://en.wikipedia.org/wiki/Texture_synthesis

Potential applications: A successful texture synthesis 
algorithm's application is abroad, including occlusion fill-in,
loosy image andvideo compression, 

foreground removal, etc.
*/

//**********************************************************************
//  用EL99算法合成纹理,速度比较慢,效果还不错,适用于大多数纹理的合成
//**********************************************************************
void CTextureView::El_99()
{
	srand((unsigned)time(NULL));
	//隋机选择3X3种子
	int rx=2+rand()%(m_sSrc.cx-4);
	int ry=2+rand()%(m_sSrc.cy-4);
	BOOL up,down,left,right;
	up=down=left=right=FALSE;

	int dx,dy;
	CTextureDoc* pDoc = GetDocument();
	dx=pDoc->width;dy=pDoc->height;
	COLORREF *result=new COLORREF[dx*dy];
	memset(result,0,dx*dy*sizeof(COLORREF));

	//将种子插于到要合成的图象中
	for(int i=0;i<5;i++)
		for(int j=0;j<5;j++) result[(dy/2-2+i)*dx+dx/2-2+j]=m_cSrc[(ry-2+i)*m_sSrc.cx+rx-2+j];

	//开始合成
	int cx,cy;
	cx=dx/2;cy=dy/2;  //保存起始中心位置
	int r,k=pDoc->window;
	r=2;//当前已合成部分的半径,对合成后的块边界上的点进行合成
	while(!(up && down && left && right))
	{
		if(!up)
		{
			int tx,ty;
			ty=cy-r-1;tx=cx-r;
			tx=(tx<0)?0:tx;
			while(tx<=cx+r  && tx<dx)
			{
				COLORREF *wp=new COLORREF[k*k];
				memset(wp,0,k*k*sizeof(COLORREF));
				for(i=0;i<k;i++)
				{
					if(ty-(k/2)+i<0 || ty-(k/2)+i>dy-1) continue;
					for(int j=0;j<k;j++)
					{
						if(tx-(k/2)+j<0 || tx-(k/2)+j>dx-1) continue;
						wp[i*k+j]=result[(ty-(k/2)+i)*dx+tx-(k/2)+j];
					}
				}
				result[ty*dx+tx]=NextPixel(m_cSrc,m_sSrc,wp,k/2);
				tx++;
				delete[] wp;
			}
		}
		if(!down)
		{
			int tx,ty;
			ty=cy+r+1;tx=cx-r;
			tx=(tx<0)?0:tx;
			while(tx<=cx+r  && tx<dx)
			{
				COLORREF *wp=new COLORREF[k*k];
				memset(wp,0,k*k*sizeof(COLORREF));
				for(i=0;i<k;i++)
				{
					if(ty-(k/2)+i<0 || ty-(k/2)+i>dy-1) continue;
					for(int j=0;j<k;j++)
					{
						if(tx-(k/2)+j<0 || tx-(k/2)+j>dx-1) continue;
						wp[i*k+j]=result[(ty-(k/2)+i)*dx+tx-(k/2)+j];
					}
				}
				result[ty*dx+tx]=NextPixel(m_cSrc,m_sSrc,wp,k/2);
				tx++;
				delete[] wp;
			}
		}
		if(!left)
		{
			int tx,ty;
			ty=cy-r-1;tx=cx-r-1;
			ty=(ty<0)?0:ty;
			while(ty<=cy+r+1  && ty<dy)
			{
				COLORREF *wp=new COLORREF[k*k];
				memset(wp,0,k*k*sizeof(COLORREF));
				for(i=0;i<k;i++)
				{
					if(ty-(k/2)+i<0 || ty-(k/2)+i>dy-1) continue;
					for(int j=0;j<k;j++)
					{
						if(tx-(k/2)+j<0 || tx-(k/2)+j>dx-1) continue;
						wp[i*k+j]=result[(ty-(k/2)+i)*dx+tx-(k/2)+j];
					}
				}
				result[ty*dx+tx]=NextPixel(m_cSrc,m_sSrc,wp,k/2);
				ty++;
				delete[] wp;
			}
		}
		if(!right)
		{
			int tx,ty;
			ty=cy-r-1;tx=cx+r+1;
			ty=(ty<0)?0:ty;
			while(ty<=cy+r+1  && ty<dy)
			{
				COLORREF *wp=new COLORREF[k*k];
				memset(wp,0,k*k*sizeof(COLORREF));
				for(i=0;i<k;i++)
				{
					if(ty-(k/2)+i<0 || ty-(k/2)+i>dy-1) continue;
					for(int j=0;j<k;j++)
					{
						if(tx-(k/2)+j<0 || tx-(k/2)+j>dx-1) continue;
						wp[i*k+j]=result[(ty-(k/2)+i)*dx+tx-(k/2)+j];
					}
				}
				result[ty*dx+tx]=NextPixel(m_cSrc,m_sSrc,wp,k/2);
				ty++;
				delete[] wp;
			}
		}

		r++;

		if(cy-r-1<0) up=TRUE;
		if(cy+r+1>=dy) down=TRUE;
		if(cx-r-1<0) left=TRUE;
		if(cx+r+1>=dx) right=TRUE;

		double total=((2*r+1)*(2*r+1))*100.0/(dx*dy);
		CString str;
		str.Format("%g%% Completed!\t r=%d",total,r);
		CMainFrame* pMfm = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
		pMfm->SetStatusStr(str);
	}
	SaveToBMP("el99_result.bmp", result, dx, dy);
	m_str="el99_result.bmp";finish=TRUE;
	delete[] result;
}
//***********************************************************
//  用样本图象匹配待合成象素的邻域,以找到一个合适的匹配点
//***********************************************************
COLORREF CTextureView::NextPixel(COLORREF *sample, CSize size, COLORREF *p, int k)
{
	if(sample==NULL || p==NULL) return -1;
	int cx=size.cx;
	int cy=size.cy;
	COLORREF *tmp=new COLORREF[cx*cy*sizeof(COLORREF)];// 用来保存匹配点颜色
	//COLORREF *tmp=new COLORREF[40];
	int ok_num=0,count=0;
	double w=8.0;//阈值
repeat:
	for(int i=k;i<(cy-k);i++)
	{
		for(int j=k;j<(cx-k);j++)
		{
			count=0;
			double dif=0.0;
			for(int m=0;m<2*k+1;m++)
			{
				for(int n=0;n<2*k+1;n++)
				{
					COLORREF pc=(COLORREF)p[m*(2*k+1)+n];
					if (pc==0) continue;

					COLORREF sc=(COLORREF)sample[(i-k+m)*cx+j-k+n];
					int difr=GetRValue(sc)-GetRValue(pc);
					int difg=GetGValue(sc)-GetGValue(pc);
					int difb=GetBValue(sc)-GetBValue(pc);
					dif+=sqrt(difr*difr+difg*difg+difg*difg+0.0);
					//dif+=abs(difr)+abs(difg)+abs(difg)+0.0;

					//在此需要考虑是否与高斯内核相乘,即:dp=dssD*G
					/* 5*5
						1 2 3 2 1
						2 5 6 5 2
						3 6 8 6 3
						2 5 6 5 2			
						1 2 3 2 1													

					*/

					count++;
				}
			}

			if(count!=0) dif/=count;
			if(dif<w)
			{
				tmp[ok_num++]=sample[i*cx+j];
			}
		}
	}

	if(ok_num==0)//如果所设阈值过低,则修改阈值,重新匹配
	{
		w*=1.5;
		goto repeat;
	}

	srand((unsigned)time(NULL));
	COLORREF res=tmp[rand()%ok_num];//隋机选择结果
	delete[] tmp;
	return res;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值