├── 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 |
--------------------------------------------------------------------------------