Exemplo n.º 1
0
void BPFlow::FindOptimalSolutionSequential()
{
	for(size_t plane=0;plane<2;plane++)
		memset(ptrBelief[plane],0,sizeof(T_message)*nTotalBelifElements[plane]);

	for(size_t i=0;i<Height;i++)
		for(size_t j=0;j<Width;j++)
			for(size_t k=0;k<2;k++)
			{
				size_t plane;
				if(j%2==0)
					plane=k;
				else
					plane=1-k;

				size_t offset=i*Width+j;
				int nStates=pWinSize[plane][offset]*2+1;
				T_message* belief=pBelief[plane][offset].data();
				
				// add range term
				Add2Message(belief,pRangeTerm[plane][offset].data(),nStates);

				if (k==0)
					// add message from the dual layer
					Add2Message(belief,pDualMessage[plane][offset].data(),nStates);
				else
					for(int l=0;l<nStates;l++)
					{
						if(plane==0) // if the current is horizontal plane
							belief[l]+=pDataTerm[offset].data()[pX[offset*2+1]*nStates+l];
						else   // if the current is vertical plane
						{
							int nStates1=pWinSize[1-plane][offset]*2+1;
							belief[l]+=pDataTerm[offset].data()[l*nStates1+pX[offset*2]];
						}
					}

				if(j>0) // horizontal energy
					for(int l=0;l<nStates;l++)
						belief[l]+=__min((double)abs(l-pWinSize[plane][offset]+pOffset[plane][offset]-pX[(offset-1)*2+plane]+pWinSize[plane][offset-1]-pOffset[plane][offset+1])*s,d);
				if(i>0) // vertical energy
					for(int l=0;l<nStates;l++)
						belief[l]+=__min((double)abs(l-pWinSize[plane][offset]+pOffset[plane][offset]-pX[(offset-Width)*2+plane]+pWinSize[plane][offset-Width]-pOffset[plane][offset-Width])*s,d);
				if(j<Width-1)
					Add2Message(belief,pSpatialMessage[plane][offset*nNeighbors+1].data(),nStates);
				if(i<Height-1)
					Add2Message(belief,pSpatialMessage[plane][offset*nNeighbors+3].data(),nStates);

				// find the minimum
				int index=0;
				double Min=belief[0];
				for(int l=1;l<nStates;l++)
					if(Min>belief[l])
					{
						Min=belief[l];
						index=l;
					}
				pX[offset*2+plane]=index;
			}
}
Exemplo n.º 2
0
//------------------------------------------------------------------------------------------------
// compute belief
//------------------------------------------------------------------------------------------------
void BPFlow::ComputeBelief()
{
	for(size_t plane=0;plane<2;plane++)
	{
		memset(ptrBelief[plane],0,sizeof(T_message)*nTotalBelifElements[plane]);
		for(size_t i=0;i<Height;i++)
			for(size_t j=0;j<Width;j++)
			{
				size_t offset=i*Width+j;
				T_message* belief=pBelief[plane][offset].data();
				int nStates=pWinSize[plane][offset]*2+1;
				// add range term
				Add2Message(belief,pRangeTerm[plane][offset].data(),nStates);
				// add message from the dual layer
				Add2Message(belief,pDualMessage[plane][offset].data(),nStates);
				if(j>0)
					Add2Message(belief,pSpatialMessage[plane][offset*nNeighbors].data(),nStates);
				if(j<Width-1)
					Add2Message(belief,pSpatialMessage[plane][offset*nNeighbors+1].data(),nStates);
				if(i>0)
					Add2Message(belief,pSpatialMessage[plane][offset*nNeighbors+2].data(),nStates);
				if(i<Height-1)
					Add2Message(belief,pSpatialMessage[plane][offset*nNeighbors+3].data(),nStates);
			}
	}
}
Exemplo n.º 3
0
//------------------------------------------------------------------------------------------------
// compute belief
//------------------------------------------------------------------------------------------------
void BPFlow::ComputeBelief()
{
    memset(ptrBelief, 0, sizeof(T_message) * nTotalBeliefElements);

    int nStates = (WinSize * 2 + 1) * (WinSize * 2 + 1) + 1;
           
    for(int i = 0; i < Height; i++)
    {
        for (int j = 0; j < Width; j++)
        {
            int p = j + i * Width;

            if (!pMask1[p]) continue;
            
            T_message* belief = pBelief[p].data();
                 
            // add range term
            Add2Message(belief, pRangeTerm[p].data(), nStates - 1);
                
            // add data term
            Add2Message(belief, pDataTerm[p].data(), nStates - 1);

            belief[nStates - 1] += alphaD;
            
            if(j>0 && pMask1[p - 1])
                Add2Message(belief, pSpatialMessage[p * nNeighbors].data(), nStates);
            
            if(j<Width-1 && pMask1[p + 1])
                Add2Message(belief, pSpatialMessage[p * nNeighbors + 1].data(), nStates);
            
            if(i>0 && pMask1[p - Width])
                Add2Message(belief, pSpatialMessage[p * nNeighbors + 2].data(), nStates);
            
            if(i<Height-1 && pMask1[p + Width])
                Add2Message(belief, pSpatialMessage[p * nNeighbors + 3].data(), nStates);
        }
    }
}
Exemplo n.º 4
0
//------------------------------------------------------------------------------------------------
// update dual message passing from one plane to the other
//------------------------------------------------------------------------------------------------
void BPFlow::UpdateDualMessage(int x, int y, int plane)
{
	int offset=y*Width+x;
	int offset1=offset;
	int wsize=pWinSize[plane][offset];
	int nStates=wsize*2+1;
	int wsize1=pWinSize[1-plane][offset];
	int nStates1=wsize1*2+1;

	s=Im_s.data()[offset*2+plane];
	d=Im_d.data()[offset*2+plane];
	//s=m_s;
	//d=m_d;

	T_message* message_org;
	message_org=new T_message[nStates];
	//memset(message_org,0,sizeof(T_message)*nStates);
	for(int i = 0;i<nStates;i++)
		message_org[i] = 0;
	
	// add the range term
	if(!IsTRW)
		Add2Message(message_org,pRangeTerm[plane][offset].data(),nStates);
	else
		Add2Message(message_org,pRangeTerm[plane][offset].data(),nStates,CTRW);

	// add spatial messages
	if(x>0)  //add left to right
	{
		if(!IsTRW)
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors].data(),nStates);
		else
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors].data(),nStates,CTRW);
	}
	if(x<Width-1) // add right to left
	{
		if(!IsTRW)
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+1].data(),nStates);
		else
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+1].data(),nStates,CTRW);
	}
	if(y>0) // add top down
	{
		if(!IsTRW)
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+2].data(),nStates);
		else
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+2].data(),nStates,CTRW);
	}
	if(y<Height-1) // add bottom up
	{
		if(!IsTRW)
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+3].data(),nStates);
		else
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+2].data(),nStates,CTRW);
	}

	if(IsTRW)
		Add2Message(message_org,pDualMessage[plane][offset1].data(),nStates,CTRW-1);

	T_message*& message=pDualMessage[1-plane][offset1].data();

	T_message Min;
	// use the data term
	if(plane==0) // from vx plane to vy plane
		for(size_t l=0;l<nStates1;l++)
			message[l]=CStochastic::Min(nStates,pDataTerm[offset].data()+l*nStates,message_org);
	else					// from vy plane to vx plane
		for(size_t l=0;l<nStates1;l++)
		{
			Min=message_org[0]+pDataTerm[offset].data()[l];
			for(size_t h=0;h<nStates;h++)
				Min=__min(Min,message_org[h]+pDataTerm[offset].data()[h*nStates1+l]);
			message[l]=Min;
		}

	// normalize the message
	Min=CStochastic::Min(nStates1,message);
	for(size_t l=0;l<nStates1;l++)
		message[l]-=Min;

	delete message_org;
}
Exemplo n.º 5
0
//------------------------------------------------------------------------------------------------
//  update the message from (x0,y0,plane) to the neighbors on the same plane
//    the encoding of the direction
//               2  |
//                   v
//    0 ------> <------- 1
//                   ^
//                3 |
//------------------------------------------------------------------------------------------------
void BPFlow::UpdateSpatialMessage(int x, int y, int plane, int direction)
{
	// eliminate impossible messages
	if (direction==0 && x==Width-1)
		return;
	if (direction==1 && x==0)
		return;
	if (direction==2 && y==Height-1)
		return;
	if (direction==3 && y==0)
		return;

	int offset=y*Width+x;
	int nStates=pWinSize[plane][offset]*2+1;

			

	T_message* message_org;
   	message_org=new T_message[nStates];

	int x1=x,y1=y; // get the destination
	switch(direction){
		case 0:
			x1++;
			s=Im_s.data()[offset*2+plane];
			d=Im_d.data()[offset*2+plane];
			break;
		case 1:
			x1--;
			s=Im_s.data()[(offset-1)*2+plane];
			d=Im_d.data()[(offset-1)*2+plane];
			break;
		case 2:
			y1++;
			s=Im_s.data()[offset*2+plane];
			d=Im_d.data()[offset*2+plane];
			break;
		case 3:
			y1--;
			s=Im_s.data()[(offset-Width)*2+plane];
			d=Im_d.data()[(offset-Width)*2+plane];
			break;
	}
	//s=m_s;
	//d=m_d;
	int offset1=y1*Width+x1;
	int nStates1=pWinSize[plane][offset1]*2+1; // get the number of states for the destination node
	int wsize=pWinSize[plane][offset];
	int wsize1=pWinSize[plane][offset1];

	T_message*& message=pSpatialMessage[plane][offset1*nNeighbors+direction].data();

	// initialize the message from the dual plane
	if(!IsTRW)
    {
		//memcpy(message_org,pDualMessage[plane][offset].data(),sizeof(T_message)*nStates);
        for(int i = 0;i<nStates;i++)
            message_org[i] = pDualMessage[plane][offset].data()[i];
    }
	else
	{
		//memset(message_org,0,sizeof(T_message)*nStates);
        for(int i = 0;i<nStates;i++)
            message_org[i] = 0;
		Add2Message(message_org,pDualMessage[plane][offset].data(),nStates,CTRW);
	}

	// add the range term
	if(!IsTRW)
		Add2Message(message_org,pRangeTerm[plane][offset].data(),nStates);
	else
		Add2Message(message_org,pRangeTerm[plane][offset].data(),nStates,CTRW);
	
	// add spatial messages
	if(!IsTRW)
	{
		if(x>0 && direction!=1) // add left to right
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors].data(),nStates);
		if(x<Width-1 && direction!=0) // add right to left 
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+1].data(),nStates);
		if(y>0 && direction!=3) // add top down
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+2].data(),nStates);
		if(y<Height-1 && direction!=2) // add bottom up
			Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+3].data(),nStates);
	}
	else
	{
		if(x>0) // add left to right
			if(direction==1)
				Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors].data(),nStates,CTRW-1);
			else
				Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors].data(),nStates,CTRW);
		if(x<Width-1) // add right to left 
			if(direction==0)
				Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+1].data(),nStates,CTRW-1);
			else
				Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+1].data(),nStates,CTRW);
		if(y>0) // add top down
			if(direction==3)
				Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+2].data(),nStates,CTRW-1);
			else
				Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+2].data(),nStates,CTRW);
		if(y<Height-1) // add bottom up
			if(direction==2)
				Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+3].data(),nStates,CTRW-1);
			else
				Add2Message(message_org,pSpatialMessage[plane][offset*nNeighbors+3].data(),nStates,CTRW);
	}
	// use distance transform function to impose smoothness compatibility
	T_message Min=CStochastic::Min(nStates,message_org)+d;
	for(ptrdiff_t l=1;l<nStates;l++)
		message_org[l]=__min(message_org[l],message_org[l-1]+s);
	for(ptrdiff_t l=nStates-2;l>=0;l--)
		message_org[l]=__min(message_org[l],message_org[l+1]+s);


	// transform the compatibility 
	int shift=pOffset[plane][offset1]-pOffset[plane][offset];
	if(abs(shift)>wsize+wsize1) // the shift is too big that there is no overlap
	{
		if(offset>0)
			for(ptrdiff_t l=0;l<nStates1;l++)
				message[l]=l*s;
		else
			for(ptrdiff_t l=0;l<nStates1;l++)
				message[l]=-l*s;
	}
	else
	{
		int start=__max(-wsize,shift-wsize1);
		int end=__min(wsize,shift+wsize1);
		for(ptrdiff_t i=start;i<=end;i++)
			message[i-shift+wsize1]=message_org[i+wsize];
		if(start-shift+wsize1>0)
			for(ptrdiff_t i=start-shift+wsize1-1;i>=0;i--)
				message[i]=message[i+1]+s;
		if(end-shift+wsize1<nStates1)
			for(ptrdiff_t i=end-shift+wsize1+1;i<nStates1;i++)
				message[i]=message[i-1]+s;
	}

	// put back the threshold
	for(ptrdiff_t l=0;l<nStates1;l++)
		message[l]=__min(message[l],Min);

	// normalize the message by subtracting the minimum value
	Min=CStochastic::Min(nStates1,message);
	for(ptrdiff_t l=0;l<nStates1;l++)
		message[l]-=Min;

	delete message_org;
}
Exemplo n.º 6
0
//------------------------------------------------------------------------------------------------
//  update the message from (x0,y0) to the neighbors
//    the encoding of the direction
//          2  |
//             v
//    0 ------> <------- 1
//             ^
//           3 |
//------------------------------------------------------------------------------------------------
void BPFlow::UpdateSpatialMessage(int x, int y, int direction)
{
	// eliminate impossible messages
	if (direction==0 && x==Width-1) return;
    
	if (direction==1 && x==0) return;
    
	if (direction==2 && y==Height-1) return;
    
	if (direction==3 && y==0) return;

	int p = y * Width + x;
    int WinLen = 2 * WinSize + 1;
	int nStates = WinLen * WinLen + 1;

	int x1 = x, y1 = y; // get the destination
	switch(direction)
    {
    case 0:
        x1++;
        break;
    case 1:
        x1--;
        break;
    case 2:
        y1++;
        break;
    case 3:
        y1--;
        break;
	}

	int q = y1 * Width + x1;

    if (!pMask1[q]) return;
    
    // init message
	T_message*& message = pSpatialMessage[q * nNeighbors + direction].data();
	T_message* message_org;
   	message_org = new T_message[nStates];

    // msg_org = dataTerm
    memset(message_org, 0, sizeof(T_message) * nStates);
    memcpy(message_org, pDataTerm[p].data(), sizeof(T_message) * (nStates - 1));

	// add the range term
    Add2Message(message_org, pRangeTerm[p].data(), nStates - 1);

	// add spatial messages
    // add m s->p where s != q 
    if(x > 0 && direction != 1 && pMask1[x - 1 + y * Width]) // add left to right
        Add2Message(message_org, pSpatialMessage[p * nNeighbors].data(), nStates);
        
    if(x < Width - 1 && direction != 0 && pMask1[x + 1 + y * Width]) // add right to left 
        Add2Message(message_org, pSpatialMessage[p * nNeighbors + 1].data(), nStates);
        
    if(y > 0 && direction != 3 && pMask1[x + (y - 1) * Width]) // add top to down
        Add2Message(message_org, pSpatialMessage[p * nNeighbors + 2].data(), nStates);
        
    if(y < Height - 1 && direction != 2 && pMask1[x + (y + 1) * Width]) // add bottom to up
        Add2Message(message_org, pSpatialMessage[p * nNeighbors + 3].data(), nStates);

    // msg_org = h(fp)
    // calculate min h(fp), fp is not empty
    T_message Min = CStochastic::Min(nStates - 1, message_org);

    // mahatton distance transformation
    // suitable for no predict flow
    int i, j, pInWin;

///*    // forward pass
    for (i = -WinSize; i <= WinSize; i++)
    {
        for (j = -WinSize; j <= WinSize; j++)
        {
            pInWin = i + WinSize + WinLen * (j + WinSize);
            if (i - 1 >= -WinSize)
            {
                message_org[pInWin] = __min(message_org[pInWin - 1] + s, message_org[pInWin]);
            }

            if (j - 1 >= -WinSize)
            {
                message_org[pInWin] = __min(message_org[pInWin - WinLen] + s, message_org[pInWin]);
            }
        }
    }

    // backward pass
    for (i = WinSize; i >= -WinSize; i--)
    {
        for (j = WinSize; j >= -WinSize; j--)
        {
            pInWin = i + WinSize + WinLen * (j + WinSize);
            if (i + 1 <= WinSize)
            {
                message_org[pInWin] = __min(message_org[pInWin + 1] + s, message_org[pInWin]);
            }

            if (j + 1 <= WinSize)
            {
                message_org[pInWin] = __min(message_org[pInWin + WinLen] + s, message_org[pInWin]);
            }
        }
    }

    for (i = 0; i < nStates - 1; i++)
    {
        message_org[i] = __min(message_org[i], Min + d);
    }
    
    memcpy(message, message_org, sizeof(T_message) * nStates);
//*/  
/*
    // brute force method for calculating min(s * |f(p) - f(q)|, d)
    T_message tmp;
    int k, l, qInWin;
    
    for (i = 0; i < nStates; i++)
        message[i] = -1;
    
    for (i = -WinSize; i <= WinSize; i++)
    {
        for (j = -WinSize; j <= WinSize; j++)
        {
            pInWin = i + WinSize + WinLen * (j + WinSize);
            for (k = -WinSize; k <= WinSize; k++)
            {
                for (l = -WinSize; l <= WinSize; l++)
                {
                    qInWin = k + WinSize + WinLen * (l + WinSize);

                    // use manhatton distance to metric distance between fp, fq
                    // min(s * (|u(p) - u(q)| + |v(p) - v(q)|), d)
                    tmp = __min((fabs(pOffset[0][p] + i - (k + pOffset[0][q])) + fabs(pOffset[1][p] + j - (l + pOffset[1][q]))) * s, d);

                    if (message[qInWin] == -1)
                        message[qInWin] = message_org[pInWin] + tmp;
                    else
                        message[qInWin] = __min(message[qInWin], message_org[pInWin] + tmp);
                }
            }
        }
    }
*/

    T_message Max = 0;
    T_message pEmpty = message_org[nStates - 1] + alphaD + alphaV;
    message[nStates - 1] = __min(Min + alphaV, pEmpty);

    for (i = 0; i < nStates - 1; i++)
        if (Max < message[i]) Max = message[i];

    // set all pixels out of mask message as maximum value
    for (int w = -WinSize; w <= WinSize; w++)
    {
        for (int h = -WinSize; h <= WinSize; h++)
        {
            int nx = x1 + w;
            int ny = y1 + h;
            int l = w + WinSize + (h + WinSize) * WinLen;
            message[l] = __min(message[l], pEmpty + pRangeTerm[p].data()[l]);
            
            if (!InsideImage(nx, ny)) continue;

            if (!pMask2[nx + ny * Width]) message[l] = Max + s * WinLen;
        }
    }
    
	// normalize the message by subtracting the minimum value
	Min = CStochastic::Min(nStates, message);
	for(int l = 0; l < nStates; l++)
		message[l] -= Min;

	delete message_org;
}