function real_filt = hurlbert( gamma, beta, sigma, lambda ) % Anya Hurlbert's Regularization Approach to Color Constancy % This function generates a filter with the indicated parameters: % % hurlbert( gamma, beta, sigma, lambda ) % % gamma (typ. 1) - the noise reduction term % beta (typ. 0.01) - the weight on surface albedo changes % sigma (typ. 4) - the std. deviation of gaussian constant color patch % lambda (typ. 10) - the weight on smooth lighting changes % J. Watlington, 11/29/96 var = sigma^2; M = 128; % Length of the filter to be generated (odd) MM = M/2; % Number of samples in the frequency domain % These are the frequencies we are sampling at omega = ( 2 * pi * [0:M] )/M; % Calculate the frequency response at the sample points p = zeros( 1, M ); % for speed for k = 1:MM+1; freq = omega(k); p(k) = (lambda*freq^2)/(lambda*freq^2 + (1+lambda*freq^2)*(beta*exp(-(freq^2)*var) + gamma*freq^4)); end for k = MM+2:M; p(k) = p(M-k+2); end figure; subplot( 2, 1, 1 ); plot( omega(1:M), p, '-' ); axis( [ 0, pi, 0, 1.1 ] ); xlabel( 'omega' ), ylabel( 'magnitude' ); title( 'Frequency Response' ); text1 = [ 'gamma: ', num2str( gamma ), ' beta: ', num2str( beta ) ]; text2 = [ 'lambda: ', num2str( lambda ), ' sigma: ', num2str( sigma ) ]; text( 2, 0.8, text1 ); text( 2, 0.6, text2 ); rfilt = ifft( p, M ); filt( 1:MM ) = rfilt( MM+1:M ); filt( MM+1:M ) = rfilt( 1:MM ); % This code generates a trapezoidal window designed to leave the % desired filter with a good DC response. W = 4; window_size = M/W; window_inc = W/M; window = ones( 1, M ); for k = 1:window_size; window( k ) = k * window_inc; window( M - k + 1 ) = k * window_inc; end corr_factor = 0.23; window( M/2 + 1 ) = 1 - corr_factor; window( M/2 ) = 1 - 2 * corr_factor; window( M/2 - 1 ) = 1 - corr_factor; end for k = 1:M; % In conjunction with the above code, this provides a trapezoidal window real_filt(k) = 1.3 * real( filt(k) ) * window(k); % The following line adds a Hamming window, and gooses the gain a tad % real_filt(k) = 1.1 .* real(filt(k)) .* ( 0.54 - 0.46 * cos( 2*pi*(k-1)/M )); % The following line adds a Blackman window % real_filt(k) = real(filt(k)) .* ( 0.42 - 0.5 * cos( 2*pi*(k-1)/(M-1)) + 0.08 * cos( 4*pi*(k-1)/(M-1)) ); end subplot( 2, 1, 2 ); plot( [-MM:(MM-1)], real_filt( 1:M ), '-' ); axis( [ -MM, MM, -0.1, 0.6 ] ); title( 'Spatial Response' ); ffilt = fft( real_filt, 2048 ); figure; pomega = 0:pi/1024:pi; plot( pomega, abs( ffilt( 1:1025 )), '-' ); axis( [ 0, pi/4, 0, 1.3 ] ); xlabel( 'omega' ), ylabel( 'magnitude' ); title( 'Freq. Response of actual filter' );