int table_printf(BlockInfo* pRoot) { MY_PRINTF("\n"); if (pRoot == NULL) return 0; BlockInfo* pCur = pRoot; int count = 0; for (; pCur != NULL; pCur = element_child(pCur)) { MY_PRINTF("+%2x(%3lx) ", element_key(pCur), element_size(pCur)); count++; } MY_PRINTF("\n"); count += table_printf(element_sibling(pRoot)); return count; }
element* table_remove(BlockInfo* pRoot, BlockInfo* pBlock) { MY_PRINTF(" table remove\n"); element* pCur = pRoot; MY_ASSERT(table_search(pRoot, element_size(pBlock)) != NULL); if (pCur == pBlock) { //pCur->child //pSib if (element_child(pCur)) { element* pSib = element_sibling(pCur); pCur = element_child(pCur); element_sibling(pCur) = pSib; } else { pCur = element_sibling(pCur); } } else if (element_size(pCur) == element_size(pBlock)) { MY_ASSERT(pCur != pBlock); MY_ASSERT(element_child(pCur) != NULL); element_child(pCur) = child_remove(element_child(pCur), pBlock); } else if (element_size(pCur) < element_size(pBlock)) { MY_ASSERT(element_sibling(pCur) != NULL); element_sibling(pCur) = table_remove(element_sibling(pCur), pBlock); } else { MY_ASSERT(element_size(pCur) > element_size(pBlock)); MY_ASSERT(0); } return pCur; };
/* * Use an inline function here just to test '__textcoal_nt' sections on darwin. */ inline int MyDisasm(uintptr_t CodeIndex, PDISCPUSTATE pCpu, uint32_t *pcb) { uint32_t cb; int rc = DISInstrWithReader(CodeIndex, DISCPUMODE_32BIT, DisasmTest1ReadCode, 0, pCpu, &cb); *pcb = cb; MY_PRINTF(("DISCoreOneEx -> rc=%d cb=%d Cpu: bOpCode=%#x pCurInstr=%p (42=%d)\n", \ rc, cb, pCpu->bOpCode, pCpu->pCurInstr, 42)); \ return rc; }
extern "C" DECLEXPORT(int) DisasmTest1(void) { DISCPUSTATE Cpu; uintptr_t CodeIndex = 0; uint32_t cb; int rc; MY_PRINTF(("DisasmTest1: %p\n", &DisasmTest1)); memset(&Cpu, 0, sizeof(Cpu)); #define DISAS_AND_CHECK(cbInstr, enmOp) \ do { \ rc = MyDisasm(CodeIndex, &Cpu, &cb); \ if (RT_FAILURE(rc)) \ return CodeIndex | 0xf000; \ if (Cpu.pCurInstr->uOpcode != (enmOp)) \ return CodeIndex| 0xe000; \ if (cb != (cbInstr)) \ return CodeIndex | 0xd000; \ CodeIndex += cb; \ } while (0) DISAS_AND_CHECK(1, OP_PUSH); DISAS_AND_CHECK(2, OP_MOV); DISAS_AND_CHECK(3, OP_MOV); DISAS_AND_CHECK(6, OP_CMP); DISAS_AND_CHECK(2, OP_JNE); DISAS_AND_CHECK(3, OP_MOV); DISAS_AND_CHECK(4, OP_CMP); DISAS_AND_CHECK(2, OP_JNE); DISAS_AND_CHECK(5, OP_MOV); DISAS_AND_CHECK(2, OP_JMP); DISAS_AND_CHECK(2, OP_XOR); DISAS_AND_CHECK(2, OP_JNE); DISAS_AND_CHECK(3, OP_MOV); DISAS_AND_CHECK(1, OP_PUSH); DISAS_AND_CHECK(3, OP_MOV); DISAS_AND_CHECK(3, OP_MOV); DISAS_AND_CHECK(3, OP_CALL); DISAS_AND_CHECK(3, OP_ADD); DISAS_AND_CHECK(1, OP_POP); DISAS_AND_CHECK(1, OP_RETN); DISAS_AND_CHECK(1, OP_INT3); return rc; }
element* child_remove(BlockInfo* pFirst, BlockInfo* pBlock) { MY_PRINTF(" child remove %p %lx %p %lx\n", pFirst, element_size(pFirst), pBlock, element_size(pBlock)); BlockInfo* pPrev = NULL; BlockInfo* pCur; for (pCur = pFirst; pCur != NULL; pCur = element_child(pCur)) { if (pCur == pBlock) { break; } pPrev = pCur; } MY_ASSERT(pCur != NULL); if (pPrev != NULL) { MY_ASSERT(pBlock != pFirst); element_child(pPrev) = element_child(pCur); return pFirst; } MY_ASSERT(pBlock == pFirst); return element_child(pCur); }
void reconstruct_video(nTupleVolume<T>* imgVol, nTupleVolume<T>* occVol, nTupleVolume<T>* dispField, float sigmaColour, int useAllPatches, int reconstructionType) { /*decalarations*/ int xSize, ySize, tSize, nTupleSize; //img Size int i,j,k; //3-D index int iMin,iMax,jMin,jMax,kMin,kMax; //Boundary of index Volume int ii,jj,kk, weightInd; int xDisp, yDisp, tDisp,xDispShift,yDispShift,tDispShift; int shiftI,shiftJ,shiftK; int hPatchSizeX,hPatchSizeY,hPatchSizeT; //half patchsize int hI,hJ,hK,doubleII,doubleJJ,doubleKK; int nbNeighbours; int correctInfo; float alpha, adaptiveSigma; float *weights,sumWeights, avgColourR, avgColourG, avgColourB, *colours; /*get image volume sizes*/ xSize = imgVol->xSize; ySize = imgVol->ySize; tSize = imgVol->tSize; nTupleSize = imgVol->nTupleSize; hPatchSizeX = imgVol->hPatchSizeX; //half patchsize hPatchSizeY = imgVol->hPatchSizeY; hPatchSizeT = imgVol->hPatchSizeT; /*allocate the (maximum) memory for the weights*/ nbNeighbours = (imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT); //number of neighbor weights = (float*)malloc((size_t)(nbNeighbours*sizeof(float))); colours = (float*)malloc((size_t)(NCHANNELS*nbNeighbours*sizeof(float))); /*check certain parameters*/ if( (imgVol->patchSizeX != (imgVol->patchSizeX)) || (imgVol->patchSizeY != (imgVol->patchSizeY)) || (imgVol->patchSizeT != (imgVol->patchSizeT)) ) /*check that the patch sizes are equal*/ //what is this for? { MY_PRINTF("Error in estimate_colour, the size of the patches are not equal in the two image volumes."); return; } if ( ( imgVol->patchSizeX > imgVol->xSize) || ( imgVol->patchSizeY > imgVol->ySize) || ( imgVol->patchSizeT > imgVol->tSize) ) /*check that the patch size is less or equal to each dimension in the images*/ { MY_PRINTF("Error in estimate_colour, the patch size is to large for one or more of the dimensions of the image volume."); return; } for (k=0; k<(occVol->tSize); k++) //run all over occVolume, t dimension for (j=0; j<(occVol->ySize); j++) // y dimension for (i=0; i<(occVol->xSize); i++)//x dimension { if ( ((occVol->get_value(i,j,k,0)) == 0) || ((occVol->get_value(i,j,k,0) == 2) ) ) //do not inpaint continue; else /*an occluded pixel (therefore to be modified)*/ { if (reconstructionType == NEAREST_NEIGHBOUR_RECONSTRUCTION ) //nearest neighbor reconstruction { xDisp = i + (int)dispField->get_value(i,j,k,0); // x Displacement yDisp = j + (int)dispField->get_value(i,j,k,1); // y Displacement tDisp = k + (int)dispField->get_value(i,j,k,2); // t displacement ////if pure replacing of pixels copy_pixel_values_nTuple_volume(imgVol, imgVol,xDisp, yDisp, tDisp, i, j, k); //copy pixel value of ANN to occluded pixel. ///set_value_nTuple_volume(occVol,i,j,k,2,0); ///set_value_nTuple_volume(imgVol,i,j,k,0,0); continue; } // init array weight and colours for (ii=0;ii<(imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT); ii++) //all the pixel in a patch { weights[ii] = (float)-1; //weight for all pixel in patch colours[ii] = (float)-1; //red colours[ii + nbNeighbours] = (float)-1;//green chanel colours[ii + 2*nbNeighbours] = (float)-1; //blue chanel } sumWeights = 0.0; alpha = FLT_MAX; correctInfo = 0; avgColourR = 0.0; avgColourG = 0.0; avgColourB = 0.0; //boudary for each patch iMin = max_int(i - hPatchSizeX,0); iMax = min_int(i + hPatchSizeX,(imgVol->xSize)-1 ); jMin = max_int(j - hPatchSizeY,0); jMax = min_int(j + hPatchSizeY,(imgVol->ySize)-1 ); kMin = max_int(k - hPatchSizeT,0); kMax = min_int(k + hPatchSizeT,(imgVol->tSize)-1 ); /* MY_PRINTF("iMin : %d, iMax : %d\n",iMin,iMax); MY_PRINTF("jMin : %d, jMax : %d\n",jMin,jMax); MY_PRINTF("kMin : %d, kMax : %d\n",kMin,kMax);*/ /*first calculate the weights*/ //run for each patch, calculate the spatial temporal neighbor of the patch for (kk=kMin; kk<=kMax;kk++) //t dimension for (jj=jMin; jj<=jMax;jj++)//y dimension for (ii=iMin; ii<=iMax;ii++) //x dimension { /*get ssd similarity*/ xDisp = ii + (int)dispField->get_value(ii,jj,kk,0); //get value dispX for pixel in the patch yDisp = jj + (int)dispField->get_value(ii,jj,kk,1); tDisp = kk + (int)dispField->get_value(ii,jj,kk,2); /*(spatio-temporally) shifted values of the covering patches*/ xDispShift = xDisp - (ii-i); //i + dispField (dispField for pixel (ii,jj,kk)) yDispShift = yDisp - (jj-j); tDispShift = tDisp - (kk-k); if (useAllPatches == 1) // if use all patches { alpha = (float)min_float(dispField->get_value(ii,jj,kk,3),alpha); //get min SSD and assign to alpha //transform matrice indice to array indice. weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = dispField->get_value(ii,jj,kk,3); //weight is an array, SSD error of patch //colours is an array colours[weightInd] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,0)); //red colours[weightInd + nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,1));//green colours[weightInd + 2*nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,2)); //blue correctInfo = 1; } else /*only use some of the patches*/ { if (((occVol->get_value(ii,jj,kk,0)) == 0) || (occVol->get_value(ii,jj,kk,0) ==-1)) { alpha = (float)min_float(dispField->get_value(ii,jj,kk,3),alpha); weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = dispField->get_value(ii,jj,kk,3); colours[weightInd] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,0)); colours[weightInd + nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,1)); colours[weightInd + 2*nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,2)); correctInfo = 1; } else { weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = -1; colours[weightInd] = -1; colours[weightInd + nbNeighbours] = -1; colours[weightInd + 2*nbNeighbours] = -1; continue; } } } alpha = max_float(alpha,1); if (correctInfo == 0) continue; if (reconstructionType == BEST_PATCH_RECONSTRUCTION) { estimate_best_colour(imgVol,imgVol, weights, nbNeighbours, colours, sigmaColour, i, j, k); continue; } //get the 75th percentile of the distances for setting the adaptive sigma adaptiveSigma = get_adaptive_sigma(weights,(imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT),sigmaColour); adaptiveSigma = max_float(adaptiveSigma,(float)0.1); /* ///MY_PRINTF("alpha : %f\n",alpha); //adjust the weights : note, the indices which are outside the image boundaries //will have no influence on the final weights (they are initialised to 0) */ for (kk=kMin; kk<=kMax;kk++) for (jj=jMin; jj<=jMax;jj++) for (ii=iMin; ii<=iMax;ii++) { if (useAllPatches) { /*weights = exp( -weights/(2*sigma�*alpha))*/ weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = (float)(exp( - ((weights[weightInd])/(2*adaptiveSigma*adaptiveSigma)) ));/*exp( - ((weights[ii])/(2*sigmaColour*sigmaColour*alpha)) );*/ // sumWeights = (float)(sumWeights+weights[weightInd]); } else /*only use some of the patches*/ { if (((occVol->get_value(ii,jj,kk,0)) == 0) || (occVol->get_value(ii,jj,kk,0) ==-1)) { /*weights = exp( -weights/(2*sigma�*alpha))*/ weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = (float)(exp( - ((weights[weightInd])/(2*adaptiveSigma*adaptiveSigma)) ));/*exp( - ((weights[ii])/(2*sigmaColour*sigmaColour*alpha)) );*/ // sumWeights = (float)(sumWeights+weights[weightInd]); } else continue; } } /*now calculate the pixel value(s)*/ for (kk=kMin; kk<=kMax;kk++) for (jj=jMin; jj<=jMax;jj++) for (ii=iMin; ii<=iMax;ii++) { if (useAllPatches) { weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); /*get ssd similarity*/ xDisp = ii + (int)dispField->get_value(ii,jj,kk,0); yDisp = jj + (int)dispField->get_value(ii,jj,kk,1); tDisp = kk + (int)dispField->get_value(ii,jj,kk,2); /*(spatio-temporally) shifted values of the covering patches*/ xDispShift = xDisp - (ii-i); yDispShift = yDisp - (jj-j); tDispShift = tDisp - (kk-k); avgColourR = avgColourR + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,0)); avgColourG = avgColourG + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,1)); avgColourB = avgColourB + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,2)); } else { if (((occVol->get_value(ii,jj,kk,0)) == 0) || (occVol->get_value(ii,jj,kk,0) ==-1)) { weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); /*get ssd similarity*/ xDisp = ii + (int)dispField->get_value(ii,jj,kk,0); yDisp = jj + (int)dispField->get_value(ii,jj,kk,1); tDisp = kk + (int)dispField->get_value(ii,jj,kk,2); /*(spatio-temporally) shifted values of the covering patches*/ xDispShift = xDisp - (ii-i); yDispShift = yDisp - (jj-j); tDispShift = tDisp - (kk-k); avgColourR = avgColourR + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,0)); avgColourG = avgColourG + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,1)); avgColourB = avgColourB + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,2)); } else continue; } } /*MY_PRINTF("SumWeights : %f\n",sumWeights);*/ imgVol->set_value(i,j,k,0,(T)(avgColourR/(sumWeights))); imgVol->set_value(i,j,k,1,(T)(avgColourG/(sumWeights))); imgVol->set_value(i,j,k,2,(T)(avgColourB/(sumWeights))); /*set_value_nTuple_volume(occVol,i,j,k,0,0);*/ } } free(weights); free(colours); return; }
/*this function calculates a nearest neighbour field, from imgVolA to imgVolB*/ void reconstruct_image_and_features(nTupleVolume* imgVol, nTupleVolume* occVol, nTupleVolume *normGradXvol, nTupleVolume *normGradYvol, nTupleVolume* dispField, float sigmaColour, int reconstructionType, bool initialisation) { int useAllPatches = 0; if (initialisation==true) useAllPatches = 0; else useAllPatches = 1; /*decalarations*/ int iMin,iMax,jMin,jMax,kMin,kMax; int weightInd; int xDisp, yDisp, tDisp,xDispShift,yDispShift,tDispShift; int hPatchSizeX,hPatchSizeY,hPatchSizeT; int nbNeighbours; int correctInfo; float alpha, adaptiveSigma; float *weights,sumWeights, *colours, *avgColours; float avgNormGradX,avgNormGradY; hPatchSizeX = imgVol->hPatchSizeX; hPatchSizeY = imgVol->hPatchSizeY; hPatchSizeT = imgVol->hPatchSizeT; /*allocate the (maximum) memory for the weights*/ nbNeighbours = (imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT); weights = new float[nbNeighbours]; colours = new float[(imgVol->nTupleSize)*nbNeighbours]; avgColours = new float[imgVol->nTupleSize]; /*check certain parameters*/ if( (imgVol->patchSizeX != (imgVol->patchSizeX)) || (imgVol->patchSizeY != (imgVol->patchSizeY)) || (imgVol->patchSizeT != (imgVol->patchSizeT)) ) /*check that the patch sizes are equal*/ { MY_PRINTF("Error in estimate_colour, the size of the patches are not equal in the two image volumes."); return; } if ( ( imgVol->patchSizeX > imgVol->xSize) || ( imgVol->patchSizeY > imgVol->ySize) || ( imgVol->patchSizeT > imgVol->tSize) ) /*check that the patch size is less or equal to each dimension in the images*/ { MY_PRINTF("Error in estimate_colour, the patch size is to large for one or more of the dimensions of the image volume."); return; } for (int k=0; k<(occVol->tSize); k++) for (int j=0; j<(occVol->ySize); j++) for (int i=0; i<(occVol->xSize); i++) { if ( ((occVol->get_value(i,j,k,0)) == 0) || ((occVol->get_value(i,j,k,0) == 2) ) ) continue; else /*an occluded pixel (therefore to be modified)*/ { if (reconstructionType == 1 ) { xDisp = i + (int)dispField->get_value(i,j,k,0); yDisp = j + (int)dispField->get_value(i,j,k,1); tDisp = k + (int)dispField->get_value(i,j,k,2); ////if pure replacing of pixels copy_pixel_values_nTuple_volume(imgVol, imgVol,xDisp, yDisp, tDisp, i, j, k); ///set_value_nTuple_volume(occVol,i,j,k,2,0); ///set_value_nTuple_volume(imgVol,i,j,k,0,0); continue; } //initialisation of the weight and colour vectors for (int ii=0;ii<(imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT); ii++) { weights[ii] = (float)-1; for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++) { colours[ii + colourInd*nbNeighbours] = (float)-1; } } for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++) { avgColours[colourInd] = (float)0.0; } sumWeights = 0.0; alpha = FLT_MAX; correctInfo = 0; avgNormGradX = 0.0; avgNormGradY = 0.0; iMin = max_int(i - hPatchSizeX,0); iMax = min_int(i + hPatchSizeX,(imgVol->xSize)-1 ); jMin = max_int(j - hPatchSizeY,0); jMax = min_int(j + hPatchSizeY,(imgVol->ySize)-1 ); kMin = max_int(k - hPatchSizeT,0); kMax = min_int(k + hPatchSizeT,(imgVol->tSize)-1 ); /* MY_PRINTF("iMin : %d, iMax : %d\n",iMin,iMax); MY_PRINTF("jMin : %d, jMax : %d\n",jMin,jMax); MY_PRINTF("kMin : %d, kMax : %d\n",kMin,kMax);*/ /*first calculate the weights*/ for (int kk=kMin; kk<=kMax;kk++) for (int jj=jMin; jj<=jMax;jj++) for (int ii=iMin; ii<=iMax;ii++) { /*get ssd similarity*/ xDisp = ii + (int)dispField->get_value(ii,jj,kk,0); yDisp = jj + (int)dispField->get_value(ii,jj,kk,1); tDisp = kk + (int)dispField->get_value(ii,jj,kk,2); /*(spatio-temporally) shifted values of the covering patches*/ xDispShift = xDisp - (ii-i); yDispShift = yDisp - (jj-j); tDispShift = tDisp - (kk-k); if (useAllPatches == 1) { alpha = (float)min_float(dispField->get_value(ii,jj,kk,3),alpha); weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = dispField->get_value(ii,jj,kk,3); for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++) { colours[weightInd + colourInd*nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,colourInd)); } correctInfo = 1; } else /*only use some of the patches*/ { if ((occVol->get_value(ii,jj,kk,0)) == 0) { alpha = (float)min_float(dispField->get_value(ii,jj,kk,3),alpha); weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = dispField->get_value(ii,jj,kk,3); for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++) { colours[weightInd + colourInd*nbNeighbours] = (float)(imgVol->get_value(xDispShift,yDispShift,tDispShift,colourInd)); } correctInfo = 1; } else { weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = -1; for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++) { colours[weightInd + colourInd*nbNeighbours] = (float)-1; } continue; } } } alpha = max_float(alpha,1); if (correctInfo == 0) continue; if (reconstructionType == 3) { estimate_best_colour(imgVol, weights, nbNeighbours, colours, i, j, k); continue; } //get the 75th percentile of the distances for setting the adaptive sigma adaptiveSigma = get_adaptive_sigma(weights,(imgVol->patchSizeX)*(imgVol->patchSizeY)*(imgVol->patchSizeT),sigmaColour); adaptiveSigma = max_float(adaptiveSigma,(float)0.1); /* ///MY_PRINTF("alpha : %f\n",alpha); //adjust the weights : note, the indices which are outside the image boundaries //will have no influence on the final weights (they are initialised to 0) */ for (int kk=kMin; kk<=kMax;kk++) for (int jj=jMin; jj<=jMax;jj++) for (int ii=iMin; ii<=iMax;ii++) { if (useAllPatches) { /*weights = exp( -weights/(2*sigma*alpha))*/ weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = (float)(exp( - ((weights[weightInd])/(2*adaptiveSigma*adaptiveSigma)) ));/*exp( - ((weights[ii])/(2*sigmaColour*sigmaColour*alpha)) );*/ // sumWeights = (float)(sumWeights+weights[weightInd]); } else /*only use some of the patches*/ { if ((occVol->get_value(ii,jj,kk,0)) == 0) { /*weights = exp( -weights/(2*sigma*alpha))*/ weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); weights[weightInd] = (float)(exp( - ((weights[weightInd])/(2*adaptiveSigma*adaptiveSigma)) ));/*exp( - ((weights[ii])/(2*sigmaColour*sigmaColour*alpha)) );*/ // sumWeights = (float)(sumWeights+weights[weightInd]); } else continue; } } /*now calculate the pixel value(s)*/ for (int kk=kMin; kk<=kMax;kk++) for (int jj=jMin; jj<=jMax;jj++) for (int ii=iMin; ii<=iMax;ii++) { if (useAllPatches) { weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); /*get ssd similarity*/ xDisp = ii + (int)dispField->get_value(ii,jj,kk,0); yDisp = jj + (int)dispField->get_value(ii,jj,kk,1); tDisp = kk + (int)dispField->get_value(ii,jj,kk,2); /*(spatio-temporally) shifted values of the covering patches*/ xDispShift = xDisp - (ii-i); yDispShift = yDisp - (jj-j); tDispShift = tDisp - (kk-k); for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++) { avgColours[colourInd] = avgColours[colourInd] + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,colourInd)); } avgNormGradX = avgNormGradX + (float)(weights[weightInd])*(normGradXvol->get_value(xDispShift,yDispShift,tDispShift,0)); avgNormGradY = avgNormGradY + (float)(weights[weightInd])*(normGradYvol->get_value(xDispShift,yDispShift,tDispShift,0)); } else { if ((occVol->get_value(ii,jj,kk,0)) == 0) { weightInd = (int)((kk-kMin)*(imgVol->patchSizeX)*(imgVol->patchSizeY) + (jj-jMin)*(imgVol->patchSizeX) + ii-iMin); /*get ssd similarity*/ xDisp = ii + (int)dispField->get_value(ii,jj,kk,0); yDisp = jj + (int)dispField->get_value(ii,jj,kk,1); tDisp = kk + (int)dispField->get_value(ii,jj,kk,2); /*(spatio-temporally) shifted values of the covering patches*/ xDispShift = xDisp - (ii-i); yDispShift = yDisp - (jj-j); tDispShift = tDisp - (kk-k); for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++) { avgColours[colourInd] = avgColours[colourInd] + (float)(weights[weightInd])*(imgVol->get_value(xDispShift,yDispShift,tDispShift,colourInd)); } avgNormGradX = avgNormGradX + (float)(weights[weightInd])*(normGradXvol->get_value(xDispShift,yDispShift,tDispShift,0)); avgNormGradY = avgNormGradY + (float)(weights[weightInd])*(normGradYvol->get_value(xDispShift,yDispShift,tDispShift,0)); } else continue; } } /*MY_PRINTF("SumWeights : %f\n",sumWeights);*/ for (int colourInd=0; colourInd<(imgVol->nTupleSize); colourInd++) { imgVol->set_value(i,j,k,colourInd,(imageDataType)((avgColours[colourInd])/(sumWeights))); } normGradXvol->set_value(i,j,k,0,(imageDataType)(avgNormGradX/(sumWeights))); normGradYvol->set_value(i,j,k,0,(imageDataType)(avgNormGradY/(sumWeights))); /*set_value_nTuple_volume(occVol,i,j,k,0,0);*/ } } delete weights; delete colours; delete avgColours; return; }
nTupleVolume * inpaint_image( nTupleVolume *imgVolIn, nTupleVolume *occVolIn, patchMatchParameterStruct *patchMatchParams, inpaintingParameterStruct *inpaintingParams) { // ******************************************************************** // // **** AUTOMATICALLY DETERMINE NUMBER OF LEVELS, IF NOT SPECIFIED **** // // ******************************************************************** // if (inpaintingParams->nLevels == -1) { inpaintingParams->nLevels = determine_multiscale_level_number(occVolIn,imgVolIn->patchSizeX,imgVolIn->patchSizeY); } display_inpainting_parameters(inpaintingParams); display_patch_match_parameters(patchMatchParams); nTupleVolume *imgVolOut; // ************************** // // **** CREATE PYRDAMIDS **** // // ************************** // nTupleVolumePyramid imgVolPyramid = create_nTupleVolume_pyramid(imgVolIn, inpaintingParams->nLevels); nTupleVolumePyramid occVolPyramid = create_nTupleVolume_pyramid_binary(occVolIn, inpaintingParams->nLevels); featurePyramid featuresVolPyramid; if (inpaintingParams->useFeatures == true) { double t1 = clock(); featuresVolPyramid = create_feature_pyramid(imgVolIn, occVolIn, inpaintingParams->nLevels); MY_PRINTF("\n\nFeatures calculation time: %f\n",((double)(clock()-t1)) / CLOCKS_PER_SEC); } else { featuresVolPyramid.normGradX = NULL; featuresVolPyramid.normGradY = NULL; featuresVolPyramid.nLevels = -1; } //create structuring element nTupleVolume *structElDilate = create_structuring_element("rectangle", imgVolIn->patchSizeX, imgVolIn->patchSizeY); //show_patch_match_parameters(patchMatchParams); // ****************************************** // // ************* START INPAINTING *********** // // ****************************************** // nTupleVolume *imgVol,*normGradXvol,*normGradYvol; nTupleVolume *shiftVol=NULL; for (int level=( (inpaintingParams->nLevels)-1); level>=0; level--) { printf("Current pyramid level : %d\n",level); nTupleVolume *imgVolPrevious,*occVol,*occVolDilate; if (patchMatchParams->maxShiftDistance != -1) patchMatchParams->maxShiftDistance = (float)( (patchMatchParams->maxShiftDistance)/( pow((float)SUBSAMPLE_FACTOR,(float)level) )); imgVol = copy_image_nTuple(imgVolPyramid[level]); occVol = copy_image_nTuple(occVolPyramid[level]); //create dilated occlusion occVolDilate = imdilate(occVol, structElDilate); if (featuresVolPyramid.nLevels >= 0) { normGradXvol = copy_image_nTuple((featuresVolPyramid.normGradX)[level]); normGradYvol = copy_image_nTuple((featuresVolPyramid.normGradY)[level]); //attach features to patchMatch parameters patchMatchParams->normGradX = normGradXvol; patchMatchParams->normGradY = normGradYvol; } //initialise solution if (level == ((inpaintingParams->nLevels)-1)) { shiftVol = new nTupleVolume(4,imgVol->xSize,imgVol->ySize,imgVol->patchSizeX,imgVol->patchSizeY,IMAGE_INDEXING); shiftVol->set_all_image_values(0); printf("\nInitialisation started\n\n\n"); initialise_inpainting(imgVol,occVol,featuresVolPyramid,shiftVol,patchMatchParams); patchMatchParams->partialComparison = 0; printf("\nInitialisation finished\n\n\n"); if (featuresVolPyramid.nLevels >= 0) //retrieve features from the pointers in the patchMatch parameters { normGradXvol = patchMatchParams->normGradX; normGradYvol = patchMatchParams->normGradY; } } else //reconstruct current solution { if (featuresVolPyramid.nLevels >= 0) { reconstruct_image_and_features(imgVol, occVol, normGradXvol, normGradYvol, shiftVol, SIGMA_COLOUR); } else { reconstruct_image(imgVol,occVol,shiftVol,SIGMA_COLOUR); //write_shift_map(shiftVol,fileOut); } } calclulate_patch_distances(imgVol,imgVol,shiftVol,occVolDilate,patchMatchParams); //iterate ANN search and reconstruction int iterationNb = 0; imageDataType residual = FLT_MAX; while( (residual > (inpaintingParams->residualThreshold) ) && (iterationNb < (inpaintingParams->maxIterations) ) ) { //copy current imgVol imgVolPrevious = copy_image_nTuple(imgVol); patch_match_ANN(imgVol,imgVol,shiftVol,occVolDilate,occVolDilate,patchMatchParams); if (featuresVolPyramid.nLevels >= 0) { reconstruct_image_and_features(imgVol, occVol, normGradXvol, normGradYvol, shiftVol, SIGMA_COLOUR); } else reconstruct_image(imgVol,occVol,shiftVol,SIGMA_COLOUR); residual = calculate_residual(imgVol,imgVolPrevious,occVol); if (patchMatchParams->verboseMode == true) printf("Iteration number %d, residual = %f\n",iterationNb,residual); iterationNb++; } //upsample shift volume, if we are not on the finest level if (level >0) { nTupleVolume * shiftVolTemp = up_sample_image(shiftVol, SUBSAMPLE_FACTOR,imgVolPyramid[level-1]); delete(shiftVol); shiftVol = copy_image_nTuple(shiftVolTemp); shiftVol->multiply((imageDataType)SUBSAMPLE_FACTOR); delete(shiftVolTemp); } else { reconstruct_image(imgVol,occVol,shiftVol,SIGMA_COLOUR,3); imgVolOut = new nTupleVolume(imgVol); } //destroy structures delete(imgVol); delete(imgVolPrevious); delete(occVol); delete(occVolDilate); if (featuresVolPyramid.nLevels >= 0) { delete normGradXvol; delete normGradYvol; } } // ************************** // // **** DELETE STRUCTURES *** // // ************************** // for (int i=0; i< (inpaintingParams->nLevels); i++) { delete(imgVolPyramid[i]); delete(occVolPyramid[i]); } delete(imgVolPyramid); delete(occVolPyramid); delete(shiftVol); delete_feature_pyramid(featuresVolPyramid); delete(patchMatchParams); printf("Inpainting finished !\n"); return(imgVolOut); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { nTupleVolume<float> *imgVol, *occVol, *gradXvol, *gradYvol, *normGradXvol, *normGradYvol, *dispField; int * imgVolSizes, *dispFieldSizes; float sigmaColour; float *dispFieldTemp; int numDimsImgVol, numDimsDispField; int useAllPatches, reconstructionType; parameterStruct *patchMatchParams; mwSize resultSize[4]; if (nrhs < (SIGMA_COLOUR_INPUT+1)) { mexErrMsgTxt("Error. A minimum of 10 parameters are needed in the spatio-temporal patch match mexfunction.\n"); return; } ASSERT ( (mxGetClassID(prhs[IMG_VOL_INPUT]) == mxSINGLE_CLASS) & (mxGetClassID(prhs[OCC_VOL_INPUT]) == mxSINGLE_CLASS) & (mxGetClassID(prhs[DISP_FIELD_INPUT]) == mxSINGLE_CLASS)); /* Get sizes of variables*/ imgVolSizes = (int*)mxGetDimensions(prhs[IMG_VOL_INPUT]); /* sizes of imgVol*/ numDimsImgVol = (int)mxGetNumberOfDimensions(prhs[IMG_VOL_INPUT]); /*length of sizes of imgVolA*/ dispFieldSizes = (int*)mxGetDimensions(prhs[DISP_FIELD_INPUT]); /*sizes of imgVolB*/ numDimsDispField = (int)mxGetNumberOfDimensions(prhs[DISP_FIELD_INPUT]); /* length of sizes of dispField*/ if ((numDimsImgVol != 4) || (numDimsDispField != 4)) { mexPrintf("Number of dimensions :\n imgVol : %d\nimgVolFine : %d\nDispField : %d\n",numDimsImgVol,numDimsDispField); mexErrMsgTxt("Error, the number of array dimensions must be 4 (x,y,t,multivalue)."); plhs[0] = mxCreateNumericMatrix((mwSize)1,(mwSize)1, mxINT32_CLASS, (mxComplexity)0); dispFieldTemp = (float*)mxGetPr(plhs[0]); *dispFieldTemp = -1; return; } //get the patchMatch parameters ASSERT(mxIsStruct(prhs[PATCH_MATCH_PARAMS_INPUT]) ); patchMatchParams = (parameterStruct*)new parameterStruct; parse_patch_match_parameters(prhs[PATCH_MATCH_PARAMS_INPUT],patchMatchParams); /* sigma colour*/ sigmaColour = (float)(*mxGetPr(prhs[SIGMA_COLOUR_INPUT])); if ( (imgVolSizes[2] < patchMatchParams->patchSizeX) || (imgVolSizes[1] < patchMatchParams->patchSizeY) || (imgVolSizes[3] < patchMatchParams->patchSizeT) ) { MY_PRINTF("Image sizes :\n x : %d, y : %d, t : %d\n",(int)imgVolSizes[2],(int)imgVolSizes[1],(int)imgVolSizes[3]); MY_PRINTF("Patch sizes :\n x : %d, y : %d, t : %d\n",(int)patchMatchParams->patchSizeX,(int)patchMatchParams->patchSizeY,(int)patchMatchParams->patchSizeT); mexErrMsgTxt("Error, the patch sizes are too large for the image."); plhs[0] = mxCreateNumericMatrix((mwSize)1,(mwSize)1, mxINT32_CLASS, (mxComplexity)0); dispFieldTemp = (float*)mxGetPr(plhs[0]); *dispFieldTemp = -1; return; } if (nrhs >= (USE_ALL_PATCHES_INPUT+1)) useAllPatches = (int)(*mxGetPr(prhs[USE_ALL_PATCHES_INPUT])); /* if we want to use all surrounding patches or not*/ else useAllPatches = 1; if (nrhs >= (RECONSTRUCTION_TYPE_INPUT+1)) reconstructionType = (int)(*mxGetPr(prhs[RECONSTRUCTION_TYPE_INPUT])); /* the manner in which we want to reconstruct the image*/ else reconstructionType = 0; int imageIndexing = 1; //input image volumes imgVol = new nTupleVolume<float>(3, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3], patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing, (float*)mxGetPr(prhs[IMG_VOL_INPUT])); occVol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3], patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing, (float*)mxGetPr(prhs[OCC_VOL_INPUT])); //shift volume dispField = new nTupleVolume<float>(4, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3], patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing, (float*)mxGetPr(prhs[DISP_FIELD_INPUT])); //features gradXvol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3], patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing, (float*)patchMatchParams->gradX); gradYvol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3], patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing, (float*)patchMatchParams->gradY); normGradXvol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3], patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing, (float*)patchMatchParams->normGradX); normGradYvol = new nTupleVolume<float>(1, (int)imgVolSizes[2], (int)imgVolSizes[1], (int)imgVolSizes[3], patchMatchParams->patchSizeX, patchMatchParams->patchSizeY, patchMatchParams->patchSizeT,imageIndexing, (float*)patchMatchParams->normGradY); /*colour estimation*/ reconstruct_videos(imgVol, occVol, gradXvol, gradYvol, normGradXvol, normGradYvol, dispField, (float)sigmaColour, useAllPatches, reconstructionType); /*OUTPUT*/ /* Create output matrix*/ resultSize[0] = (int)(imgVolSizes[0]); resultSize[1] = (int)(imgVolSizes[1]); resultSize[2] = (int)(imgVolSizes[2]); resultSize[3] = (int)(imgVolSizes[3]); plhs[0] = mxCreateNumericArray((mwSize)4,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0); float *imgVolOutTemp = (float*)mxGetPr(plhs[0]); memcpy(imgVolOutTemp,imgVol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*resultSize[3]*sizeof(float)); //create other output matrices resultSize[0] = (int)(imgVolSizes[1]); resultSize[1] = (int)(imgVolSizes[2]); resultSize[2] = (int)(imgVolSizes[3]); plhs[1] = mxCreateNumericArray((mwSize)3,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0); float* gradXoutTemp = (float*)mxGetPr(plhs[1]); memcpy(gradXoutTemp,gradXvol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*sizeof(float)); plhs[2] = mxCreateNumericArray((mwSize)3,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0); float* gradYoutTemp = (float*)mxGetPr(plhs[2]); memcpy(gradYoutTemp,gradYvol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*sizeof(float)); plhs[3] = mxCreateNumericArray((mwSize)3,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0); float* normGradXoutTemp = (float*)mxGetPr(plhs[3]); memcpy(normGradXoutTemp,normGradXvol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*sizeof(float)); plhs[4] = mxCreateNumericArray((mwSize)3,(mwSize*)resultSize, mxSINGLE_CLASS, (mxComplexity)0); float* normGradYoutTemp = (float*)mxGetPr(plhs[4]); memcpy(normGradYoutTemp,normGradYvol->get_value_ptr( 0,0,0,0), resultSize[0]*resultSize[1]*resultSize[2]*sizeof(float)); delete imgVol; delete gradXvol; delete gradYvol; delete normGradXvol; delete normGradYvol; delete patchMatchParams; return; }