├── NSS57.png ├── SWAP50.png ├── ns29.png ├── example.png ├── final ├── out29.png ├── out50.png └── out57.png ├── input ├── in29.png ├── in50.png ├── in57.png └── desktop.ini ├── sGradMex.mexw64 ├── style ├── tar29.png ├── tar50.png ├── tar57.png └── desktop.ini ├── imIndexToVect.m ├── myInsertText.m ├── globals.h ├── getGMat.m ├── doPoissonCombination.m ├── updateImagePoisson.m ├── mexUtils.h ├── example.m ├── README.md ├── Algorithm.h ├── sGradMex.cpp └── Parameters.h /NSS57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/NSS57.png -------------------------------------------------------------------------------- /SWAP50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/SWAP50.png -------------------------------------------------------------------------------- /ns29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/ns29.png -------------------------------------------------------------------------------- /example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/example.png -------------------------------------------------------------------------------- /final/out29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/final/out29.png -------------------------------------------------------------------------------- /final/out50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/final/out50.png -------------------------------------------------------------------------------- /final/out57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/final/out57.png -------------------------------------------------------------------------------- /input/in29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/input/in29.png -------------------------------------------------------------------------------- /input/in50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/input/in50.png -------------------------------------------------------------------------------- /input/in57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/input/in57.png -------------------------------------------------------------------------------- /sGradMex.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/sGradMex.mexw64 -------------------------------------------------------------------------------- /style/tar29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/style/tar29.png -------------------------------------------------------------------------------- /style/tar50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/style/tar50.png -------------------------------------------------------------------------------- /style/tar57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/roimehrez/photorealism/HEAD/style/tar57.png -------------------------------------------------------------------------------- /input/desktop.ini: -------------------------------------------------------------------------------- 1 | [.ShellClassInfo] 2 | InfoTip=This folder is shared online. 3 | IconFile=C:\PROGRA~2\Google\Drive\GOOGLE~1.EXE 4 | IconIndex=16 5 | -------------------------------------------------------------------------------- /style/desktop.ini: -------------------------------------------------------------------------------- 1 | [.ShellClassInfo] 2 | InfoTip=This folder is shared online. 3 | IconFile=C:\PROGRA~2\Google\Drive\GOOGLE~1.EXE 4 | IconIndex=16 5 | -------------------------------------------------------------------------------- /imIndexToVect.m: -------------------------------------------------------------------------------- 1 | % function I = imIndexToVect(Y,X,imHeight) 2 | function I = imIndexToVect(Y,X,imHeight) 3 | 4 | I = reshape(Y + (X-1)*imHeight,prod(size(X)),1); 5 | -------------------------------------------------------------------------------- /myInsertText.m: -------------------------------------------------------------------------------- 1 | function [ im ] = myInsertText( im, str ) 2 | im = insertText(im,... 3 | [5,5],... 4 | str,... 5 | 'FontSize',22,... 6 | 'BoxColor','black',... 7 | 'BoxOpacity',0.7,... 8 | 'TextColor','white'); 9 | end 10 | 11 | -------------------------------------------------------------------------------- /globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define MAX_PATCH_SIZE 15 3 | #define MAX_SOURCE_IMAGES 3 4 | #define MAX_PIXEL_PATCH MAX_SOURCE_IMAGES * (MAX_PATCH_SIZE * MAX_PATCH_SIZE) + 2 5 | #define MAX_DIM 10 6 | typedef unsigned char u08; 7 | #define COLOR_GAMMA 0.5f 8 | #define MAX_PYRAMID_LEVELS 30 9 | #define MAX_NUM_THREADS 16 10 | #define MAX_DIST 9999999999.f 11 | 12 | #define GV_GRADIENT 3 13 | #define GH_GRADIENT 4 14 | //#define HAS_SEARCH_MASK 15 | //-SD 16 | //#define HAS_3CHANNELS 17 | //-SD 18 | //#define TEST_BUG 19 | 20 | 21 | extern float g_fW2; 22 | typedef struct _myBox 23 | { 24 | int isActive; 25 | float x1,x2,x3,x4,y1,y2,y3,y4; 26 | } myBox; 27 | -------------------------------------------------------------------------------- /getGMat.m: -------------------------------------------------------------------------------- 1 | function [Gx,Gy]=getGMat(w,h, mask) 2 | imgSize=w*h; 3 | 4 | dS=[1,-1]; 5 | filtSizeS=1; 6 | 7 | indsGx1 = []; 8 | indsGx2 = []; 9 | valsGx = []; 10 | indsGy1 = []; 11 | indsGy2 = []; 12 | valsGy = []; 13 | mask_sw = mask(1:end - 1, :); 14 | mask_sh = mask(:, 1: end - 1); 15 | 16 | for disp=0:filtSizeS 17 | 18 | [X,Y] = meshgrid(1:w-1,1:h); 19 | indsGx1=[indsGx1; imIndexToVect(Y,X,h)]; 20 | indsGx2=[indsGx2; imIndexToVect(Y,X+disp,h)]; 21 | valsGx=[valsGx; mask_sh(:).*dS(disp+1)]; 22 | 23 | [X,Y] = meshgrid(1:w,1:h-1); 24 | indsGy1=[indsGy1; imIndexToVect(Y,X,h)]; 25 | indsGy2=[indsGy2; imIndexToVect(Y+disp,X,h)]; 26 | valsGy=[valsGy; mask_sw(:).*dS(disp+1)]; 27 | 28 | end 29 | 30 | Gx=sparse(indsGx1,indsGx2,valsGx,imgSize,imgSize); 31 | Gy=sparse(indsGy1,indsGy2,valsGy,imgSize,imgSize); 32 | 33 | -------------------------------------------------------------------------------- /doPoissonCombination.m: -------------------------------------------------------------------------------- 1 | function out_im = doPoissonCombination(im, im_dx, im_dy, im_size, grad_weight) 2 | % optimization to solve SPE in order to combine 3 | % L channel and the gradient channels 4 | [h,w,~] = size(im); 5 | meanL = mean2(im); 6 | im = im - meanL; 7 | TH = 100; 8 | 9 | % remove very high gradients 10 | im_dx(abs(im_dx) > TH) = 0; 11 | im_dy(abs(im_dy) > TH) = 0; 12 | 13 | % prepare the weights 14 | weightGrad = grad_weight * ones(im_size); 15 | weightColor = ones(im_size); 16 | 17 | % sparse representation of the matries 18 | [Gx,Gy] = getGMat(w,h,weightGrad); 19 | n = size(Gx,1); 20 | Icolor = sparse( 1:n, 1:n, weightColor(:)); 21 | 22 | % LTI system with each row as eq, combine the grad_x, grad_y and L 23 | A = [Gx; Gy; Icolor]; 24 | b = double([weightGrad(:) .* im_dx(:); weightGrad(:) .* im_dy(:); im(:)]); 25 | 26 | % solving 27 | x = (A'*A) \ (A'*b); 28 | out_im = reshape(x, [h,w]); 29 | out_im = out_im + meanL; 30 | 31 | -------------------------------------------------------------------------------- /updateImagePoisson.m: -------------------------------------------------------------------------------- 1 | function out_im = updateImagePoisson(origIm, targetIm, w) 2 | % origIm - input (content) RGB uint8 image 3 | % targetIm - the stylized image to be process 4 | 5 | %convert to LAB 6 | origLAB = rgb2lab(origIm); 7 | styledLAB = rgb2lab(targetIm); 8 | 9 | %intialize 10 | im_size = [size(targetIm,1),size(targetIm,2)]; 11 | out_im = styledLAB; 12 | 13 | 14 | % loop over L,a,b channels, process eachone seperatly 15 | % possible to change for with parfor to reproduce the times report in the 16 | % paper 17 | for c=1:3 18 | [dx, dy] = sGradMex(single(origLAB(:,:, c))); 19 | %the above line could be replace with the following MATLAB code: 20 | %a = single(origLAB(:,:, c)); 21 | %dx = a - circshift(a,-1,2); 22 | %dy = a - circshift(a,-1,1); 23 | out_im(:,:,c) = doPoissonCombination(styledLAB(:,:,c),dx,dy,im_size,w(c));%test 24 | end 25 | 26 | %convert to rgb 27 | out_im = im2uint8(lab2rgb(out_im)); 28 | 29 | end 30 | -------------------------------------------------------------------------------- /mexUtils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "mex.h" 4 | #include "Parameters.h" 5 | 6 | void fillNNMap(const mxArray* x_pInput, SNNMap& xr_sMap); 7 | 8 | bool readParameter(const mxArray *A, char* x_strFieldName , double x_dMin, double x_dMax, double& xr_dValue); 9 | 10 | 11 | inline void readImage(const mxArray *A, char* x_strFieldName, ImageInput& x_rImage); 12 | void readImage(const mxArray *val, ImageInput& x_rImage); 13 | 14 | inline void readVoteWeight(const mxArray *A); 15 | 16 | inline void readNNMAP(const mxArray *A, char* x_strName,SNNMap& x_sNNMap); 17 | 18 | 19 | 20 | void fillNNMap(const mxArray* x_pInput, SNNMap& xr_sMap); 21 | 22 | void fillInImage3D(ImageInput* x_psSrcImage,float***& x_rfDstImage); 23 | 24 | void fillInImage2D(ImageInput* x_psSrcImage,float**& x_rfDstImage); 25 | mxArray* fillOutImage3D(float*** x_pfSrImage, int x_nWidth, int x_nHeight, int x_nDim); 26 | 27 | mxArray* fillOutImage2D(float** x_pfSrImage, int x_nWidth, int x_nHeight); 28 | 29 | void readOptions(const mxArray *A); 30 | int fillNNMapArray(const mxArray* x_pInput, SNNMap* x_psMap); 31 | void readGainBias(const mxArray *A, int x_nIndex); 32 | int readGainBiasArray(const mxArray *x_pInput); 33 | 34 | float** create2DArray(int x_nWidth, int x_nHeight); 35 | float*** create3DArray(int x_nWidth, int x_nHeight, int x_nDim); 36 | 37 | void delete3DMatrixF(float***& xr_pfMatrix, int x_nWidth, int x_nHeight, int x_nDim); 38 | 39 | void delete3DMatrixN(int***& xr_pnMatrix, int x_nWidth, int x_nHeight, int x_nDim); 40 | void delete2DMatrixF(float**& xr_pfMatrix, int x_nWidth, int x_nHeight); 41 | 42 | void delete3DMatrixN(int**& xr_pnMatrix, int x_nWidth, int x_nHeight); 43 | void fillPyramid(const mxArray* x_pInput, SMipMapPyramid& xr_sPyramid); 44 | int fillPyramidArray(const mxArray* x_pInput, SMipMapPyramid* x_psPyramid); 45 | void delete4DMatrixF(float****& xr_pfMatrix, int x_nWidth, int x_nHeight, int x_nDim1, int x_nDim2); -------------------------------------------------------------------------------- /example.m: -------------------------------------------------------------------------------- 1 | % EXAMPLE script for "Photorealistic Style Transfer with Screened Poisson 2 | % Equation" 3 | % Please cite: 4 | % Roey Mechrez, Eli Shechtman and Lihi Zelnik-Manor 5 | % "Photorealistic Style Transfer with Screened Poisson Equation" 6 | % BMVC 2017 7 | 8 | grad_weight = [5,1,1]; 9 | 10 | images_numbers = [57,50,29]; 11 | % loop ocer 3 example images from different style transfer algorithms 12 | % Neural style (Gatys et al., Luan et al.) + segmentation 13 | % Style Swap Chen et al. 14 | % and Neural style (Gatys et al.) 15 | % see our paper for citations and details 16 | for im = 1:3 17 | i = images_numbers(im); 18 | % reading the pre-computed stylized images -- target_im 19 | switch im 20 | case 1%'gatys+segmentation' 21 | target_im = imread(sprintf('NSS%d.png',i)); 22 | style_method = 'gatys with segmentation'; 23 | case 2%'style_swap' 24 | target_im = imread(sprintf('SWAP%d.png',i)); 25 | style_method = 'style_swap'; 26 | case 3 27 | target_im = imread(sprintf('ns%d.png',i)); 28 | style_method = 'neural style'; 29 | end 30 | 31 | % reading the input and style images for display 32 | orig_im = imread(fullfile('input',sprintf('in%d.png',i))); 33 | style_im = imread(fullfile('style',sprintf('tar%d.png',i))); 34 | 35 | % resize the images to have same size as target image 36 | if size(orig_im,1) ~= size(target_im,1) || size(orig_im,1) ~= size(style_im,1) 37 | [m,n,c] = size(target_im); 38 | orig_im = imresize(orig_im,[m,n]); 39 | style_im = imresize(style_im,[m,n]); 40 | end 41 | 42 | % compute our algorithm 43 | tic; 44 | out_im = updateImagePoisson(orig_im, target_im ,grad_weight); 45 | t = toc; 46 | fprintf('time to process image: %d is %2.2f sec \n',i,t); 47 | 48 | % save and print 49 | orig_im = myInsertText( orig_im, 'input' ); 50 | style_im = myInsertText( style_im, 'style' ); 51 | target_im = myInsertText( target_im, 'input' ); 52 | out_im_tag = myInsertText( out_im, 'our SPE' ); 53 | cat_im = cat(2,orig_im,style_im,target_im,out_im_tag); 54 | figure;imshow(cat_im); 55 | imwrite(out_im,fullfile('final',sprintf('out%d.png',i))); 56 | end 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Photorealistic Style Transfer with Screened Poisson Equation 3 | 4 | [Roey Mechrez](http://cgm.technion.ac.il/people/Roey/) , [Eli Shechtman](https://research.adobe.com/person/eli-shechtman/) and [Lihi Zelnik-Manor](http://lihi.eew.technion.ac.il/). BMVC 2017. 5 | 6 | [[The Project Page]](http://cgm.technion.ac.il/Computer-Graphics-Multimedia/Software/photorealism/) 7 | 8 | 9 | SPE - MATLAB 1.0 (2017-02-21) 10 | Copyright 2006-2017 Roey Mechrez Licensed for noncommercial research use only. 11 | 12 |
13 | 14 |
15 | 16 | 17 | 18 | ## Background 19 | 20 | This code implements a fast post processing to make images photorealistic using Screened Poisson Equation (SPE) 21 | 22 | Style transfer algorithms generate unrealistic images, this algorithm is a post-processing to any style transfer method (such as Gatys et al.). The algorithm solves the Screen Poisson equation to combine the stylized image with the original image gradients. 23 | 24 | For more information see: 25 | ``` 26 | @article{mechrez2017Photorealistic, 27 | title={Photorealistic Style Transfer with Screened Poisson Equation}, 28 | author={Mechrez, Roey, Shechtman, Eli and Zelnik-Manor, Lihi}, 29 | journal={BMVC}, 30 | year={2017} 31 | } 32 | ``` 33 | 34 | [[arXiv]](https://arxiv.org/abs/1709.09828) 35 | Please cite these paper if you use this code in an academic publication. 36 | 37 | 38 | ## Use 39 | 40 | To run one pair of images use 41 | ``` 42 | example.m 43 | ``` 44 | core functions: 45 | ``` 46 | doPoissonCombination.m, updateImagePoisson.m 47 | ``` 48 | if you are using Linux or OS, see [issue#2](https://github.com/roimehrez/photorealism/issues/2) for solution since the attach mex file will not work. 49 | 50 | ## License 51 | 52 | This software is provided under the provisions of the Lesser GNU Public License (LGPL). 53 | see: http://www.gnu.org/copyleft/lesser.html. 54 | 55 | This software can be used only for research purposes, you should cite 56 | the aforementioned papers in any resulting publication. 57 | 58 | The Software is provided "as is", without warranty of any kind. 59 | 60 | 61 | ## Code References 62 | 63 | [1] Mechrez, Roey and Shechtman, Eli and Zelnik-Manor, Lihi. "Saliency Driven Image Manipulation". arXiv preprint arXiv:1612.02184. 2016 [url](https://arxiv.org/abs/1612.02184) 64 | 65 | [2] Darabi, Soheil and Shechtman, Eli and Barnes, Connelly and Goldman, Dan B and Sen, Pradeep. "Image melding: Combining inconsistent images using patch-based synthesis." ACM Trans. Graph. 2012 [url](http://www.ece.ucsb.edu/~psen/melding) 66 | 67 | [3] Fujun Luan, Sylvain Paris, Eli Shechtman, Kavita Bala. "Deep Photo Style Transfer". CVPR. 2017 [url](https://github.com/luanfujun/deep-photo-styletransfer) 68 | 69 | 70 | 71 | 72 | ## Version History 73 | 74 | * Version 1.0 (2017-02-21) 75 | Initial Release 76 | -------------------------------------------------------------------------------- /Algorithm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "ImageReader.h" 3 | #include "SourceImage.h" 4 | #include "CCorrespondanceMap.h" 5 | #include "Patch.h" 6 | 7 | 8 | class CAlgorithm 9 | { 10 | public: 11 | CSourceImage* m_pSource1;//first source 12 | CSourceImage* m_pSource2[MAX_SOURCE_IMAGES];//second source 13 | CPatch **m_pPathecs; 14 | float*** m_pfAccum; 15 | float**** m_pfAccumMed; 16 | CCorrespondanceMap* m_pCorrespondingMap[MAX_SOURCE_IMAGES];//Corresponding Map 17 | float** m_pfMask; 18 | float** m_pfSegments; 19 | float** m_pfEMAlpha; 20 | int m_nChannels; 21 | int m_nNumberOfSourceImages; 22 | void doVotingMed(float**** x_pfOutput, int x_nIndex); 23 | void doVotingInverse(float**** x_pfOutput, int x_nIndex); 24 | void voteForPatch(int x, int y, CPatch* x_pPatch, float x_fMaskValue, int x_nNumberOfChannels); 25 | 26 | float isCoherent(const int patchSize, int x_nIndex, float*** ann, int ax, int ay, float bx, float by, int dx, int dy, int _nAW, int _nAH, float x_fDist); 27 | int m_nDstImageSize; 28 | int m_nDstWidth; 29 | int m_nDstHeight; 30 | void correctDepthInfo(); 31 | void unWeightCoherency(int x_nIndex); 32 | void createACC(); 33 | void giveCoherencyWeight(float** x_pfCohWeight); 34 | void createACCMed(int x_nWidth, int x_nHeight); 35 | void mergeACCAndACCMED(); 36 | CAlgorithm(CSourceImage* x_pSource1, CSourceImage* x_pSource2); 37 | CAlgorithm( char* x_strCorrespondingFileName); 38 | CAlgorithm( bool x_bIsSynthesize); 39 | CAlgorithm( SMipMapPyramid* x_pA, SMipMapPyramid* x_pB , bool x_bIsSynthesize); 40 | CAlgorithm( SMipMapPyramid* x_pA, SMipMapPyramid* x_pB , SNNMap* x_pNNMapForward, SNNMap* x_pNNMapBackward); 41 | CAlgorithm( SMipMapPyramid* x_pA, SMipMapPyramid* x_pB , SNNMap* x_pNNMap, int x_nDoVoting, int x_nNumberOfSources = 1, bool x_bDoGradientMedian = 0, int x_nScaledWidth = 0, int x_nScaledHeight = 0); 42 | int m_nPatchWidth; 43 | ~CAlgorithm(void); 44 | void doVoting(float*** x_pfOutput, int x_nEmIndex, int x_nNormalized = 1, float x_fMaskValues = -1); 45 | 46 | void doVotingBid(float*** x_pfOutput, int x_nEmIndex, float x_fMaskValues = -1); 47 | //void voteForPatch(int x, int y, CPatch* x_pPatch); 48 | void initValues(); 49 | void doEMIterations(); 50 | void calculateACCFromACCMED(); 51 | int getHeight(int x_nIndex){if(x_nIndex) return (*m_pSource2)->giveWidth(); return m_pSource1->giveWidth(); }; 52 | int getWidth(int x_nIndex){if(x_nIndex) return (*m_pSource2)->giveHeight(); return m_pSource1->giveHeight(); }; 53 | void addDataForMed(int x, int y, int x_nIndex, CPatch* x_pPatch2, CPatch* x_pPatch, int x_nNumberOfChannels); 54 | void addDataForInv(int x, int y, float x_fxR, float x_fyR, int x_nIndex, CPatch* x_pPatch, int x_nNumberOfChannels); 55 | float givePatchForVis(int x_nRX, int x_nRY,int x_nX, int x_nY,CPatch* x_pPatch);//This is for the visualizer and when I call it, it fills the x_pPatch with the values in the source image. 56 | void voteForPatchMed(int x, int y, int x_nNumberOfChannels); 57 | 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /sGradMex.cpp: -------------------------------------------------------------------------------- 1 | 2 | // MATLAB interface, for PatchMatch + Generalized PatchMatch. 3 | 4 | #include 5 | #include "mex.h" 6 | #include "globals.h" 7 | #include "Algorithm.h" 8 | #include "mexUtils.h" 9 | #include 10 | #define EDGE_CONST 100 11 | 12 | 13 | 14 | 15 | 16 | void calculateDX( float** x_pfInputIm, int x_nWidth, int x_nHeight, float** x_pfOutput) 17 | { 18 | int _nW = x_nWidth - 1; 19 | int _nH = x_nHeight - 1; 20 | 21 | for(int i = 0; i < x_nWidth; i++) 22 | { 23 | for(int j = 0 ; j < x_nHeight ; j++) 24 | { 25 | x_pfOutput[i][j] = 0; 26 | } 27 | } 28 | for(int j = 0 ; j < x_nHeight ; j++) 29 | { 30 | for(int i = 0; i < x_nWidth; i++) 31 | { 32 | 33 | float _fC = x_pfInputIm[i][j]; 34 | float _fN = (i < _nW) ? x_pfInputIm[ i + 1][j] : x_pfInputIm[i][j]; 35 | float _fB = 0; 36 | float _fD = _fC - _fN; 37 | x_pfOutput[i][j] = _fD; 38 | } 39 | } 40 | 41 | for(int j = 0 ; j < x_nHeight ; j++) 42 | { 43 | for(int i = 1; i < _nW; i++) 44 | { 45 | 46 | float _fD = x_pfOutput[i][j]; 47 | 48 | if(_fD < -EDGE_CONST || _fD > EDGE_CONST) 49 | { 50 | float _fC = x_pfInputIm[i][j]; 51 | float _fTD = 0; 52 | float _fND = x_pfOutput[ i + 1][j]; 53 | float _fBD = x_pfOutput[ i - 1][j]; 54 | if(_fC < -EDGE_CONST || _fC > EDGE_CONST) 55 | { 56 | if(_fND > -EDGE_CONST && _fND < EDGE_CONST) 57 | { 58 | _fTD = _fND; 59 | } 60 | else if(_fBD > -EDGE_CONST && _fBD < EDGE_CONST) 61 | { 62 | _fTD = _fBD; 63 | } 64 | else 65 | { 66 | _fTD = 0; 67 | } 68 | } 69 | else 70 | { 71 | if(_fBD > -EDGE_CONST && _fBD < EDGE_CONST) 72 | { 73 | _fTD = _fBD; 74 | } 75 | else if(_fND > -EDGE_CONST && _fND < EDGE_CONST) 76 | { 77 | _fTD = _fND; 78 | } 79 | else 80 | { 81 | _fTD = 0; 82 | } 83 | 84 | } 85 | x_pfOutput[ i ][j] = _fTD; 86 | } 87 | } 88 | 89 | } 90 | } 91 | 92 | 93 | void calculateDY( float** x_pfInputIm, int x_nWidth, int x_nHeight, float** x_pfOutput) 94 | { 95 | int _nW = x_nWidth - 1; 96 | int _nH = x_nHeight - 1; 97 | 98 | for(int i = 0; i < x_nWidth; i++) 99 | { 100 | for(int j = 0 ; j < x_nHeight ; j++) 101 | { 102 | x_pfOutput[i][j] = 0; 103 | } 104 | } 105 | 106 | for(int i = 0; i < x_nWidth; i++) 107 | { 108 | for(int j = 0 ; j < x_nHeight ; j++) 109 | { 110 | 111 | 112 | float _fC = x_pfInputIm[i][j]; 113 | float _fN = (j < _nH) ? x_pfInputIm[ i ][j + 1] : x_pfInputIm[i][j]; 114 | float _fB = 0; 115 | float _fD = _fC - _fN; 116 | x_pfOutput[i][j] = _fD; 117 | } 118 | } 119 | 120 | //for(int k = 0 ; k < 10 ; k++) 121 | { 122 | 123 | for(int i = 0; i < x_nWidth; i++) 124 | { 125 | for(int j = 1 ; j < _nH ; j++) 126 | { 127 | //if(i == 23 && j == 11) 128 | // printf("here!\n"); 129 | float _fD = x_pfOutput[i][j]; 130 | if(_fD < -EDGE_CONST || _fD > EDGE_CONST) 131 | { 132 | float _fC = x_pfInputIm[i][j]; 133 | float _fTD = 0; 134 | float _fND = x_pfOutput[ i ][j + 1]; 135 | float _fBD = x_pfOutput[ i ][j - 1]; 136 | if(_fC < -EDGE_CONST || _fC > EDGE_CONST) 137 | { 138 | if(_fND > -EDGE_CONST && _fND < EDGE_CONST) 139 | { 140 | _fTD = _fND; 141 | } 142 | else if(_fBD > -EDGE_CONST && _fBD < EDGE_CONST) 143 | { 144 | _fTD = _fBD; 145 | } 146 | else 147 | { 148 | _fTD = 0; 149 | } 150 | } 151 | else 152 | { 153 | if(_fBD > -EDGE_CONST && _fBD < EDGE_CONST) 154 | { 155 | _fTD = _fBD; 156 | } 157 | else if(_fND > -EDGE_CONST && _fND < EDGE_CONST) 158 | { 159 | _fTD = _fND; 160 | } 161 | else 162 | { 163 | _fTD = 0; 164 | } 165 | 166 | } 167 | x_pfOutput[ i ][j] = _fTD; 168 | } 169 | 170 | } 171 | } 172 | } 173 | 174 | for(int j = 0 ; j < x_nHeight ; j++) 175 | { 176 | for(int i = 1; i < _nW; i++) 177 | { 178 | 179 | float _fD = x_pfOutput[i][j]; 180 | if(_fD < -EDGE_CONST || _fD > EDGE_CONST) 181 | { 182 | printf("Error: at (%d,%d) gradient is big!\b", i , j); 183 | } 184 | 185 | } 186 | } 187 | } 188 | 189 | 190 | 191 | void mexFunction(int nout, mxArray *pout[], int nin, const mxArray *pin[]) { 192 | 193 | if (nin != 1) { mexErrMsgTxt("sDistMex called with != 1 input arguments"); } 194 | 195 | const mxArray *A = pin[0]; 196 | if(mxGetNumberOfDimensions(A) != 2){ mexErrMsgTxt("Error: the input has to be gray scale image!"); } 197 | if(!mxIsSingle(A)){ mexErrMsgTxt("Error: the input has to be single!"); } 198 | ImageInput _sA; 199 | const mwSize* dimA = mxGetDimensions(A); 200 | _sA.m_pfData = (float*)mxGetData(A); 201 | _sA.m_nWidth = dimA[0]; 202 | _sA.m_nHeight = dimA[1]; 203 | _sA.m_bIsDefined = 1; 204 | float** _pfInputIm = 0; 205 | fillInImage2D(&_sA, _pfInputIm); 206 | 207 | float** _pf_DX = create2DArray(_sA.m_nWidth, _sA.m_nHeight); 208 | float** _pf_DY = create2DArray(_sA.m_nWidth, _sA.m_nHeight); 209 | calculateDX(_pfInputIm ,_sA.m_nWidth, _sA.m_nHeight, _pf_DX); 210 | calculateDY(_pfInputIm, _sA.m_nWidth, _sA.m_nHeight, _pf_DY); 211 | 212 | 213 | mxArray* DX = fillOutImage2D(_pf_DX, _sA.m_nWidth, _sA.m_nHeight); 214 | pout[1] = DX; 215 | 216 | mxArray* DY = fillOutImage2D(_pf_DY, _sA.m_nWidth, _sA.m_nHeight); 217 | pout[0] = DY; 218 | 219 | delete2DMatrixF(_pf_DX, _sA.m_nWidth, _sA.m_nHeight); 220 | delete2DMatrixF(_pf_DY, _sA.m_nWidth, _sA.m_nHeight); 221 | } 222 | -------------------------------------------------------------------------------- /Parameters.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "globals.h" 3 | #include "macros.h" 4 | #include 5 | #include 6 | 7 | struct SNNMap 8 | { 9 | int m_nWidth; 10 | int m_nHeight; 11 | bool m_bIsDefined; 12 | float* m_pfData; 13 | }; 14 | 15 | struct ImageInput 16 | { 17 | int m_nWidth; 18 | int m_nHeight; 19 | int m_nDims; 20 | bool m_bIsDefined; 21 | float* m_pfData; 22 | float** m_pf2DData; 23 | float*** m_pf3DData; 24 | }; 25 | 26 | struct SMipMapPyramid 27 | { 28 | int m_nLength; 29 | int m_nDim; 30 | int m_arrnWidth[MAX_PYRAMID_LEVELS]; 31 | int m_arrnHeight[MAX_PYRAMID_LEVELS]; 32 | float* m_arrpfData[MAX_PYRAMID_LEVELS]; 33 | float m_arrfScales[MAX_PYRAMID_LEVELS]; 34 | float global_scale; 35 | 36 | }; 37 | 38 | class CParameters 39 | { 40 | public: 41 | int m_nParallelIterations; 42 | int m_nSequentialIterations; 43 | int m_nPatchWidth; 44 | int m_nRSMax; 45 | int m_nRSMin; 46 | int m_nNumberOfEMIterations; 47 | int m_nDoMinNNF; 48 | int m_nNumberOfThreads; 49 | int m_nRandomSeed; 50 | float m_fRSRatio; 51 | float m_fRSIters; 52 | float m_fMinScale; 53 | float m_fMaxScale; 54 | float m_fMinAngle; 55 | float m_fMaxAngle; 56 | float m_fNormalizeWeight; 57 | float m_arrfVoteWeights[MAX_PATCH_SIZE][MAX_PATCH_SIZE]; 58 | float m_arrfVoteWeightOneD[MAX_PATCH_SIZE * MAX_PATCH_SIZE]; 59 | float m_arrfMinBias[MAX_DIM]; 60 | float m_arrfMaxBias[MAX_DIM]; 61 | float m_arrfMinGain[MAX_DIM]; 62 | float m_arrfMaxGain[MAX_DIM]; 63 | float* m_pfGainBias[MAX_SOURCE_IMAGES]; 64 | int m_nDimOfMinMax; 65 | float m_fGradWeight; 66 | float m_fMinRelScale; 67 | float m_fMaxRelScale; 68 | float m_fWindowSize; 69 | float m_fCompletenessWeight; 70 | int m_nIsPixelInterpolation; 71 | int m_nIsRadnomInit; 72 | int m_nDoRandomSearch; 73 | int m_nIsReflection; 74 | float m_fCoherencyWeight; 75 | ImageInput m_sDstWeight; 76 | ImageInput m_sMaskInput; 77 | ImageInput m_sEMAlpha; 78 | ImageInput m_sCurrentSRCIm; 79 | ImageInput m_sSearchSize; 80 | ImageInput m_sSrcSearchMask; 81 | ImageInput m_sTrgSegments; 82 | ImageInput m_sDstSearchMask; 83 | ImageInput m_sEpipolarConst; 84 | 85 | ImageInput m_sSegments; 86 | SNNMap m_sPrevMap; 87 | SNNMap m_sPriorMap; 88 | SNNMap m_sWindowSize; 89 | 90 | 91 | CParameters( int x_nPatchWidht = 8, int x_nParallelIterations = 0, int x_nSequentialIterations = 0, int x_nRSMax = 1000, int x_nRSMin = 1, float x_fRSRatio = 0.5, float x_fRSIters = 1.f , float x_fMaxScale = 2.f, float x_fMinScale = .5f, float x_fMinRelScale = 1.0f, float x_fMaxRelScale = 1.0f, float x_fMinAngle = 0.f, float x_fMaxAngle = 2 * M_PI, float x_fNormalizeWeight = 0 92 | , float x_fCoherencyWeight = 1.f,int x_nNumberOfEMIterations = 0, int x_nDoMinNNF = 0, int x_nNumberOfThreads = 1, int x_nIsPixelInterpolation = 0, float x_fGradWeight = 0) 93 | { 94 | m_nParallelIterations = x_nParallelIterations; 95 | m_nSequentialIterations = x_nSequentialIterations; 96 | m_nPatchWidth = x_nPatchWidht; 97 | m_nRSMax = x_nRSMax; 98 | m_nRSMin = x_nRSMin ; 99 | m_fRSRatio = x_fRSRatio; 100 | m_fRSIters = x_fRSIters ; 101 | m_fMinScale = x_fMinScale; 102 | m_fMaxScale = x_fMaxScale; 103 | m_fMinRelScale = x_fMinRelScale; 104 | m_fMaxRelScale = x_fMaxRelScale; 105 | m_fMinAngle = x_fMinAngle; 106 | m_fMaxAngle = x_fMaxAngle; 107 | m_fCompletenessWeight = 0; 108 | for(int i = 0 ; i < MAX_DIM ; i++) 109 | { 110 | m_arrfMinBias[i] = 0; 111 | m_arrfMaxBias[i] = 0; 112 | m_arrfMinBias[i] = 1.f; 113 | m_arrfMaxBias[i] = 1.f; 114 | } 115 | m_nDimOfMinMax = 0; 116 | m_nRandomSeed = ((unsigned)time ( NULL ) ); 117 | m_nDoMinNNF = x_nDoMinNNF; 118 | m_nIsPixelInterpolation = x_nIsPixelInterpolation; 119 | m_nNumberOfThreads = x_nNumberOfThreads; 120 | m_nNumberOfEMIterations = x_nNumberOfEMIterations; 121 | m_fCoherencyWeight = x_fCoherencyWeight; 122 | m_fGradWeight = x_fGradWeight; 123 | m_fNormalizeWeight = x_fNormalizeWeight; 124 | m_nIsRadnomInit = 1; 125 | m_nIsReflection = 1; 126 | m_nDoRandomSearch = 1; 127 | 128 | for(int i = 0 ; i < MAX_PATCH_SIZE ; i++) 129 | { 130 | for(int j = 0 ; j < MAX_PATCH_SIZE ; j++) 131 | { 132 | m_arrfVoteWeights[i][j] = 1.f; 133 | } 134 | } 135 | memset(m_pfGainBias, 0, sizeof(float) * MAX_SOURCE_IMAGES); 136 | m_sPrevMap.m_bIsDefined = 0; 137 | m_sWindowSize.m_bIsDefined = 0; 138 | m_sPriorMap.m_bIsDefined = 0; 139 | 140 | m_sSearchSize.m_bIsDefined = 0; 141 | m_sSearchSize.m_pf2DData = 0; 142 | m_sSearchSize.m_pf3DData = 0; 143 | m_fWindowSize = 0; 144 | 145 | m_sDstWeight.m_bIsDefined = 0; 146 | m_sDstWeight.m_pf2DData = 0; 147 | m_sDstWeight.m_pf3DData = 0; 148 | 149 | m_sSrcSearchMask.m_bIsDefined = 0; 150 | m_sSrcSearchMask.m_pf2DData = 0; 151 | m_sSrcSearchMask.m_pf3DData = 0; 152 | 153 | m_sDstSearchMask.m_bIsDefined = 0; 154 | m_sDstSearchMask.m_pf2DData = 0; 155 | m_sDstSearchMask.m_pf3DData = 0; 156 | 157 | m_sEpipolarConst.m_bIsDefined = 0; 158 | m_sEpipolarConst.m_pf2DData = 0; 159 | m_sEpipolarConst.m_pf3DData = 0; 160 | 161 | m_sMaskInput.m_bIsDefined = 0; 162 | m_sMaskInput.m_pf2DData = 0; 163 | m_sMaskInput.m_pf3DData = 0; 164 | 165 | m_sEMAlpha.m_bIsDefined = 0; 166 | m_sEMAlpha.m_pf2DData = 0; 167 | m_sEMAlpha.m_pf3DData = 0; 168 | 169 | m_sCurrentSRCIm.m_bIsDefined = 0; 170 | m_sCurrentSRCIm.m_pf2DData = 0; 171 | m_sCurrentSRCIm.m_pf3DData = 0; 172 | 173 | m_sSegments.m_bIsDefined = 0; 174 | m_sSegments.m_pf2DData = 0; 175 | m_sSegments.m_pf3DData = 0; 176 | 177 | m_sTrgSegments.m_bIsDefined = 0; 178 | m_sTrgSegments.m_pf2DData = 0; 179 | m_sTrgSegments.m_pf3DData = 0; 180 | 181 | }; 182 | ~CParameters(void); 183 | }; 184 | 185 | 186 | extern CParameters* g_pParameter; 187 | --------------------------------------------------------------------------------