% *  This code was used in the following articles:
% *  [1] Learning 3-D Scene Structure from a Single Still Image, 
% *      Ashutosh Saxena, Min Sun, Andrew Y. Ng, 
% *      In ICCV workshop on 3D Representation for Recognition (3dRR-07), 2007.
% *      (best paper)
% *  [2] 3-D Reconstruction from Sparse Views using Monocular Vision, 
% *      Ashutosh Saxena, Min Sun, Andrew Y. Ng, 
% *      In ICCV workshop on Virtual Representations and Modeling 
% *      of Large-scale environments (VRML), 2007. 
% *  [3] 3-D Depth Reconstruction from a Single Still Image, 
% *      Ashutosh Saxena, Sung H. Chung, Andrew Y. Ng. 
% *      International Journal of Computer Vision (IJCV), Aug 2007. 
% *  [6] Learning Depth from Single Monocular Images, 
% *      Ashutosh Saxena, Sung H. Chung, Andrew Y. Ng. 
% *      In Neural Information Processing Systems (NIPS) 18, 2005.
% *
% *  These articles are available at:
% *  http://make3d.stanford.edu/publications
% * 
% *  We request that you cite the papers [1], [3] and [6] in any of
% *  your reports that uses this code. 
% *  Further, if you use the code in image3dstiching/ (multiple image version),
% *  then please cite [2].
% *  
% *  If you use the code in third_party/, then PLEASE CITE and follow the
% *  LICENSE OF THE CORRESPONDING THIRD PARTY CODE.
% *
% *  Finally, this code is for non-commercial use only.  For further 
% *  information and to obtain a copy of the license, see 
% *
% *  http://make3d.stanford.edu/publications/code
% *
% *  Also, the software distributed under the License is distributed on an 
% * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
% *  express or implied.   See the License for the specific language governing 
% *  permissions and limitations under the License.
% *
% */
function [X, Y, StepLen, Coeff, Coeffs ]=SearchCorrMatchEpipoarLine...
		(defaultPara, ITarget, IField, POriReproj, Pocclu, TargetFullyInField)

% This function serch along the epipolar line from 
% POriReproj to Pocclu with fix step size

% ParameterSetting
Field2TargetScale = 2;
TargetSize = size(ITarget);%round([Iy/55*5 Ix/305*10]);
FieldSize = round(TargetSize*Field2TargetScale); % 1.5 gives bad result
StepSize = min(FieldSize)/10; % make sure after each close by step the Field overlap % /2 since too big step size
EpiolarLen = norm(POriReproj - Pocclu);
P2 = POriReproj - Pocclu;
UnitEpipoVector = Pocclu - POriReproj; %( X_Hori, Y_Vert)
MargimSerachValue = 0.2*EpiolarLen; % percentage of the marginal search area
DeviateFromEpipoleThre = 10; % pixels
[IyField IxField] = size( IField);
% equalized the images
%ITarget = histeq(ITarget);
% IField = histeq(IField);
UnitEpipoVector = UnitEpipoVector./norm(UnitEpipoVector);
best_max     = 0.0;
best_id = [];
Coeffs = [];
% Loop over Scale
%NumScale = length(Scale)

%for i = 1:NumScale

	% loop for step size along the epipolar line
	adj_row         = TargetSize(1) ;%- 1;
        adj_col         = TargetSize(2) ;%- 1;
	StepLen = -MargimSerachValue;%0;
	Shift_id = 1;
    
	while StepLen <= EpiolarLen+MargimSerachValue
		
        % Scale the ITarget
        %
        
		% create the new field for normxcorr2 to run
		FieldCenter = round(POriReproj + StepLen * UnitEpipoVector);%( X_Hori, Y_Vert)
        FieldCenter(1) = min(max( FieldCenter(1),1) , IxField);%( X_Hori, Y_Vert)
        FieldCenter(2) = min(max( FieldCenter(2),1) , IyField);%( X_Hori, Y_Vert)
        %figure(1); hold on; scatter(FieldCenter(1,1), FieldCenter(2,1),'y');
		IField_tmp = IField( FieldCenter(2):min( FieldCenter(2)+FieldSize(1), IyField) , ...
                                                FieldCenter(1):min( FieldCenter(1)+FieldSize(2), IxField) );
		if ( (size(ITarget, 1 ) <= size(IField_tmp,1)) && (size(ITarget, 2 ) <= size(IField_tmp,2)) ) % make sure 
			res             = normxcorr2( ITarget, IField_tmp);           
			if (TargetFullyInField)
        		        % If we know that the target is compeltely within the field,
               		 	%   exclude portions of the correlation that are generated by
	                	%   only a partial overlap of the target and  field.
        	        	top     = size(ITarget,1) + 1;
           	   	  	left    = size(ITarget,2) + 1;
	               	 	height  = size(IField_tmp,1) - size(ITarget,1) ;%+ 1;
        	        	width   = size(IField_tmp,2) - size(ITarget,2) ;%+ 1;
                		% use only those results where the Target is compeltely
	               	 	%   inside the Field.
        	        	res     = res( top:(top+height), left:(left+width) );
                		adj_row  = 0;
                        
	                	adj_col  = 0;
            end

            if Shift_id == 2
               disp('check corrolation');
            end
	        	% Max(matrix) returns the largest value in each col, in a row vector
        		[ max_vals, max_row_inds ] = max( abs( res ) );
	        	% Find the Col with the bigest Max
        		[ max_val , max_col_ind  ] = max( max_vals );
	        	% Get the row & col with the largest correlation
        		max_row_ind = max_row_inds( max_col_ind );
	        	% Adjust to get offset of scaled Target, in field, in units of
        		%   FIELD pixels.	
			tmp_offsetRow = max_row_ind - adj_row + FieldCenter(2);
			tmp_offsetCol = max_col_ind - adj_col + FieldCenter(1);
			
% 			if distances <= DeviateFromEpipoleThre
		        	Coeffs( Shift_id ).offsetRow    = tmp_offsetRow;
        			Coeffs( Shift_id ).offsetCol    = tmp_offsetCol;
				Coeffs( Shift_id ).index        = Shift_id;
        			Coeffs( Shift_id ).StepLen  = StepLen;
		        	Coeffs( Shift_id ).correlation  = max_val;
%       	  		StepLen, max_val, best_max, max_row_ind, max_col_ind
	        		% imview close all;
        			% imview( res );
		        	% imview( target_tmp);
        			if (( Shift_id==1) || (max_val > best_max) )
                			best_max = max_val;
		        	        best_id = Shift_id;
		        	end % check for new best location
% 			end
		end

		Shift_id = Shift_id + 1;
		StepLen = StepLen+StepSize;	
    end
    if ~isempty(best_id)
        P3 = [Coeffs( best_id ).offsetCol; Coeffs( best_id ).offsetRow] - Pocclu;
		u = P2' * P3 / (P2' * P2);
		distances = sqrt( sum( ( repmat(u,[2,1]) .* repmat(P2,[1,size(P3,2)]) - P3).^2 ,1));
        if distances <= DeviateFromEpipoleThre
            X       = Coeffs( best_id ).offsetCol;
            Y       = Coeffs( best_id ).offsetRow;
            StepLen   = Coeffs( best_id ).StepLen;
            Coeff   = Coeffs( best_id ).correlation;
        else
            X       = NaN;
            Y       = NaN;
            StepLen   = 0;
            Coeff   = 0;
        end
    else
        X       = NaN;
        Y       = NaN;
        StepLen   = 0;
        Coeff   = 0;
    end

%end
