Beispiel #1
0
void BPFlow::FindOptimalSolution()
{
    int WinLen = WinSize * 2 + 1;
    int nStates = WinLen * WinLen;

    for(int p = 0; p < Area; p++)
    {
        if (!pMask1[p]) continue;
        
        T_message* belief = pBelief[p].data();

        int index = nStates;
        double Min = belief[index];
        int x = p % Width;
        int y = p / Width;
        
        for (int i = 0; i < nStates; i++)
        {
            int fx = i % WinLen - WinSize;
            int fy = i / WinLen - WinSize;

            int nx = x + fx;
            int ny = y + fy;
            if (!InsideImage(nx,ny)) continue;

            // inside the image but not in the mask
            if (!pMask2[nx + ny * Width]) continue;
            
            if (Min > belief[i])
            {
                Min = belief[i];
                index = i;
            }
        }
        
        pX[p] = index;
    }
}
Beispiel #2
0
//------------------------------------------------------------------------------------------------
// function to compute data term
//------------------------------------------------------------------------------------------------
void BPFlow::ComputeDataTerm()
{
	// allocate the buffer for data term
	nTotalMatches=AllocateBuffer<PixelBuffer2D<T_message>,T_message>(pDataTerm,ptrDataTerm,pWinSize[0],pWinSize[1]);

	T_message HistMin,HistMax;
	double HistInterval;
	double* pHistogramBuffer;
	int nBins=20000;
	int total=0; // total is the total number of plausible matches, used to normalize the histogram
	pHistogramBuffer=new double[nBins];
	memset(pHistogramBuffer,0,sizeof(double)*nBins);
	HistMin= 32767;
	HistMax=0;
	//--------------------------------------------------------------------------------------------------
	// step 1. the first sweep to compute the data term for the visible matches
	//--------------------------------------------------------------------------------------------------
	for(ptrdiff_t i=0;i<Height;i++)			// index over y
		for(ptrdiff_t j=0;j<Width;j++)		// index over x
		{
			size_t index=i*Width+j;
			int XWinLength=pWinSize[0][index]*2+1;
			// loop over a local window
			for(ptrdiff_t k=-pWinSize[1][index];k<=pWinSize[1][index];k++)  // index over y
				for(ptrdiff_t l=-pWinSize[0][index];l<=pWinSize[0][index];l++)  // index over x
				{
					ptrdiff_t x=j+pOffset[0][index]+l;
					ptrdiff_t y=i+pOffset[1][index]+k;

					// if the point is outside the image boundary then continue
					if(!InsideImage(x,y))
						continue;
					ptrdiff_t index2=y*Width2+x;
					T_message foo=0;
					for(int n=0;n<nChannels;n++)
						foo+=abs(pIm1[index*nChannels+n]-pIm2[index2*nChannels+n]); // L1 norm
//#ifdef INTMESSAGE
//						foo+=abs(pIm1[index*nChannels+n]-pIm2[index2*nChannels+n]); // L1 norm
//#else
//						foo+=fabs(pIm1[index*nChannels+n]-pIm2[index2*nChannels+n]); // L1 norm
//#endif
						
					
					pDataTerm[index][(k+pWinSize[1][index])*XWinLength+l+pWinSize[0][index]]=foo;
					HistMin=__min(HistMin,foo);
					HistMax=__max(HistMax,foo);
					total++;
				}
		}
	// compute the histogram info
	HistInterval=(double)(HistMax-HistMin)/nBins;
	//HistInterval/=21;

	//--------------------------------------------------------------------------------------------------
	// step 2. get the histogram of the matching
	//--------------------------------------------------------------------------------------------------
	for(ptrdiff_t i=0;i<Height;i++)			// index over y
		for(ptrdiff_t j=0;j<Width;j++)		// index over x
		{
			size_t index=i*Width+j;
			int XWinLength=pWinSize[0][index]*2+1;
			// loop over a local window
			for(ptrdiff_t k=-pWinSize[1][index];k<=pWinSize[1][index];k++)  // index over y
				for(ptrdiff_t l=-pWinSize[0][index];l<=pWinSize[0][index];l++)  // index over x
				{
					ptrdiff_t x=j+pOffset[0][index]+l;
					ptrdiff_t y=i+pOffset[1][index]+k;

					// if the point is outside the image boundary then continue
					if(!InsideImage(x,y))
						continue;
					int foo=__min(pDataTerm[index][(k+pWinSize[1][index])*XWinLength+l+pWinSize[0][index]]/HistInterval,nBins-1);
					pHistogramBuffer[foo]++;
				}
		}
	for(size_t i=0;i<nBins;i++) // normalize the histogram
		pHistogramBuffer[i]/=total;

	T_message DefaultMatchingScore;
	double Prob=0;
	for(size_t i=0;i<nBins;i++)
	{
		Prob+=pHistogramBuffer[i];
		if(Prob>=0.5)//(double)Area/nTotalMatches) // find the matching score
		{
			DefaultMatchingScore=__max(i,1)*HistInterval+HistMin; 
			break;
		}
	}
	//DefaultMatchingScore=__min(100*DefaultMatchingScore,HistMax/10);
	if(IsDisplay)
#ifdef INTMESSAGE
		printf("Min: %d, Default: %d, Max: %d\n",HistMin,DefaultMatchingScore,HistMax);
#else
		printf("Min: %f, Default: %f, Max: %f\n",HistMin,DefaultMatchingScore,HistMax);
#endif

	//DefaultMatchingScore=0.1;
	//--------------------------------------------------------------------------------------------------
	// step 3. assigning the default matching score to the outside matches
	//--------------------------------------------------------------------------------------------------
	for(ptrdiff_t i=0;i<Height;i++)			// index over y
		for(ptrdiff_t j=0;j<Width;j++)		// index over x
		{
			size_t index=i*Width+j;
			int XWinLength=pWinSize[0][index]*2+1;
			// loop over a local window
			for(ptrdiff_t k=-pWinSize[1][index];k<=pWinSize[1][index];k++)  // index over y
				for(ptrdiff_t l=-pWinSize[0][index];l<=pWinSize[0][index];l++)  // index over x
				{
					ptrdiff_t x=j+pOffset[0][index]+l;
					ptrdiff_t y=i+pOffset[1][index]+k;

                    int _ptr=(k+pWinSize[1][index])*XWinLength+l+pWinSize[0][index];
					// if the point is outside the image boundary then continue
					if(!InsideImage(x,y))
						pDataTerm[index][_ptr]=DefaultMatchingScore;
                     else if (IsDataTermTruncated) // put truncaitons to the data term
                        pDataTerm[index][_ptr]=__min(pDataTerm[index][_ptr],DefaultMatchingScore);
				}
		}
	delete pHistogramBuffer;
}
Beispiel #3
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;
}