void initialise_inpainting(nTupleVolume *imgVol, nTupleVolume *occVol, featurePyramid featuresVolPyramid, nTupleVolume *shiftVol, patchMatchParameterStruct *patchMatchParams) { int iterNb=0; patchMatchParams->partialComparison = 1; bool initialisation = true; nTupleVolume *occVolIter; occVolIter = copy_image_nTuple(occVol); seed_random_numbers((double)3); nTupleVolume *structElErode = create_structuring_element("rectangle", 3, 3); nTupleVolume *structElDilate = create_structuring_element("rectangle", imgVol->patchSizeX, imgVol->patchSizeY); nTupleVolume *occVolDilate = imdilate(occVol, structElDilate); //extract features images from featuresVolPyramid (coarsest level) nTupleVolume *normGradXvol,*normGradYvol; if (featuresVolPyramid.nLevels >= 0) { normGradXvol = copy_image_nTuple((featuresVolPyramid.normGradX)[featuresVolPyramid.nLevels-1]); normGradYvol = copy_image_nTuple((featuresVolPyramid.normGradY)[featuresVolPyramid.nLevels-1]); //attach features to patchMatch parameters patchMatchParams->normGradX = normGradXvol; patchMatchParams->normGradY = normGradYvol; } while ( (occVolIter->sum_nTupleVolume()) >0) { nTupleVolume *occVolErode = imerode(occVolIter, structElErode); nTupleVolume *occVolPatchMatch = copy_image_nTuple(occVolDilate); /***************************/ /******* NNSEARCH ******/ /***************************/ //indicate which pixels can be used for comparing patches //but we are not allowed to point to in the patchMatch (we set these pixels to 2) for (int x=0; x<(occVolPatchMatch->xSize); x++) for (int y=0; y<(occVolPatchMatch->ySize); y++) { if ( (occVolDilate->get_image_value(x,y,0) - occVolIter->get_image_value(x,y,0)) == 1) occVolPatchMatch->set_image_value(x,y,0,(imageDataType)2); } //set first guess nTupleVolume *firstGuess = copy_image_nTuple(shiftVol); //carry out patchMatch patch_match_ANN(imgVol,imgVol,shiftVol,occVolPatchMatch,occVolDilate,patchMatchParams,firstGuess); /***************************/ /**** RECONSTRUCTION ***/ /***************************/ nTupleVolume *occVolReconstruct = copy_image_nTuple(occVolIter); //Indicate which pixels are on the current border, and need to be inpainted //Also, we indicate that the pixels inside the occlusion (and not on the border) are occluded (and //therefore not to be used for reconstruction) but should not //be inpainted at the current iteration. To indicate this //we set them to 2 for (int x=0; x<(occVolPatchMatch->xSize); x++) for (int y=0; y<(occVolPatchMatch->ySize); y++) { imageDataType valueTemp = abs(occVolIter->get_image_value(x,y,0) - occVolErode->get_image_value(x,y,0)); occVolReconstruct->set_image_value(x,y,0,valueTemp); if (occVolErode->get_image_value(x,y,0) == 1) occVolReconstruct->set_image_value(x,y,0,(imageDataType)2); } //call reconstruction function if (featuresVolPyramid.nLevels >= 0) reconstruct_image_and_features(imgVol, occVolReconstruct, normGradXvol, normGradYvol, shiftVol, SIGMA_COLOUR, AGGREGATED_PATCHES,initialisation); else { reconstruct_image(imgVol,occVolReconstruct,shiftVol,SIGMA_COLOUR,AGGREGATED_PATCHES,initialisation); } iterNb++; if (patchMatchParams->verboseMode == true) printf("\n Initialisation iteration number : %d \n",iterNb); delete(occVolPatchMatch); delete(occVolReconstruct); //copy the information from the eroded occlusion to the current occlusion (occVolIter) delete(occVolIter); occVolIter = copy_image_nTuple(occVolErode); delete(occVolErode); } }
int main(int argc, char** argv) { int i; int j; int Ymax = 235; int Ymin = 16; int row,col; int sum = 0; int id = 0; double temp; double Cx = 109.38; double Cy = 152.02; double theta = 2.53; double ecx = 1.60; double ecy = 2.41; double a = 25.39; double b = 14.03; double t; double lea = 0; imt_l* H; imt_l* y; imt_c* resultr; imt_c* resultg; imt_c* resultb; imt_c* bi_graph; imt_c* result; imt_c* h; linux_mem_init(); rgb_mt_t* image = imread(argv[1]); if(image == NULL) { exit(2); } row = image->r->row; col = image->r->col; H = create_zero_l(3,3); resultr = create_zero_c(row,col); resultg = create_zero_c(row,col); resultb = create_zero_c(row,col); y = create_zero_l(row,col); medfilt2(image->r,resultr); move_c(resultr,image->r); medfilt2(image->g,resultg); move_c(resultg,image->g); medfilt2(image->b,resultb); move_c(resultb,image->b); imshow("blur.bmp",image); set_pixel_l(H,1,1,65.4810/255); set_pixel_l(H,1,2,128.5530/255); set_pixel_l(H,1,3,24.9660/255); set_pixel_l(H,2,1,-37.7970/255); set_pixel_l(H,2,2,-74.2030/255); set_pixel_l(H,2,3,112.0000/255); set_pixel_l(H,3,1,112.0000/255); set_pixel_l(H,3,2,-93.7860/255); set_pixel_l(H,3,3,-18.2140/255); for(i = 1;i <= row;i ++) for(j = 1;j <= col;j ++) { temp = get_pixel_l(H,1,1) * (double)get_pixel_c(image->r,i,j) + get_pixel_l(H,1,2) * (double)get_pixel_c(image->g,i,j) + get_pixel_l(H,1,3) * (double)get_pixel_c(image->b,i,j) + 16; set_pixel_c(resultr,i,j,(unsigned char)temp); temp = get_pixel_l(H,2,1) * (double)get_pixel_c(image->r,i,j) + get_pixel_l(H,2,2) * (double)get_pixel_c(image->g,i,j) + get_pixel_l(H,2,3) * (double)get_pixel_c(image->b,i,j) + 128; set_pixel_c(resultg,i,j,(unsigned char)temp); temp = get_pixel_l(H,3,1) * (double)get_pixel_c(image->r,i,j) + get_pixel_l(H,3,2) * (double)get_pixel_c(image->g,i,j) + get_pixel_l(H,3,3) * (double)get_pixel_c(image->b,i,j) + 128; set_pixel_c(resultb,i,j,(unsigned char)temp); } clear(H); bi_graph = create_zero_c(row,col); for(i = 1;i <= row;i ++) for(j = 1;j <= col;j ++) { temp = cos(theta) * ((double)get_pixel_c(resultg,i,j) - Cx) + sin(theta) * ((double)get_pixel_c(resultb,i,j) - Cy); set_pixel_l(y,i,j,-sin(theta)*((double)get_pixel_c(resultg,i,j) - Cx) + cos(theta)*((double)get_pixel_c(resultb,i,j) - Cy)); lea = (temp - ecx) * (temp - ecx) / (a * a) + (get_pixel_l(y,i,j) - ecy) * (get_pixel_l(y,i,j) - ecy) / b / b; if(lea < 1.0) { set_pixel_c(bi_graph,i,j,255); } if(get_pixel_c(resultr,i,j) <= 80) { set_pixel_c(bi_graph,i,j,0); } } clear(resultr); clear(resultg); clear(resultb); image->r = bi_graph; image->g = bi_graph; image->b = bi_graph; imshow("bigraph.bmp",image); h = create_zero_c(3,3); set_pixel_c(h,1,1,255); set_pixel_c(h,1,2,255); set_pixel_c(h,1,3,255); set_pixel_c(h,2,1,255); set_pixel_c(h,2,2,255); set_pixel_c(h,2,3,255); set_pixel_c(h,3,1,255); set_pixel_c(h,3,2,255); set_pixel_c(h,3,3,255); result = imrode(bi_graph,h); move_c(result,bi_graph); clear(result); clear(h); h = create_zero_c(12,12); for(i = 1;i <= 12;i ++) for(j = 1;j <= 12;j ++) set_pixel_c(h,i,j,255); result = imdilate(bi_graph,h); move_c(result,bi_graph); clear(result); clear(h); bwareaopen(bi_graph,row * col / 10); for(i = 1;i <= row;i ++) { for(j = 1;j <= col;j ++) { if(get_pixel_c(bi_graph,i,j) == 0) set_pixel_c(bi_graph,i,j,255); else set_pixel_c(bi_graph,i,j,0); } } bwareaopen(bi_graph,row * col / 10); for(i = 1;i <= row;i ++) { for(j = 1;j <= col;j ++) { if(get_pixel_c(bi_graph,i,j) == 0) set_pixel_c(bi_graph,i,j,255); else set_pixel_c(bi_graph,i,j,0); } } result = focus(bi_graph); id = identifier(result); image->r = bi_graph; image->g = bi_graph; image->b = bi_graph; imshow("result.bmp",image); clear(bi_graph); image = imread(argv[1]); for(i = 1;i <= row;i ++) for(j = 1;j < col;j ++) { if(i <= l1 && i >= l0 && j <= n1 && j >= n0) { if(get_pixel_c(result,i - l0,j - n0) == 255) { sum ++; set_pixel_c(image->r,i,j,0); set_pixel_c(image->g,i,j,255); set_pixel_c(image->b,i,j,0); } } if(((j > n0 - 5 && j < n0 + 5) || (j < n1 + 5 && j > n1 - 5)) && ((i < l1 + 5 && i > l1 - 5) || (i > l0 - 5&& i < l0 + 5))) { set_pixel_c(image->r,i,j,255); set_pixel_c(image->g,i,j,0); set_pixel_c(image->b,i,j,0); } } imshow("focus.bmp",image); m_stat(); characteristic(); if(id == 0) { printf("Unknown\n"); } else if(id == 1) { printf("Rock!\n"); } else if(id == 2) { printf("Scissors!\n"); } else if(id == 3) { printf("Paper!\n"); } return 0; }
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); }