├── .gitignore ├── README.md ├── tools ├── imbilateral.m ├── cumsum_image.m ├── imbilateral.asv ├── 3rdparty │ ├── color_science │ │ ├── grey.mat │ │ ├── test.mat │ │ ├── Thumbs.db │ │ ├── cc_lin.tif │ │ ├── keele.mat │ │ ├── locus.mat │ │ ├── rgb_cc.mat │ │ ├── train.mat │ │ ├── xyz_cc.mat │ │ ├── MBlocus.mat │ │ ├── cc_lin_sp.tif │ │ ├── halftone.mat │ │ ├── phosphors.mat │ │ ├── weights.mat │ │ ├── fundamentals_ss.mat │ │ ├── srgb2xyz.m │ │ ├── xyz2srgb.m │ │ ├── cband.m │ │ ├── rgb2lms.m │ │ ├── lms2rgb.m │ │ ├── temp_test.m │ │ ├── plotFundamentals.m │ │ ├── plotDeviceSPDs.m │ │ ├── lms2rgbMB.m │ │ ├── license.txt │ │ ├── rgbMB2lms.m │ │ ├── dkl_sph2cart.m │ │ ├── cmccat00.m │ │ ├── cmccat00r.m │ │ ├── svd_demo.m │ │ ├── cmccat97.m │ │ ├── plotMBdiagram.m │ │ ├── cielabde.m │ │ ├── sprague.m │ │ ├── cie94de.m │ │ ├── dkl2lms.m │ │ ├── camera_demo1.m │ │ ├── lms2dkl.m │ │ ├── dkl_cart2sph.m │ │ ├── cmcde.m │ │ ├── xyz2lab.m │ │ ├── xyz2luv.m │ │ ├── r2xyz.m │ │ ├── cie00de.m │ │ ├── lab2xyz.m │ │ ├── cielabplot.m │ │ ├── printer_demo1.m │ │ ├── ciecam02.m │ │ ├── printer_demo.m │ │ ├── camera_demo.m │ │ ├── cieplot.m │ │ ├── crtdemo.m │ │ └── plotDKLspace.m │ ├── toolbox_v1.3_color_science.zip │ └── %5BStephen_Westland%2C_Caterina_Ripamonti%2C_Vien_Cheung(b-ok.xyz).pdf ├── imbilateral_demo.asv ├── imbilateral_demo.m └── paddarray_symmetric.m ├── structure_detect ├── canny.m └── canny_demo.m ├── data ├── stereo_vision │ ├── img1.png │ ├── img2.png │ ├── madera_1.jpg │ └── madera_2.jpg └── denoise │ └── lena_noised_gaussian_sigma=20_multi_2.png ├── hdr ├── tone_mapping │ ├── fbf │ │ ├── org.jpg │ │ ├── fast_bilat.m │ │ ├── hdr_img.jpeg │ │ ├── ldr_img.jpeg │ │ ├── simple_bf_tm.asv │ │ ├── simple_bf_tm.m │ │ ├── bilateral128_1.jpg │ │ ├── office.hdr_fastBF.jpg │ │ ├── ldr_img_30 5 2 1 128 1.jpeg │ │ ├── ldr_img_30 2 8 0.2 64 1.jpeg │ │ ├── ldr_img_30 5 2 0.12 64 1.jpeg │ │ ├── ldr_img_30 10 8 0.2 64 1.jpeg │ │ ├── ldr_img_30 10 8 0.2 64 0.5.jpeg │ │ ├── ldr_img30 5 2 0.12 128 1.jpeg │ │ ├── ldr_img_256 5 2 0.12 128 1.jpeg │ │ ├── ldr_img_30 1 2 0.12 128 1.jpeg │ │ ├── ldr_img_30 5 2 0.12 128 1.jpeg │ │ ├── fast_bilat_demo.m │ │ ├── simple_bf_tm_demo.asv │ │ └── simple_bf_tm_demo.m │ └── 1997TVCG_HDR_ToneMapping.pdf └── mit_cp_probelm_set3 │ ├── simple_bf_tm.m │ └── simple_bf_tm.asv ├── image_resize ├── Linear Methods for Image Interpolation.pdf ├── edge_guided_interpolation │ ├── test.m │ ├── demo.m │ ├── gauss_2d.m │ ├── calc_u_h.m │ ├── lmmse_interp.m │ ├── var_45_135.m │ ├── ow_interp.m │ ├── h_v_interp.m │ └── diag_interp.m └── cubic_convolution │ ├── Cubic splines for image interpolation and digital filtering.pdf │ ├── sample_rad.m │ ├── test_fft.m │ ├── cubic_kernel.m │ ├── fast_nn_resize.m │ ├── kernel_frequency_demo.m │ ├── bilinear_resize.m │ ├── cubic_conv.m │ └── test_demo.m ├── demosaic ├── high_quality_linear_interp │ ├── High-quality Linear Interpolation for Demosaicing of Bayer-patterned Color Images.pdf │ └── grad_bilinear_demosaic.m ├── tools │ └── mosaic.m ├── demosaic_demo.m └── demosaic_bilinear.m ├── Algorithms.md ├── image_denoise ├── nl_mean_demo.m └── nl_mean.m ├── maths └── optimization │ ├── lmlsq_demo.m │ └── lmlsq.m └── stereo_vision └── rectification ├── estimateFundamentalMatrixDemo.m ├── estimateFundamentalMatrixNorm8Points.m └── estimateFundamentalMatrixRANSAC.m /.gitignore: -------------------------------------------------------------------------------- 1 | /temp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Image-Processing -------------------------------------------------------------------------------- /tools/imbilateral.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/imbilateral.m -------------------------------------------------------------------------------- /tools/cumsum_image.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/cumsum_image.m -------------------------------------------------------------------------------- /tools/imbilateral.asv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/imbilateral.asv -------------------------------------------------------------------------------- /structure_detect/canny.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/structure_detect/canny.m -------------------------------------------------------------------------------- /data/stereo_vision/img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/data/stereo_vision/img1.png -------------------------------------------------------------------------------- /data/stereo_vision/img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/data/stereo_vision/img2.png -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/org.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/org.jpg -------------------------------------------------------------------------------- /data/stereo_vision/madera_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/data/stereo_vision/madera_1.jpg -------------------------------------------------------------------------------- /data/stereo_vision/madera_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/data/stereo_vision/madera_2.jpg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/fast_bilat.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/fast_bilat.m -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/hdr_img.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/hdr_img.jpeg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img.jpeg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/simple_bf_tm.asv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/simple_bf_tm.asv -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/simple_bf_tm.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/simple_bf_tm.m -------------------------------------------------------------------------------- /tools/3rdparty/color_science/grey.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/grey.mat -------------------------------------------------------------------------------- /tools/3rdparty/color_science/test.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/test.mat -------------------------------------------------------------------------------- /hdr/mit_cp_probelm_set3/simple_bf_tm.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/mit_cp_probelm_set3/simple_bf_tm.m -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/bilateral128_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/bilateral128_1.jpg -------------------------------------------------------------------------------- /tools/3rdparty/color_science/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/Thumbs.db -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cc_lin.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/cc_lin.tif -------------------------------------------------------------------------------- /tools/3rdparty/color_science/keele.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/keele.mat -------------------------------------------------------------------------------- /tools/3rdparty/color_science/locus.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/locus.mat -------------------------------------------------------------------------------- /tools/3rdparty/color_science/rgb_cc.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/rgb_cc.mat -------------------------------------------------------------------------------- /tools/3rdparty/color_science/train.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/train.mat -------------------------------------------------------------------------------- /tools/3rdparty/color_science/xyz_cc.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/xyz_cc.mat -------------------------------------------------------------------------------- /hdr/mit_cp_probelm_set3/simple_bf_tm.asv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/mit_cp_probelm_set3/simple_bf_tm.asv -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/office.hdr_fastBF.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/office.hdr_fastBF.jpg -------------------------------------------------------------------------------- /tools/3rdparty/color_science/MBlocus.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/MBlocus.mat -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cc_lin_sp.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/cc_lin_sp.tif -------------------------------------------------------------------------------- /tools/3rdparty/color_science/halftone.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/halftone.mat -------------------------------------------------------------------------------- /tools/3rdparty/color_science/phosphors.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/phosphors.mat -------------------------------------------------------------------------------- /tools/3rdparty/color_science/weights.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/weights.mat -------------------------------------------------------------------------------- /hdr/tone_mapping/1997TVCG_HDR_ToneMapping.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/1997TVCG_HDR_ToneMapping.pdf -------------------------------------------------------------------------------- /tools/3rdparty/toolbox_v1.3_color_science.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/toolbox_v1.3_color_science.zip -------------------------------------------------------------------------------- /tools/3rdparty/color_science/fundamentals_ss.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/color_science/fundamentals_ss.mat -------------------------------------------------------------------------------- /data/denoise/lena_noised_gaussian_sigma=20_multi_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/data/denoise/lena_noised_gaussian_sigma=20_multi_2.png -------------------------------------------------------------------------------- /image_resize/Linear Methods for Image Interpolation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/image_resize/Linear Methods for Image Interpolation.pdf -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img_30 5 2 1 128 1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img_30 5 2 1 128 1.jpeg -------------------------------------------------------------------------------- /image_resize/edge_guided_interpolation/test.m: -------------------------------------------------------------------------------- 1 | a = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]; 2 | b = [0.25, 0.25; 0.25 0.25]; 3 | 4 | pad_a = padarray(a,[0,2],'symmetric','both') 5 | 6 | conv_a_b = conv2(pad_a,b,'valid') -------------------------------------------------------------------------------- /tools/3rdparty/%5BStephen_Westland%2C_Caterina_Ripamonti%2C_Vien_Cheung(b-ok.xyz).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/tools/3rdparty/%5BStephen_Westland%2C_Caterina_Ripamonti%2C_Vien_Cheung(b-ok.xyz).pdf -------------------------------------------------------------------------------- /image_resize/cubic_convolution/Cubic splines for image interpolation and digital filtering.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/image_resize/cubic_convolution/Cubic splines for image interpolation and digital filtering.pdf -------------------------------------------------------------------------------- /tools/imbilateral_demo.asv: -------------------------------------------------------------------------------- 1 | filename = '../temp/data/lena.jpg'; 2 | image = rgb2gray(imread(filename)); 3 | wsize = 5; 4 | sigma_d = 2; 5 | sigam_r = 0.12; 6 | figure('orginal image' 7 | bilater_image = imbilateral( image, wsize, sigma_d, sigam_r) -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img_30 2 8 0.2 64 1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img_30 2 8 0.2 64 1.jpeg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img_30 5 2 0.12 64 1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img_30 5 2 0.12 64 1.jpeg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img_30 10 8 0.2 64 1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img_30 10 8 0.2 64 1.jpeg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img_30 10 8 0.2 64 0.5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img_30 10 8 0.2 64 0.5.jpeg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img30 5 2 0.12 128 1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img30 5 2 0.12 128 1.jpeg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img_256 5 2 0.12 128 1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img_256 5 2 0.12 128 1.jpeg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img_30 1 2 0.12 128 1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img_30 1 2 0.12 128 1.jpeg -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/ldr_img_30 5 2 0.12 128 1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/hdr/tone_mapping/fbf/ldr_img_30 5 2 0.12 128 1.jpeg -------------------------------------------------------------------------------- /demosaic/high_quality_linear_interp/High-quality Linear Interpolation for Demosaicing of Bayer-patterned Color Images.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShenQM/Image-Processing/HEAD/demosaic/high_quality_linear_interp/High-quality Linear Interpolation for Demosaicing of Bayer-patterned Color Images.pdf -------------------------------------------------------------------------------- /image_resize/edge_guided_interpolation/demo.m: -------------------------------------------------------------------------------- 1 | clear; 2 | close all; 3 | file_name = '../../temp/data/lena.jpg'; 4 | 5 | image = imread(file_name); 6 | image = rgb2gray(image); 7 | image = tril(ones(size(image)),0); 8 | figure('name','original image'); 9 | imshow(image); 10 | 11 | resized_image = ow_interp(image, 'linear'); 12 | -------------------------------------------------------------------------------- /image_resize/cubic_convolution/sample_rad.m: -------------------------------------------------------------------------------- 1 | function [ sampled_array ] = sample_rad( h, sampled_sz ) 2 | %SAMPLE_RAD Summary of this function goes here 3 | % Detailed explanation goes here 4 | x = (0:sampled_sz(2)-1)*h(2); 5 | y = (0:sampled_sz(1)-1)*h(1); 6 | [X, Y] = meshgrid(x, y); 7 | sampled_array = sin(0.5.*(X.^2 + Y.^2)); 8 | end 9 | 10 | -------------------------------------------------------------------------------- /image_resize/cubic_convolution/test_fft.m: -------------------------------------------------------------------------------- 1 | nn_kernel_x = -0.5:0.01:0.5; 2 | nn_kernel_y = ones(size(nn_kernel_x)); 3 | L = size(nn_kernel_y,2); 4 | Y = fft(nn_kernel_y); 5 | P2 = abs(Y/L); 6 | P1 = P2(1:L/2+1); 7 | P1(2:end-1) = 2*P1(2:end-1); 8 | Fs = 100; 9 | f = Fs*(0:(L/2))/L; 10 | plot(f,P1) 11 | title('Single-Sided Amplitude Spectrum of X(t)') 12 | xlabel('f (Hz)') 13 | ylabel('|P1(f)|') -------------------------------------------------------------------------------- /image_resize/edge_guided_interpolation/gauss_2d.m: -------------------------------------------------------------------------------- 1 | function [ output_kernel ] = gauss_2d( x, y, sigma ) 2 | %GAUSS_2D Summary of this function goes here 3 | % Detailed explanation goes here 4 | [X, Y] = meshgrid(x, y); 5 | output_kernel = exp(-(X.^2+Y.^2)./(sigma.^2)./2); 6 | % sz = size(output_kernel); 7 | % output_kernel(sz(1)/2+1, sz(2)/2+1) = 0; 8 | output_kernel = output_kernel/sum(output_kernel(:)); 9 | end 10 | 11 | -------------------------------------------------------------------------------- /tools/imbilateral_demo.m: -------------------------------------------------------------------------------- 1 | close all; 2 | filename = 'E:\Projects\Image-Processing\temp\data\lena.jpg'; 3 | image = rgb2gray(imread(filename)); 4 | wsize = 5; 5 | sigma_d = 5; 6 | sigam_r = 5; 7 | figure('name','orginal image'); 8 | imshow(image); 9 | imwrite(image, 'org.jpg'); 10 | bilateral_image = uint8(imbilateral( image, wsize, sigma_d, sigam_r)); 11 | figure('name','bilateral filtered image'); 12 | imshow(bilateral_image); 13 | imwrite(bilateral_image, 'bilateral.jpg'); -------------------------------------------------------------------------------- /demosaic/tools/mosaic.m: -------------------------------------------------------------------------------- 1 | function [ cfa_image ] = mosaic( rgb_image, cfa_pattern ) 2 | %MOSAIC Summary of this function goes here 3 | % Detailed explanation goes here 4 | cfa_image = zeros(size(rgb_image,1), size(rgb_image,2)); 5 | start_point = [1, 1; 1, 2; 2, 1; 2, 2]; 6 | for i = 1:4 7 | cfa_image(start_point(i,1):2:end, start_point(i,2):2:end) = ... 8 | rgb_image(start_point(i,1):2:end, start_point(i,2):2:end, cfa_pattern(i)); 9 | end 10 | end 11 | 12 | -------------------------------------------------------------------------------- /Algorithms.md: -------------------------------------------------------------------------------- 1 | # Implemented algorithms instructions 2 | 3 | ## 1.Image Processing 4 | 5 | Canny edge detection algorithm steps: 6 | 7 | 1. Gaussian filter(denoise). 8 | 2. Calculate intensity and directions of image gradient. 9 | 3. Non-max suppression of the gradient according to gradient direction. 10 | 4. Double threshold detection get weak edges and strong edges. 11 | 5. Tracking edges by hysteresis. 12 | 13 | 14 | 15 | ## 2.Math Tools 16 | 17 | ### 2.1 Optimization 18 | 19 | #### 2.1.1 Levenberg-Marquardt Method 20 | 21 | -------------------------------------------------------------------------------- /image_resize/edge_guided_interpolation/calc_u_h.m: -------------------------------------------------------------------------------- 1 | function [ u_h ] = calc_u_h( input_image, half_sz, sigma) 2 | %CALC_U_H Summary of this function goes here 3 | % Detailed explanation goes here 4 | dist = 2*half_sz-1; 5 | x = -dist:2:dist; 6 | y = x; 7 | kernel_sz = size(x,2)/2; 8 | gauss_kernel_2d = gauss_2d(x, y, sigma); 9 | 10 | % Calculate u_h 11 | pad_input_image = padarray(input_image,[kernel_sz-1, kernel_sz-1], 'pre'); 12 | pad_input_image = padarray(pad_input_image,[kernel_sz, kernel_sz], 'post'); 13 | u_h = conv2(pad_input_image, gauss_kernel_2d, 'valid'); 14 | end 15 | 16 | -------------------------------------------------------------------------------- /image_denoise/nl_mean_demo.m: -------------------------------------------------------------------------------- 1 | dbstop if error; 2 | close all; 3 | file_name = 'data/denoise/lena_noised_gaussian_sigma=20_multi_2.png'; 4 | sigma = 20; 5 | k = 0.4; 6 | half_patch_sz = 3; 7 | half_search_sz = 10; 8 | 9 | image = imread(file_name); 10 | image_gray = rgb2gray(image); 11 | image_gray = double(image_gray); 12 | 13 | image_gray_denoise = nl_mean(image_gray, sigma, k, half_patch_sz, half_search_sz); 14 | 15 | figure('name', 'nonlocal mean denoise test'); 16 | subplot(1,2,1); 17 | imshow(image_gray/255); 18 | title('original image'); 19 | 20 | subplot(1,2,2); 21 | imshow(image_gray_denoise/255); 22 | title('denoised image'); -------------------------------------------------------------------------------- /structure_detect/canny_demo.m: -------------------------------------------------------------------------------- 1 | clear; 2 | close all; 3 | dbstop if error; 4 | file_name = 'data/denoise/lena_noised_gaussian_sigma=20_multi_2.png'; 5 | image = imread(file_name); 6 | low_thresh = 0.05; 7 | high_thresh = 0.15; 8 | kernel_sz = 7; 9 | sigma = 2; 10 | [ edges ] = canny(image, kernel_sz, sigma, low_thresh, high_thresh); 11 | figure('name','canny edge detect'); 12 | subplot(2,2,1); 13 | imshow(image); 14 | title('orige'); 15 | subplot(2,2,2); 16 | imshow(edges); 17 | title('edge'); 18 | gray_image = rgb2gray(image); 19 | edge_matlab = edge(gray_image, 'canny'); 20 | subplot(2,2,3); 21 | imshow(edge_matlab); 22 | title('edge_matlab'); -------------------------------------------------------------------------------- /image_resize/cubic_convolution/cubic_kernel.m: -------------------------------------------------------------------------------- 1 | function [ kernel_res ] = cubic_kernel( s ) 2 | kernel_res = zeros(size(s)); 3 | kernel_res(abs(s)0 & s < 1)) = kernel_0_1(s(s>0 & s < 1)); 7 | kernel_res((s>1 & s < 2)) = kernel_1_2(s(s>1 & s < 2)); 8 | end 9 | 10 | function [ kernel_res ] = kernel_0_1( s ) 11 | s2 = s.*s; 12 | s3 = s2.*s; 13 | kernel_res = 1.5*s3 - 2.5*s2 + 1; 14 | end 15 | 16 | function [ kernel_res ] = kernel_1_2( s ) 17 | s2 = s.*s; 18 | s3 = s2.*s; 19 | kernel_res = -0.5*s3 + 2.5*s2 - 4*s + 2; 20 | end 21 | -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/fast_bilat_demo.m: -------------------------------------------------------------------------------- 1 | close all; 2 | filename = 'E:\Projects\data\jpeg\lena.jpg'; 3 | % image = hdrread(filename); 4 | image = rgb2gray(imread(filename)); 5 | wsize = 3; 6 | sigma_s = 5; 7 | sigma_r = 25; 8 | num_seg = 256; 9 | scale = 1; 10 | figure('name','orginal image'); 11 | imshow(image); 12 | imwrite(image, 'org.jpg'); 13 | %bilateral_image = uint8(imbilateral( image, wsize, sigma_d, sigam_r)); 14 | [ bilateral_image ] = fast_bilat( image, num_seg, wsize, sigma_s, sigma_r, scale ); 15 | bilateral_image = uint8(bilateral_image); 16 | figure('name','bilateral filtered image'); 17 | imshow(bilateral_image, []); 18 | imwrite(bilateral_image, [filename, num2str(num_seg) '_', num2str(scale), '.jpg']); -------------------------------------------------------------------------------- /tools/3rdparty/color_science/srgb2xyz.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION srgb2xyz 3 | % *** 4 | % *** function [XYZ] = srgb2xyz(RGB) 5 | % *** computes XYZ from 8-bit RGB 6 | % *** RGB is n by 3 and in the range 0-255 7 | % *** XYZ is returned in the range 0-1 8 | % *** see also xyz2srgb 9 | function [XYZ] = srgb2xyz(RGB) 10 | if (size(RGB,2)~=3) 11 | disp('RGB must be n by 3'); return; 12 | end 13 | 14 | XYZ = zeros(size(RGB)); 15 | 16 | M = [0.4124 0.3576 0.1805; 0.2126 0.7152 0.0722; 0.0193 0.1192 0.9505]; 17 | 18 | DACS=RGB/255; 19 | RGB = zeros(size(RGB)); 20 | 21 | index = (DACS<=0.04045); 22 | RGB = RGB + (index).*(DACS/12.92); 23 | RGB = RGB + (1-index).*((DACS+0.055)/1.055).^2.4; 24 | 25 | XYZ = (M*RGB')'; 26 | 27 | end -------------------------------------------------------------------------------- /tools/3rdparty/color_science/xyz2srgb.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION xyz2srgb 3 | % *** 4 | % *** function [RGB] = xyz2srgb(XYZ) 5 | % *** computes 8-bit sRGB from XYZ 6 | % *** XYZ is n by 3 and in the range 0-1 7 | % *** see also srgb2xyz 8 | function [RGB] = xyz2srgb(XYZ) 9 | if (size(XYZ,2)~=3) 10 | disp('XYZ must be n by 3'); return; 11 | end 12 | 13 | M = [3.2406 -1.5372 -0.4986; -0.9689 1.8758 0.0415; 0.0557 -0.2040 1.0570]; 14 | 15 | RGB = (M*XYZ')'; 16 | 17 | 18 | RGB(RGB<0) = 0; 19 | RGB(RGB>1) = 1; 20 | 21 | DACS = zeros(size(XYZ)); 22 | index = (RGB<=0.0031308); 23 | DACS = DACS + (index).*(12.92*RGB); 24 | DACS = DACS + (1-index).*(1.055*RGB.^(1/2.4)-0.055); 25 | 26 | RGB=ceil(DACS*255); 27 | RGB(RGB<0) = 0; 28 | RGB(RGB>255) = 255; 29 | end -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cband.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cband 3 | % *** 4 | % *** Stearns-Stearns spectral bandpass correction 5 | % *** operates on matrix P of dimensions n by m 6 | % *** n spectra each at m wavelengths 7 | % =================================================== 8 | function [p] = cband(p) 9 | 10 | a = 0.083; 11 | dim = size(p); 12 | n = dim(1); 13 | 14 | % the first and last wavelengths 15 | p(1,:) = (1 + a)*p(1,:) - a*p(2,:); 16 | p(n,:) = (1 + a)*p(n,:) - a*p(n-1,:); 17 | % al the other wavelengths 18 | for i=2:n-1 19 | p(i,:) = -a*p(i-1,:) + (1 + 2*a)*p(i,:) - a*p(i+1,:); 20 | end 21 | 22 | end 23 | % ==================================================== 24 | % *** END FUNCTION cband 25 | % ==================================================== 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/simple_bf_tm_demo.asv: -------------------------------------------------------------------------------- 1 | close all; 2 | dbstop if error; 3 | filename = 'E:\Projects\data\hdr\office.hdr'; 4 | out_range = 30; 5 | wsize = 2; 6 | sigma_s = 8; 7 | sigma_r = 0.2; 8 | num_seg = 64; 9 | scale = 1; 10 | 11 | hdr_img = hdrread(filename); 12 | 13 | figure('name', 'hdr_linear'); 14 | min_hdr = min(hdr_img(:)); 15 | max_hdr 16 | 17 | ldr_img = simple_bf_tm(hdr_img, out_range, wsize, sigma_s, sigma_r, num_seg, scale); 18 | %ldr_img = tonemap(hdr_img); 19 | figure('name','hdr image'); 20 | imshow(hdr_img, []); 21 | imwrite(hdr_img, 'hdr_img.jpeg'); 22 | figure('name','ldr image'); 23 | imshow(ldr_img, []); 24 | imwrite(ldr_img, ['ldr_img_', num2str([out_range, wsize, sigma_s, sigma_r, num_seg, scale]),'.jpeg']); 25 | imwrite(ldr_img, [filename, num2str([out_range, wsize, sigma_s, sigma_r, num_seg, scale]),'.jpeg']); 26 | 27 | 28 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/rgb2lms.m: -------------------------------------------------------------------------------- 1 | % ================================================================= 2 | % *** FUNCTION rgb2lms 3 | % *** 4 | % *** function [lms] = rgb2lms(phosphors,fundamentals,rgb) 5 | % *** computes lms from rgb. 6 | % *** phosphors is an n by 3 matrix containing 7 | % *** the three spectral power distributions of the display device 8 | % *** fundamentals is an n x 3 matrix containing 9 | % *** the rgb are the rgb values of the display device. 10 | % *** the lms are the cone spectral sensitivities. 11 | % ================================================================= 12 | function [lms] = rgb2lms(phosphors,fundamentals,rgb) 13 | 14 | % Compute lms from rgb. 15 | rgbTOlms = fundamentals'*phosphors; 16 | lms = rgbTOlms * rgb; 17 | % =================================================== 18 | % *** END FUNCTION rgb2lms 19 | % =================================================== -------------------------------------------------------------------------------- /tools/3rdparty/color_science/lms2rgb.m: -------------------------------------------------------------------------------- 1 | % ================================================================ 2 | % *** FUNCTION lms2rgb 3 | % *** 4 | % *** function [rgb] = lms2rgb(phosphors,fundamentals,lms) 5 | % *** computes rgb from lms. 6 | % *** phosphors is an n by 3 matrix containing 7 | % *** the three spectral power distributions of the display device 8 | % *** fundamentals is an n x 3 matrix containing 9 | % *** the lms are the cone spectral sensitivities. 10 | % *** the rgb are the rgb values of the display device. 11 | % ================================================================ 12 | function [rgb] = lms2rgb(phosphors,fundamentals,lms) 13 | 14 | % Compute lms from rgb. 15 | rgbTOlms = fundamentals'*phosphors; 16 | lmsTOrgb = inv(rgbTOlms); 17 | rgb = lmsTOrgb * lms; 18 | % =================================================== 19 | % *** END FUNCTION lms2rgb 20 | % =================================================== -------------------------------------------------------------------------------- /tools/paddarray_symmetric.m: -------------------------------------------------------------------------------- 1 | function [ padded_array ] = paddarray_symmetric( input_array, pad_sz ) 2 | %PADDARRAY_SYMMETRIC Pad the array using symmetric method. 3 | % Using the board row/column as the symmetry axises. 4 | % Detailed explanation goes here 5 | org_sz = size(input_array); 6 | padded_sz = org_sz + pad_sz + pad_sz; 7 | padded_array = zeros(padded_sz); 8 | padded_array(pad_sz+1:pad_sz+org_sz(1),pad_sz+1:pad_sz+org_sz(2)) = input_array; 9 | 10 | % add left 11 | padded_array(:,1:pad_sz) = flip(padded_array(:,pad_sz+2:pad_sz+pad_sz+1),2); 12 | % add right 13 | padded_array(:,end-pad_sz+1:end) = flip(padded_array(:,end-pad_sz-pad_sz:end-pad_sz-1),2); 14 | % add top 15 | padded_array(1:pad_sz,:) = flip(padded_array(pad_sz+2:pad_sz+pad_sz+1,:),1); 16 | % add bottom 17 | padded_array(end-pad_sz+1:end,:) = flip(padded_array(end-pad_sz-pad_sz:end-pad_sz-1,:),1); 18 | end 19 | 20 | -------------------------------------------------------------------------------- /maths/optimization/lmlsq_demo.m: -------------------------------------------------------------------------------- 1 | clear; 2 | close all; 3 | 4 | %Example 1: Rosenbrock's Valley 5 | rosen = @(x) [10*(x(2)-x(1)^2) 6 | 1-x(1)]; 7 | rosen_jac = @(x) [-20*x(1), 10; 8 | -1, 0]; 9 | x0 = [1.2; -0.8]; 10 | maxiter = 100; 11 | tao = 0.001; 12 | ks1 = 1e-7; 13 | ks2 = 1e-7; 14 | %[x_res, x_iter, f_iter, cnt] = lmlsq(rosen, rosen_jac, x0, maxiter, tao, ks1, ks2); 15 | [x_res, x_iter, f_iter, cnt] = lmlsq(rosen, x0); %without analyze jacobian 16 | %[x_res, x_iter, f_iter, cnt] = lmlsq(rosen, x0, 'jacobian', rosen_jac); 17 | 18 | x = -2:0.01:2; 19 | y = -1:0.01:3; 20 | [X,Y] = meshgrid(x,y); 21 | Z = zeros(size(X)); 22 | for i = 1:size(x,2) 23 | for j = 1:size(y,2) 24 | f = feval(rosen, [x(i),y(j)]); 25 | Z(i,j) = 0.5*(f'*f); 26 | end 27 | end 28 | contour(X,Y,Z); 29 | rosen_val = sum(f_iter.^2,1); 30 | hold on; 31 | plot(x_iter(1,1:cnt),x_iter(2,1:cnt),'ro-'); -------------------------------------------------------------------------------- /hdr/tone_mapping/fbf/simple_bf_tm_demo.m: -------------------------------------------------------------------------------- 1 | close all; 2 | dbstop if error; 3 | filename = 'E:\Projects\data\hdr\office.hdr'; 4 | out_range = 30; 5 | wsize = 2; 6 | sigma_s = 8; 7 | sigma_r = 0.2; 8 | num_seg = 64; 9 | scale = 1; 10 | 11 | hdr_img = hdrread(filename); 12 | 13 | figure('name', 'hdr_linear'); 14 | min_hdr = min(hdr_img(:)); 15 | max_hdr = max(hdr_img(:)); 16 | linear_hdr = (hdr_img - min_hdr) ./ (max_hdr - min_hdr) + min_hdr; 17 | imshow(linear_hdr); 18 | ldr_img = simple_bf_tm(hdr_img, out_range, wsize, sigma_s, sigma_r, num_seg, scale); 19 | %ldr_img = tonemap(hdr_img); 20 | figure('name','hdr image'); 21 | imshow(hdr_img, []); 22 | imwrite(hdr_img, 'hdr_img.jpeg'); 23 | figure('name','ldr image'); 24 | imshow(ldr_img, []); 25 | imwrite(ldr_img, ['ldr_img_', num2str([out_range, wsize, sigma_s, sigma_r, num_seg, scale]),'.jpeg']); 26 | imwrite(ldr_img, [filename, num2str([out_range, wsize, sigma_s, sigma_r, num_seg, scale]),'.jpeg']); 27 | 28 | 29 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/temp_test.m: -------------------------------------------------------------------------------- 1 | xy=[0 0; 1 0; 0.5 0.866]; 2 | col=[1 0 0; 0 1 0; 0 0 1]; 3 | patch('Vertices',xy, 'Faces',[1:size(xy,1)],... 4 | 'EdgeColor','none','FaceVertexCData',... 5 | col,'FaceColor','interp'); 6 | axis off 7 | 8 | figure(2) 9 | red = [30.24 17.30 2.03]; 10 | green = [30.19 61.00 10.81]; 11 | blue = [18.62 8.99 100.82]; 12 | white = [77.00 85.40 108.72]; 13 | w = [1 1 1]; 14 | r = [1 0 0]; 15 | g = [0 1 0]; 16 | b = [0 0 1]; 17 | k = [0 0 0]; 18 | rxy = [red(1)/sum(red) red(2)/sum(red) red(2)]; 19 | gxy = [green(1)/sum(green) green(2)/sum(green) green(2)]; 20 | bxy = [blue(1)/sum(blue) blue(2)/sum(blue) blue(2)]; 21 | wxy = [white(1)/sum(white) white(2)/sum(white) white(2)]; 22 | kxy = [white(1)/sum(white) white(2)/sum(white) 0]; 23 | v = [rxy; gxy; bxy; wxy; kxy]; 24 | c = [r; g; b; w; k]; 25 | f = [1 2 4; 1 2 5; 1 3 4; 1 3 5; 2 3 4; 2 3 5]; 26 | patch('Vertices',v, 'Faces',f, 'EdgeColor','none',... 27 | 'FaceVertexCData',c,'FaceColor','interp') -------------------------------------------------------------------------------- /tools/3rdparty/color_science/plotFundamentals.m: -------------------------------------------------------------------------------- 1 | function plotFundamentals 2 | % PLOTFUNDAMENTALS Plot the selected cone sensitivities. 3 | %-------------------------------------------------------------------------- 4 | % plotFundamentals 5 | % ========= 6 | % 7 | % The function plots the cone fundamentls. 8 | % 9 | % Usage 10 | % ===== 11 | % plotFuntadentals(fundamentals) 12 | % 13 | % Parameters 14 | % ========== 15 | % 16 | % fundamentals - This is a matrix Nx3 containing the selected 17 | % cone sensitivities. 18 | % 19 | % 20 | % 28-Nov -2011 kr Wrote it. 21 | 22 | % Define wavelength range. 23 | wavelength=linspace(390,780,391) 24 | load fundamentals_ss 25 | 26 | figure(1) 27 | set(gcf,'color','w') 28 | plot(wavelength, fundamentals(:,1),'r-', 'LineWidth',2) ; hold on 29 | plot(wavelength, fundamentals(:,2),'g-', 'LineWidth',2) ; hold on 30 | plot(wavelength, fundamentals(:,3),'b-', 'LineWidth',2) ; hold on 31 | 32 | xlabel('wavelength (nm)','FontSize',9); ylabel('sensitivity','FontSize',9); 33 | axis([390 780 0 1]); -------------------------------------------------------------------------------- /image_resize/cubic_convolution/fast_nn_resize.m: -------------------------------------------------------------------------------- 1 | function [ resized_image ] = fast_nn_resize( input_image, scaled_size) 2 | %FAST_NN_RESIZE Neareast algorithm for image resize use vector operation. 3 | % input_image -- Image to be resized. 4 | % scale -- Resize factor. 5 | % resized_image -- Resized image. 6 | 7 | %2. Get the coordinates of reized image pixels in the original 8 | org_sz = [size(input_image,1), size(input_image,2)]; 9 | resized_image = zeros([scaled_size(1), scaled_size(2), size(input_image,3)]); 10 | delta_scaled = scaled_size - 1; 11 | delta_org = org_sz - 1; 12 | r_idx = round(((1:scaled_size(1))-1)*delta_org(1)/delta_scaled(1)+1); 13 | c_idx = round(((1:scaled_size(2))-1)*delta_org(2)/delta_scaled(2)+1); 14 | %r_idx(r_idx < 1) = 1; 15 | %c_idx(c_idx < 1) = 1; 16 | r_idx = repmat(r_idx', 1, scaled_size(2)); 17 | c_idx = repmat(c_idx, scaled_size(1), 1); 18 | idx = (c_idx-1)*size(input_image,1) + r_idx; 19 | 20 | %3. Get the scaled image 21 | for k_channel = 1:size(input_image,3) 22 | sub_channel = input_image(:,:,k_channel); 23 | resized_image(:,:,k_channel) = sub_channel(idx); 24 | end 25 | end 26 | 27 | -------------------------------------------------------------------------------- /demosaic/demosaic_demo.m: -------------------------------------------------------------------------------- 1 | close all; 2 | dbstop if error; 3 | file_name = '..\temp\data\kodak_image_set\kodim07.png'; 4 | file_name = '..\temp\data\lena.jpg'; 5 | 6 | rgb_image = imread(file_name); 7 | cfa_pattern = [1 2 2 3]; 8 | cfa_image = mosaic(rgb_image, cfa_pattern); 9 | imwrite(uint8(cfa_image), '..\temp\data\mosaic_image.jpg'); 10 | 11 | demosaiced_image_linear = demosaic_bilinear(cfa_image, cfa_pattern); 12 | biliner_snr = psnr(uint8(demosaiced_image_linear), rgb_image) 13 | figure('name', 'bilinear demosaic'); 14 | imshow(uint8(demosaiced_image_linear)); 15 | imwrite(uint8(demosaiced_image_linear), '..\temp\data\demosaic_bilinear.png'); 16 | 17 | demosaiced_image_grad = grad_bilinear_demosaic(cfa_image, cfa_pattern); 18 | figure('name', 'grad based bilinear demosaic'); 19 | grad_biliner_snr = psnr(uint8(demosaiced_image_grad), rgb_image) 20 | imshow(uint8(demosaiced_image_grad)); 21 | imwrite(uint8(demosaiced_image_grad), '..\temp\data\demosaic_grad_bilinear.png'); 22 | 23 | demosaiced_matlab = demosaic(uint8(cfa_image), 'rggb'); 24 | demosaiced_matlab_snr = psnr(uint8(demosaiced_matlab), rgb_image) 25 | figure('name', 'matlab demosaic'); 26 | imshow(uint8(demosaiced_matlab)); 27 | imwrite(uint8(demosaiced_matlab), '..\temp\data\demosaic_matlab.png'); 28 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/plotDeviceSPDs.m: -------------------------------------------------------------------------------- 1 | function plotDeviceSPDs 2 | % PLOTFUNDAMENTALS Plot the selected cone sensitivities. 3 | %-------------------------------------------------------------------------- 4 | % plotFundamentals 5 | % ========= 6 | % 7 | % The function plots the display device SPDs. 8 | % 9 | % Usage 10 | % ===== 11 | % plotDeviceSPDs 12 | % 13 | % Parameters 14 | % ========== 15 | % 16 | % phosphors - This is a matrix Nx3 containing the spectral power 17 | % distributions of the monitor. 18 | % 19 | % 20 | % 28-Nov -2011 kr Wrote it. 21 | 22 | % Define wavelength range. 23 | wavelength = linspace(390,780,391) 24 | load phosphors 25 | 26 | figure(2) 27 | set(gcf,'color','w') 28 | plot(wavelength, phosphors(:,1),'r-', 'LineWidth',2) ; hold on 29 | plot(wavelength, phosphors(:,2),'g-', 'LineWidth',2) ; hold on 30 | plot(wavelength, phosphors(:,3),'b-', 'LineWidth',2) ; hold on 31 | 32 | xlabel('wavelength (nm)','FontSize',9); ylabel('radiance (W/sr*sqm)','FontSize',9); 33 | % Scale y-axis according to maximum peak. 34 | peak1=max(phosphors(:,1)); 35 | peak2=max(phosphors(:,2)); 36 | peak3=max(phosphors(:,3)); 37 | peaks=[peak1 peak2 peak3]; 38 | [Ymax Imax]=max(peaks); 39 | axis([390 780 0 Ymax]); 40 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/lms2rgbMB.m: -------------------------------------------------------------------------------- 1 | % ============================================================ 2 | % *** FUNCTION lms2rgbMB 3 | % *** 4 | % *** function [rgbMB] = lms2rgbMB(lms,s) 5 | % *** computes rgbMB from lms. 6 | % *** lms is an n by 1 matrix containing 7 | % *** the l-,m-, and s-cone excitations 8 | % *** s is a 1 by n matrix containing the lms scaling factors. 9 | % *** rgbMB are the chromaticity coordinates in the 10 | % *** MacLeod and Boynton (1979) chromaticity diagram. 11 | % ============================================================ 12 | function [rgbMB] = lms2rgbMB(lms,s) 13 | % check number of input arguments. 14 | % if s is not provided, use default scaling factors valid 15 | % for the Stockman and Sharpe (2000) 2-deg fundamentals. 16 | % else use s. 17 | if nargin==1 18 | lms_scaling=[0.689903 0.348322 0.0371597]; 19 | else 20 | lms_scaling = s; 21 | end 22 | % rescale cone excitations. 23 | lms = diag(lms_scaling')*lms; 24 | % compute luminance 25 | luminance = lms(1)+ lms(2) 26 | % compute rgbMB chromaticities. 27 | rMB = lms(1)/luminance; 28 | gMB = lms(2)/luminance; 29 | bMB = lms(3)/luminance; 30 | rgbMB = [rMB gMB bMB]; 31 | % =================================================== 32 | % *** END FUNCTION lms2rgbMB 33 | % =================================================== -------------------------------------------------------------------------------- /image_resize/edge_guided_interpolation/lmmse_interp.m: -------------------------------------------------------------------------------- 1 | function [ output_args ] = lmmse_interp( input_image, scale, sigma1, sigma2 ) 2 | %LMMSE_INTERP Summary of this function goes here 3 | % Detailed explanation goes here 4 | org_sz = size(input_image); 5 | half_sz = 2; 6 | dist = 2*half_sz-1; 7 | x = -dist:2:dist; 8 | y = x; 9 | kernel_sz = size(x,2)/2; 10 | gauss_kernel_2d = gauss_2d(x, y, sigma1); 11 | 12 | % Calculate u_h 13 | pad_input_image = padarray(input_image,[kernel_sz-1, kernel_sz-1], 'pre'); 14 | pad_input_image = padarray(pad_input_image,[kernel_sz, kernel_sz], 'post'); 15 | ux = conv2(pad_input_image, gauss_kernel_2d, 'valid'); 16 | 17 | % Calculate sigma_h. 18 | ux_3d = repmat(ux, 1, 1, kernel_sz); 19 | temp_array = zeros(org_sz(1), org_sz(2), kernel_sz); 20 | kernel_1d = gauss_kernel_2d'; 21 | kernel_1d = kernel_1d(:); 22 | kernel_1d_3d = temp_array; 23 | idx = 1; 24 | for r = 1:2:2*dist+1 25 | for c = 1:2:2*dist+1 26 | temp_array(:,:,idx) = ((pad_input_image(r:r+org_sz(1)-1,... 27 | c:c+org_sz(2)-1) - ux).^2).*kernel_1d(idx); 28 | kernel_1d_3d(:,:,idx) = kernel_1d(idx); 29 | idx = idx + 1; 30 | end 31 | end 32 | sig_h = sum(temp_array,3); 33 | 34 | end 35 | 36 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Stephen Westland 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/rgbMB2lms.m: -------------------------------------------------------------------------------- 1 | % =================================================================== 2 | % *** FUNCTION rgbMB2lms 3 | % *** 4 | % *** function [lms] = rgbMB2lms(rgbMB,luminance,s) 5 | % *** computes lms from rgbMB. 6 | % *** lms is a 1 by n matrix containing 7 | % *** the l-,m-, and s-cone excitations 8 | % *** rgbMB is a 1 by n matrix which represents 9 | % *** the chromaticity coordinates in the 10 | % *** MacLeod and Boynton (1979) chromaticity diagram. 11 | % *** luminance is the sum of the scaled l_bar and m_bar excitations. 12 | % *** s is a 1 by n matrix containing the lms scaling factors. 13 | % ==================================================================== 14 | function [lms] = rgbMB2lms(rgbMB,luminance,s) 15 | % check number of input arguments. 16 | % if s is not provided, use default scaling factors valid 17 | % for the Stockman and Sharpe (2000) 2-deg fundamentals. 18 | % else use s. 19 | if nargin==2 20 | lms_scaling=[0.689903 0.348322 0.0371597]; 21 | else 22 | lms_scaling = s; 23 | end 24 | % compute scaled LMS from rgbMB and luminance. 25 | lms_scaled = rgbMB .* luminance 26 | % to obtain LMS excitations the previous LMS values need to be unscaled. 27 | % define LMS scaling according to which fundamentals are used. 28 | lms = lms_scaled./(lms_scaling); 29 | % ====================================================================== 30 | % *** END FUNCTION lms2rgbMB 31 | % ====================================================================== -------------------------------------------------------------------------------- /image_resize/edge_guided_interpolation/var_45_135.m: -------------------------------------------------------------------------------- 1 | function [ var_45, var_135 ] = var_45_135( input_image, u_h, half_sz, I_45, I_135, method ) 2 | %VAR_45_135M Summary of this function goes here 3 | % Detailed explanation goes here 4 | org_sz = size(input_image); 5 | var_45 = zeros(org_sz); 6 | var_135 = var_45; 7 | image_45 = zeros(2*org_sz(1), 2*org_sz(2)); 8 | image_135 = image_45; 9 | image_45(1:2:end,1:2:end) = input_image; 10 | image_45(2:2:end,2:2:end) = I_45; 11 | image_135(1:2:end,1:2:end) = input_image; 12 | image_135(2:2:end,2:2:end) = I_135; 13 | 14 | pad_image_45 = padarray(image_45, [half_sz-1,half_sz-1], 'symmetric', 'both'); 15 | pad_image_45 = padarray(pad_image_45, [1,1], 'symmetric', 'post'); 16 | pad_image_135 = padarray(image_135, [half_sz-1,half_sz-1], 'symmetric', 'both'); 17 | pad_image_135 = padarray(pad_image_135, [1,1], 'symmetric', 'post'); 18 | delta_45 = zeros(org_sz(1),org_sz(2),2*half_sz+1); 19 | delta_135 = delta_45; 20 | for i = 1:2*half_sz+1 21 | test = pad_image_135(i:org_sz(1)+i-1, i:org_sz(2)+i-1); 22 | delta_135(:,:,i) = pad_image_135(i:2:2*org_sz(1)+i-1, i:2:2*org_sz(2)+i-1) - u_h; 23 | j = 2*half_sz+1 - (i-1); 24 | test2 = pad_image_45(i:2:2*org_sz(1)+i-1, j:2:j+2*org_sz(2)-1); 25 | delta_45(:,:,i) = pad_image_45(i:2:2*org_sz(1)+i-1, j:2:j+2*org_sz(2)-1) - u_h; 26 | end 27 | 28 | if strcmp(method, 'abs') 29 | delta_45 = abs(delta_45); 30 | delta_135 = abs(delta_135); 31 | var_45 = (sum(delta_45,3)).^2; 32 | var_135 = (sum(delta_135,3)).^2; 33 | end 34 | end 35 | 36 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/dkl_sph2cart.m: -------------------------------------------------------------------------------- 1 | % ============================================================================== 2 | % *** FUNCTION dkl_sph2cart 3 | % *** 4 | % *** function [dkl_rad] = dkl_sph2cart(dkl_deg) 5 | % *** transforms dkl coordinates from radians to degrees 6 | % *** and then from spherical to Cartesian. 7 | % *** dkl_deg is a vector containing the DKL coordinates in degrees 8 | % *** in the order: [radius azimuth elevation] 9 | % *** dkl_rad is a vector containing the DKL coordinates in radians 10 | % *** in the order: [luminance; chromatic (L-M); chromatic S-(L+M)] in radians 11 | 12 | % ============================================================================== 13 | 14 | function [dkl_rad] = dkl_sph2cart(dkl_deg) 15 | 16 | % define radius, azimuth and elevation. 17 | radius = dkl_deg(1); 18 | azimuth_deg = dkl_deg(2); 19 | elevation_deg = -dkl_deg(3); 20 | % convert degrees into radians using the 21 | % MATLAB function degtorad. 22 | azimuth_rad = degtorad(azimuth_deg); 23 | elevation_rad = degtorad(elevation_deg); 24 | 25 | % convert spherical coordinates into Cartesian. 26 | if elevation_deg == 90 27 | lum = radius; 28 | rgisolum = 0; 29 | sisolum = 0; 30 | elseif elevation_deg == -90 31 | % target is along the luminance axis. 32 | lum = radius; 33 | rgisolum = 0; 34 | sisolum = 0; 35 | else 36 | radius = radius; 37 | lum = radius*tan(elevation_rad); 38 | chro_LM = radius*-cos(azimuth_rad); 39 | chro_S = radius*sin(azimuth_rad); 40 | end 41 | 42 | dkl_rad = [lum chro_LM chro_S]'; 43 | % =================================================== 44 | % *** END FUNCTION dkl_cart2sph 45 | % =================================================== -------------------------------------------------------------------------------- /image_resize/cubic_convolution/kernel_frequency_demo.m: -------------------------------------------------------------------------------- 1 | % Kernel shape 2 | % nearest kernel 3 | nn_kernel_x = -2:0.01:2; 4 | nn_kernel_y = ones(size(nn_kernel_x)); 5 | nn_kernel_y(abs(nn_kernel_x ) > 0.5) = 0; 6 | 7 | % linear kernel 8 | linear_x_neg = -2:0.01:0; 9 | linear_y_neg = linear_x_neg + 1; 10 | linear_x_pos = 0.01:0.01:2; 11 | linear_y_pos = 1 - linear_x_pos; 12 | linear_x = [linear_x_neg, linear_x_pos]; 13 | linear_y = [linear_y_neg, linear_y_pos]; 14 | linear_y(abs(linear_x) > 1) = 0; 15 | 16 | % cubic convolution kernel 17 | cubic_conv_x = -2:0.01:2; 18 | cubic_conv_y = cubic_kernel(abs(cubic_conv_x)); 19 | 20 | figure('Name', 'Interpolation kernels'); 21 | subplot(2,2,1); 22 | plot(nn_kernel_x, nn_kernel_y); 23 | ylim([0,1.5]); 24 | title('Nearest-neighbor'); 25 | subplot(2,2,2); 26 | plot(linear_x, linear_y); 27 | ylim([0,1.5]); 28 | title('Linear interpolation'); 29 | subplot(2,2,3); 30 | plot(cubic_conv_x, cubic_conv_y); 31 | ylim([-0.2,1.5]); 32 | title('Cubic convolution'); 33 | 34 | % Frequence response 35 | figure('Name', 'Kernel response'); 36 | u = 0:0.01:2; 37 | nn_response = abs(sinc(u)); 38 | % linear_response = (1 - cos(2*pi*u)) ./ (2*(pi*u).^2); 39 | linear_response = abs(sinc(u).^2); 40 | f0 = 3*(sinc(u).^2 - sinc(2*u))./(pi*u).^2; 41 | f1 = 2*(3*sinc(2*u).^2 - 2*sinc(2*u) - sinc(4*u)) ./ (pi*u).^2; 42 | a = -0.5; 43 | cubic_conv_response = abs(f0 + a*f1); 44 | ideal_x = 0:0.01:0.5; 45 | ideal_y = ones(size(ideal_x)); 46 | ideal_yy = 0:0.01:1; 47 | ideal_xx = ones(size(ideal_yy))*0.5; 48 | plot(u, nn_response, u, linear_response, u, cubic_conv_response, ideal_x, ideal_y,'r--', ideal_xx, ideal_yy,'r--'); 49 | ylim([0,1.1]); 50 | %plot(u, abs(linear_response)); 51 | legend('nearest neighbor', 'linear interpolation', 'cubic convolution','ideal'); -------------------------------------------------------------------------------- /image_resize/cubic_convolution/bilinear_resize.m: -------------------------------------------------------------------------------- 1 | function [ resized_image ] = bilinear_resize( input_image, scaled_size ) 2 | %BILINEAR_RESIZE Summary of this function goes here 3 | % Detailed explanation goes here 4 | 5 | %2 Get all coordinates 6 | org_sz = [size(input_image,1), size(input_image,2)]; 7 | resized_image = zeros([scaled_size(1), scaled_size(2), size(input_image,3)]); 8 | delta_scaled = scaled_size - 1; 9 | delta_org = org_sz - 1; 10 | x = ((1:scaled_size(2))-1)*delta_org(2)/delta_scaled(2)+1; 11 | y = ((1:scaled_size(1))-1)*delta_org(1)/delta_scaled(1)+1; 12 | %x(x<1) = 1; 13 | %y(y<1) = 1; 14 | x0 = floor(x); 15 | x0(end) = size(input_image,2) - 1; 16 | x1 = x0 + 1; 17 | %x1(x1>size(input_image,2)) = size(input_image,2); 18 | y0 = floor(y); 19 | y0(end) = size(input_image,1) - 1; 20 | y1 = y0 + 1; 21 | %y1(y1>size(input_image,1)) = size(input_image,1); 22 | 23 | x = repmat(x, size(input_image,1), 1); 24 | y = repmat(y', 1, scaled_size(2)); 25 | x0 = repmat(x0, size(input_image,1), 1); 26 | x1 = repmat(x1, size(input_image,1), 1); 27 | y0 = repmat(y0', 1, scaled_size(2)); 28 | y1 = repmat(y1', 1, scaled_size(2)); 29 | 30 | %3 Interploate 31 | for k_channel = 1:size(input_image, 3) 32 | %3.1 Interpolate along x axis 33 | sub_channel = input_image(:,:,k_channel); 34 | image_x0 = sub_channel(:,x0(1,:)); 35 | image_x1 = sub_channel(:,x1(1,:)); 36 | image_x = ((image_x1-image_x0)./(x1-x0)) .* (x-x0) + image_x0; 37 | %3.2 Interpolate along y axis 38 | image_y0 = image_x(y0(:,1),:); 39 | image_y1 = image_x(y1(:,2),:); 40 | resized_image = ((image_y1-image_y0)./(y1-y0)) .* (y-y0) + image_y0; 41 | end 42 | end 43 | 44 | -------------------------------------------------------------------------------- /image_resize/edge_guided_interpolation/ow_interp.m: -------------------------------------------------------------------------------- 1 | function [ output_image ] = ow_interp( input_image, method ) 2 | quart_1 = ow_interp_kernel_45_135(input_image, method); 3 | figure('name','image_45_135'); 4 | imshow(quart_1,[]); 5 | 6 | out_image = zeros(2*size(input_image)); 7 | out_image(1:2:end,1:2:end) = input_image; 8 | out_image(2:2:end,2:2:end) = quart_1; 9 | ow_interp_kernel_h_v(out_image, method); 10 | end 11 | function [ output_image ] = ow_interp_kernel_45_135( input_image, method ) 12 | %OW_INTER Summary of this function goes here 13 | % Detailed explanation goes here 14 | [I_45, I_135] = diag_interp(input_image, method); 15 | figure('name','I_45 image'); 16 | imshow(I_45,[]); 17 | figure('name','I_135 image'); 18 | imshow(I_135,[]); 19 | 20 | u_h = calc_u_h(input_image, 1, 1); 21 | figure('name','u_h'); 22 | imshow(u_h,[]); 23 | 24 | [var_45, var_135] = var_45_135(input_image, u_h, 2, I_45, I_135, 'abs'); 25 | figure('name','var_45'); 26 | imshow(var_45,[]); 27 | figure('name','var_135'); 28 | imshow(var_135,[]); 29 | 30 | var_45 = var_45 + eps; 31 | var_135 = var_135 + eps; 32 | w_45 = var_45./(var_45+var_135); 33 | w_135 = 1 - w_45; 34 | output_image = w_45.*I_45 + w_135.*I_135; 35 | end 36 | 37 | function [output_image] = ow_interp_kernel_h_v(input_image, method) 38 | figure('name','input_image'); 39 | imshow(input_image,[]); 40 | mask = zeros(size(input_image)); 41 | mask(1:2:end,2:2:end) = 1; 42 | mask(2:2:end,1:2:end) = 1; 43 | mask = logical(mask); 44 | [I_h, I_v] = h_v_interp(input_image, mask, method); 45 | figure('name','I_h image'); 46 | imshow(I_h,[]); 47 | figure('name','I_v image'); 48 | imshow(I_v,[]); 49 | end 50 | 51 | -------------------------------------------------------------------------------- /image_resize/cubic_convolution/cubic_conv.m: -------------------------------------------------------------------------------- 1 | function [ scaled_image ] = cubic_conv( input_image, scaled_sz) 2 | % CUBIC_CONV Implement cubic convolution along x direction, 3 | % then along y direction. 4 | % input_image Input image. 5 | % scaled_sz Size of output image. 6 | % scaled_image Output image. 7 | scaled_image_x = cubic_conv_x(input_image, scaled_sz(2)); 8 | scaled_image = cubic_conv_x(scaled_image_x', scaled_sz(1)); 9 | scaled_image = scaled_image'; 10 | end 11 | 12 | function [ scaled_image_x ] = cubic_conv_x( input_image, scaled_sz_x ) 13 | %1. Compute the coordinates to be interpolated 14 | org_sz = [size(input_image,1), size(input_image,2)]; 15 | x_org = (0:scaled_sz_x-1)/(scaled_sz_x-1)*(org_sz(2)-1); 16 | x = zeros([1, scaled_sz_x, 4]); 17 | x_org_dec = x_org - floor(x_org); 18 | x(1,:,1) = cubic_kernel(x_org_dec + 1); 19 | x(1,:,2) = cubic_kernel(x_org_dec); 20 | x(1,:,3) = cubic_kernel(1 - x_org_dec); 21 | x(1,:,4) = cubic_kernel(2 - x_org_dec); 22 | X = repmat(x, org_sz(1), 1, 1); 23 | 24 | %2. Compute the boudary data 25 | col_neg_1 = input_image(:,3) - 3*input_image(:,2) + 3*input_image(:,1); 26 | col_N_plus_1 = input_image(:,end-2) - 3*input_image(:,end-1) + 3*input_image(:,end); 27 | extent_image = [col_neg_1, input_image, col_N_plus_1]; 28 | 29 | x_int = floor(x_org); 30 | x_int(x_int >= org_sz(2)-1) = org_sz(2)-2; 31 | % x_int_to_ext_idx = x_int + 1; 32 | %3. Convolution for the interpolated data 33 | conv_x = cat(3,extent_image(:,x_int+1), extent_image(:,x_int+2),... 34 | extent_image(:,x_int+3), extent_image(:,x_int+4)); 35 | scaled_image_x = dot(X, conv_x, 3); 36 | scaled_image_x(:,1) = input_image(:,1); 37 | scaled_image_x(:,end) = input_image(:,end); 38 | end -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cmccat00.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cmccat00 3 | % *** 4 | % *** function [xyzc] = cmccat97(xyz,xyzt,xyzr,lt, lr,f) 5 | % *** implements the cmccat2000 CAT 6 | % *** xyz must be an n by 3 matrix of XYZ 7 | % *** xyzt and xyzr contain white points 8 | % *** f has default value of 1 9 | % *** lt and lr are the luminances of the adapting 10 | % *** test and reference fields and default to 100 11 | % *** see also cmccat97 12 | function [xyzc] = cmccat00(xyz,xyzt,xyzr,lt,lr, f) 13 | 14 | if (size(xyz,2)~=3) 15 | disp('first input must be n by 3'); return; 16 | end 17 | if (length(xyzt)~=3 | length(xyzr)~=3) 18 | disp('check white point inputs'); return; 19 | end 20 | 21 | if (nargin<6) 22 | disp('using default values of la, lt and f') 23 | la = 100; lt= 100; f=1; 24 | end 25 | 26 | xyzc = xyz; % to allocate memory 27 | rgb = xyz; 28 | 29 | % define the matrix for the transform to 'cone' space 30 | M(1,:) = [0.7982 0.3389 -0.1371]; 31 | M(2,:) = [-0.5918 1.5512 0.0406]; 32 | M(3,:) = [0.0008 0.0239 0.9753]; 33 | 34 | % transform to rgb 35 | rgb = (M*xyz')'; 36 | rgbt = M*xyzt'; 37 | rgbr = M*xyzr'; 38 | 39 | 40 | % compute d, the degree of adaptation 41 | d = f*(0.08*log10((lt+lr)/2)+0.76-0.45*(lt-lr)/(lt+lr)) 42 | % clip d if it is outside the range [0,1] 43 | if (d<0) 44 | d=0; 45 | elseif (d>1) 46 | d=1; 47 | end 48 | 49 | % compute corresponding rgb values 50 | a = d*xyzt(2)/xyzr(2) 51 | rgbc(:,1) = rgb(:,1)*(a*rgbr(1)/rgbt(1) + 1 - d); 52 | rgbc(:,2) = rgb(:,2)*(a*rgbr(2)/rgbt(2) + 1 - d); 53 | rgbc(:,3) = rgb(:,3)*(a*rgbr(3)/rgbt(3) + 1 - d); 54 | disp(rgbc) 55 | 56 | % define the matrix for the inverse transform 57 | IM(1,:) = [1.076450 -0.237662 0.161212]; 58 | IM(2,:) = [0.410964 0.554342 0.034694]; 59 | IM(3,:) = [-0.010954 -0.013389 1.024343]; 60 | 61 | % implement step 4: convert from rgb to xyz 62 | xyzc = (IM*rgbc')'; -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cmccat00r.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cmccat00r 3 | % *** 4 | % *** function [xyzc] = cmccat97(xyz,xyzt,xyzr,lt, lr,f) 5 | % *** implements the reverse cmccat2000 CAT 6 | % *** xyzc must be an n by 3 matrix of XYZ 7 | % *** xyzt and xyzr contain white points 8 | % *** f has default value of 1 9 | % *** lt and lr are the luminances of the adapting 10 | % *** test and reference fields and default to 100 11 | % *** see also cmccat97, cmccat00 12 | function [xyzc] = cmccat00r(xyzc,xyzt,xyzr,lt,lr, f) 13 | 14 | if (size(xyzc,2)~=3) 15 | disp('first input must be n by 3'); return; 16 | end 17 | if (length(xyzt)~=3 | length(xyzr)~=3) 18 | disp('check white point inputs'); return; 19 | end 20 | 21 | if (nargin<6) 22 | disp('using default values of la, lt and f') 23 | la = 100; lt= 100; f=1; 24 | end 25 | 26 | xyz = xyzc; % to allocate memory 27 | rgb = xyz; 28 | 29 | % define the matrix for the transform to 'cone' space 30 | M(1,:) = [0.7982 0.3389 -0.1371]; 31 | M(2,:) = [-0.5918 1.5512 0.0406]; 32 | M(3,:) = [0.0008 0.0239 0.9753]; 33 | 34 | % transform to rgb 35 | rgbc = (M*xyzc')' 36 | rgbt = M*xyzt' 37 | rgbr = M*xyzr' 38 | 39 | 40 | % compute d, the degree of adaptation 41 | d = f*(0.08*log10((lt+lr)/2)+0.76-0.45*(lt-lr)/(lt+lr)) 42 | % clip d if it is outside the range [0,1] 43 | if (d<0) 44 | d=0; 45 | elseif (d>1) 46 | d=1; 47 | end 48 | 49 | % compute corresponding rgb values 50 | a = d*xyzt(2)/xyzr(2) 51 | rgb(:,1) = rgbc(:,1)/(a*rgbr(1)/rgbt(1) + 1 - d); 52 | rgb(:,2) = rgbc(:,2)/(a*rgbr(2)/rgbt(2) + 1 - d); 53 | rgb(:,3) = rgbc(:,3)/(a*rgbr(3)/rgbt(3) + 1 - d); 54 | disp(rgb) 55 | 56 | % define the matrix for the inverse transform 57 | IM(1,:) = [1.076450 -0.237662 0.161212]; 58 | IM(2,:) = [0.410964 0.554342 0.034694]; 59 | IM(3,:) = [-0.010954 -0.013389 1.024343]; 60 | 61 | % implement step 4: convert from rgb to xyz 62 | xyzc = (IM*rgb')'; -------------------------------------------------------------------------------- /tools/3rdparty/color_science/svd_demo.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION svd_demo 3 | % *** 4 | % *** function svd_demo 5 | % *** performs svd on set of reflectance spectra 6 | % *** using original and centred data 7 | % *** plots the first three basis functions 8 | % *** rrequires keele.mat is in the path 9 | % =================================================== 10 | function svd_demo 11 | numbas = 3; % the number of basis functions required 12 | load keele.mat 13 | % the keele data are in the 0-100 format 14 | spectra=spectra/100; 15 | w=linspace(400,700,31); 16 | 17 | % perform svd 18 | [u1,s1,v1]=svd(spectra); 19 | % only keep the first numbas 20 | v1 = v1(:,1:numbas); 21 | plot(w,v1); 22 | title('1st three basis function without centering') 23 | xlabel('wavelength') 24 | 25 | % perform svd on centred data 26 | m = mean(spectra); 27 | diff = spectra-ones(size(spectra,1),1)*m; 28 | [u2,s2,v2] =svd(diff); 29 | % only keep the first numbas 30 | v2 = v2(:,1:numbas); 31 | figure 32 | plot(w,v2); 33 | title('1st three basis function with centering') 34 | xlabel('wavelength') 35 | 36 | 37 | % find the weights 38 | x1 = v1'*spectra'; % x = v'*spectra; 39 | x2 = v2'*diff'; 40 | 41 | % reconstruct the spectra from the weights 42 | recon = x1'*v1'; 43 | recon1 = x2'*v2'+ones(size(spectra,1),1)*m; 44 | 45 | 46 | i = round(rand*404); 47 | figure 48 | plot(w,recon(i,:),'b-',w,recon1(i,:),'r-',w,spectra(i,:),'ko') 49 | axis([400 700 0 1]) 50 | xlabel('wavelength'); 51 | ylabel('reflectance factor'); 52 | 53 | % compute colour differences 54 | xyz = r2xyz(spectra,400,700,'d65_64'); 55 | xyz1 = r2xyz(recon,400,700,'d65_64'); 56 | xyz2 = r2xyz(recon1,400,700,'d65_64'); 57 | lab = xyz2lab(xyz,'d65_64'); 58 | lab1 = xyz2lab(xyz1,'d65_64'); 59 | lab2 = xyz2lab(xyz2,'d65_64'); 60 | de1 = cielabde(lab,lab1); 61 | de2 = cielabde(lab,lab2); 62 | 63 | disp([median(de1) median(de2)]); 64 | end 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /stereo_vision/rectification/estimateFundamentalMatrixDemo.m: -------------------------------------------------------------------------------- 1 | close all; 2 | 3 | file1 = '../../data/stereo_vision/img1.png'; 4 | file2 = '../../data/stereo_vision/img2.png'; 5 | 6 | img1 = rgb2gray(imread(file1)); 7 | img2 = rgb2gray(imread(file2)); 8 | 9 | points1 = detectSURFFeatures(img1); 10 | points2 = detectSURFFeatures(img2); 11 | 12 | [features1, validPoints1] = extractFeatures(img1, points1); 13 | [features2, validPoints2] = extractFeatures(img2, points2); 14 | 15 | indexPairs = matchFeatures(features1,features2); 16 | matchedPoints1 = validPoints1(indexPairs(:,1),:); 17 | matchedPoints2 = validPoints2(indexPairs(:,2),:); 18 | 19 | figure; showMatchedFeatures(img1,img2,matchedPoints1,matchedPoints2); 20 | 21 | if 0 22 | F = estimateFundamentalMatrix(matchedPoints1.Location, matchedPoints2.Location, 'Method', 'Norm8Point') 23 | F1 = estimateFundamentalMatrixNorm8Points(matchedPoints1.Location, matchedPoints2.Location) 24 | else 25 | [F,inliersIndex] = estimateFundamentalMatrix(matchedPoints1.Location, matchedPoints2.Location, 'Method',... 26 | 'RANSAC', 'DistanceType', 'Algebraic'); 27 | [F1,inliersIndex1, n] = estimateFundamentalMatrixRANSAC(double(matchedPoints1.Location), double(matchedPoints2.Location)); 28 | end 29 | x1 = [matchedPoints1.Location';ones(1, size(matchedPoints1.Location,1))]; 30 | x2 = [matchedPoints2.Location';ones(1,size(matchedPoints2.Location,1))]; 31 | a = diag(x2'*F*x1); 32 | b = diag(x2'*(-F1)*x1); 33 | a42 = x2(:,42)'*F*x1(:,42) 34 | b42 = x2(:,42)'*F1*x1(:,42) 35 | inliersIndex(42) 36 | inliersIndex1(42) 37 | sum(inliersIndex) 38 | sum(inliersIndex1) 39 | error1 = sum((a.^2)) 40 | error2 = sum((b.^2)) 41 | F , F1 42 | 43 | n 44 | % FF = estimateFundamentalMatrix(matchedPoints1.Location(inliersIndex,:), matchedPoints2.Location(inliersIndex,:), 'Method', 'Norm8Point') 45 | % FF1 = estimateFundamentalMatrixNorm8Points(matchedPoints1.Location(inliersIndex,:), matchedPoints2.Location(inliersIndex,:)) -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cmccat97.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cmccat97 3 | % *** 4 | % *** function [xyzc] = cmccat97(xyz,xyzt,xyzr,la,f) 5 | % *** implements the cmccat97s CAT 6 | % *** xyz must be an n by 3 matrix of XYZ 7 | % *** xyzt and xyzr contain white points 8 | % *** f has default value of 1 9 | % *** la is the luminance of the adapting field and 10 | % *** has a default value of 100 11 | % *** see also 12 | function [xyzc] = cmccat97(xyz,xyzt,xyzr,la,f) 13 | 14 | if (size(xyz,2)~=3) 15 | disp('first input must be n by 3'); return; 16 | end 17 | if (length(xyzt)~=3 | length(xyzr)~=3) 18 | disp('check white point inputs'); return; 19 | end 20 | 21 | if (nargin<5) 22 | disp('using default values of la and f') 23 | la = 100; f=1; 24 | end 25 | 26 | xyzc = xyz; % to allocate memory 27 | rgb = xyz; 28 | 29 | % define the matrix for the transform to 'cone' space 30 | M(1,:) = [0.8951 0.2664 -0.1614]; 31 | M(2,:) = [-0.7502 1.7135 0.0367]; 32 | M(3,:) = [0.0389 -0.0685 1.0296]; 33 | 34 | % normalise xyz and transform to rgb 35 | rgb = (M*(xyz./[xyz(:,2) xyz(:,2) xyz(:,2)])')'; 36 | rgbt = M*(xyzt/xyzt(2))'; 37 | rgbr = M*(xyzr/xyzr(2))'; 38 | 39 | % compute d, the degree of adaptation 40 | d = f - f/(1 + 2*(la^0.25) + la*la/300); 41 | % clip d if it is outside the range [0,1] 42 | if (d<0) 43 | d=0; 44 | elseif (d>1) 45 | d=1; 46 | end 47 | p = (rgbt(3)/rgbr(3))^0.0834; 48 | 49 | % compute corresponding rgb values 50 | rgbc(:,1) = rgb(:,1)*(d*rgbr(1)/rgbt(1) + 1 - d); 51 | rgbc(:,2) = rgb(:,2)*(d*rgbr(2)/rgbt(2) + 1 - d); 52 | rgbc(:,3) = abs(rgb(:,3)).^p*(d*(rgbr(3)/(rgbt(3)^p)) + 1 - d); 53 | index = (rgb(:,3)<0); 54 | rgbc(:,3) = index.*(-rgbc(:,3)) + (1-index).*rgbc(:,3); 55 | 56 | % define the matrix for the inverse transform 57 | IM(1,:) = [0.98699 -0.14705 0.15996]; 58 | IM(2,:) = [0.43231 0.51836 0.04929]; 59 | IM(3,:) = [-0.00853 0.04004 0.96849]; 60 | 61 | % implement step 4: convert from rgb to xyz 62 | xyzc = [xyz(:,2) xyz(:,2) xyz(:,2)].*(IM*rgbc')'; -------------------------------------------------------------------------------- /tools/3rdparty/color_science/plotMBdiagram.m: -------------------------------------------------------------------------------- 1 | function plotMBdiagram 2 | % plotMBdiagram Plot the MacLeod and Boynton (1979) chromaticity diagram. 3 | % To plot the spectral locus in the diagram I have performed a series of 4 | % computations starting from the linear cone fundamentals in quantal units. 5 | % The locus is also available at www.cvrl.org 6 | % 7 | %-------------------------------------------------------------------------- 8 | % plotMBdiagram 9 | % ========= 10 | % 11 | % 30-Nov -2011 kr Wrote it. 12 | % Load MB chromaticity coordinates in the rage {390,830} at 1nm interval. 13 | load MBlocus 14 | wavelength=linspace(390,830,441); 15 | close all; 16 | figure(1) 17 | set(gcf,'color','w') 18 | plot(rMB,bMB,'k-', 'LineWidth',4); hold on 19 | % Highlight single coordinates at specific wavelengths as in MB(1979) 20 | % paper. 21 | plot(rMB(1),bMB(1),'ko', 'LineWidth',4); hold on % 390nm 22 | text(rMB(1)+0.02,bMB(1)+0.02, '390'); 23 | plot(rMB(31),bMB(31),'ko', 'LineWidth',4); hold on % 420nm 24 | text(rMB(31)-0.02,bMB(31)-0.08, '420'); 25 | plot(rMB(51),bMB(51),'ko', 'LineWidth',4); hold on % 440nm 26 | text(rMB(51)-0.07,bMB(51), '440'); 27 | plot(rMB(71),bMB(71),'ko', 'LineWidth',4); hold on % 460nm 28 | text(rMB(71)-0.07,bMB(71), '460'); 29 | plot(rMB(91),bMB(91),'ko', 'LineWidth',4); hold on % 480nm 30 | text(rMB(91)-0.07,bMB(91), '480'); 31 | plot(rMB(131),bMB(131),'ko', 'LineWidth',4); hold on % 520nm 32 | text(rMB(131),bMB(131)+0.03, '520'); 33 | plot(rMB(211),bMB(211),'ko', 'LineWidth',4); hold on % 600nm 34 | text(rMB(211),bMB(211)+0.03, '600'); 35 | plot(rMB(311),bMB(311),'ko', 'LineWidth',4); hold on % 520nm 36 | text(rMB(311),bMB(311)+0.03, '700'); 37 | % Plot confusion lines. 38 | plot([0 1],[0 1],'g-', 'LineWidth',2); hold on % D line 39 | text(0.9,0.81, 'D'); 40 | plot([1 0],[0 1],'r-.', 'LineWidth',2); hold on % P line 41 | text(0.1,0.81, 'P'); 42 | plot([0.52 0.52],[0 1],'b--', 'LineWidth',2); hold on % T line 43 | 44 | text(0.55,0.81, 'T'); 45 | 46 | xlabel('rMB','FontSize',9); ylabel('bMB','FontSize',9); 47 | axis([0 1 0 1]); -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cielabde.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cielabde 3 | % *** 4 | % *** function [de, dl, dc, dh] = cielabde(lab1, lab2) 5 | % *** computes colour difference from CIELAB values 6 | % *** using CIELAB formula 7 | % *** inputs must be n by 3 matrices 8 | % *** and contain L*, a* and b* values 9 | % *** see also cmcde, cie94de, and cie00de 10 | % =================================================== 11 | function [de,dl,dc,dh] = cielabde(lab1,lab2) 12 | 13 | if (size(lab1,1)~=size(lab2,1)) 14 | disp('inputs must be the same size'); return; 15 | end 16 | 17 | if (size(lab1,2)~=3 | size(lab2,2)~=3) 18 | disp('inputs must be n by 3'); return; 19 | end 20 | de = zeros(1,size(lab1,2)); 21 | dl = zeros(1,size(lab1,2)); 22 | dc = zeros(1,size(lab1,2)); 23 | dh = zeros(1,size(lab1,2)); 24 | 25 | dl = lab2(:,1)-lab1(:,1); 26 | dc = (lab2(:,2).^2 + lab2(:,3).^2).^0.5-(lab1(:,2).^2 + lab1(:,3).^2).^0.5; 27 | dh = ((lab2(:,2)-lab1(:,2)).^2 + (lab2(:,3)-lab1(:,3)).^2 - dc.^2); 28 | dh = (abs(dh)).^0.5; 29 | 30 | 31 | % get the polarity of the dh term 32 | dh = dh.*dhpolarity(lab1,lab2); 33 | 34 | de = (dl.^2 + dc.^2 + dh.^2).^0.5; 35 | end 36 | 37 | function [p] = dhpolarity(lab1,lab2) 38 | % function [p] = dhpolarity(lab1,lab2) 39 | % computes polarity of hue difference 40 | % p = +1 if the hue of lab2 is anticlockwise 41 | % from lab1 and p = -1 otherwise 42 | [h1,c1] = cart2pol(lab1(:,2), lab1(:,3)); 43 | [h2,c2] = cart2pol(lab2(:,2), lab2(:,3)); 44 | 45 | h1 = h1*180/pi; 46 | h2 = h2*180/pi; 47 | 48 | index = (h1<0); 49 | h1 = (1-index).*h1 + index.*(h1+360); 50 | index = (h2<0); 51 | h2 = (1-index).*h2 + index.*(h2+360); 52 | 53 | index = (h1>180); 54 | h1 = (1-index).*h1 + index.*(h1-180); 55 | h2 = (1-index).*h2 + index.*(h2-180); 56 | 57 | p = (h2-h1); 58 | 59 | index = (p==0); 60 | p = (1-index).*p + index*1; 61 | index = (p>180); 62 | p = (1-index).*p + index.*(p-360); 63 | 64 | p = p./abs(p); 65 | 66 | end 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/sprague.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION sprague 3 | % *** 4 | % *** Interpolates an n by w matrix of spectra 5 | % *** where n is the number of spectra 6 | % *** f is an interpolation factor 7 | % *** e.g. if f=2 the sampling rate is doubled 8 | % =================================================== 9 | function [p] = sprague(spectra,f) 10 | if (f<2 | ((f-floor(f))>0)) 11 | disp('invalid f value - premature termination'); 12 | p = 0; 13 | return; 14 | end 15 | % set the parameters 16 | c = [884 -1960 3033 -2648 1080 -180; ... 17 | 508 -540 488 -367 144 -24; ... 18 | -24 144 -367 488 -540 508; ... 19 | -180 1080 -2648 3033 -1960 884]; 20 | 21 | [numSpectra lengthSpectra] = size(spectra); 22 | 23 | for i=1:numSpectra 24 | % select a spectrum 25 | r = spectra(i,:); 26 | % add the extra start and end points 27 | k = c(1,:); 28 | p1 = (k*(r(1:6))')/209; 29 | k = c(2,:); 30 | p2 = (k*(r(1:6))')/209; 31 | k = c(3,:); 32 | p3 = (k*(r(end-5:end))')/209; 33 | k = c(4,:); 34 | p4 = (k*(r(end-5:end))')/209; 35 | r = [p1 p2 r p3 p4]; 36 | N = lengthSpectra+4; 37 | 38 | p = zeros(numSpectra,f*(N-5)+1); 39 | xx = linspace(1/f,1-1/f,f-1); 40 | 41 | for j=3:N-3 42 | a0 = r(j); 43 | a1 = (2*r(j-2)-16*r(j-1)+16*r(j+1)-2*r(j+2))/24; 44 | a2 = (-r(j-2)+16*r(j-1)-30*r(j)+16*r(j+1)-r(j+2))/24; 45 | a3 = (-9*r(j-2)+39*r(j-1)-70*r(j)+66*r(j+1)-33*r(j+2)+7*r(j+3))/24; 46 | a4 = (13*r(j-2)-64*r(j-1)+126*r(j)-124*r(j+1)+61*r(j+2)-12*r(j+3))/24; 47 | a5 = (-5*r(j-2)+25*r(j-1)-50*r(j)+50*r(j+1)-25*r(j+2)+5*r(j+3))/24; 48 | y = a0+a1*xx+a2*xx.^2+a3*xx.^3+a4*xx.^4+a5*xx.^5; 49 | index = j-2; 50 | p(i,(index-1)*f+1) = r(j); 51 | p(i,(index-1)*f+1+1:(index-1)*f+1+f-1)=y; 52 | end 53 | p(i,f*(N-5)+1)=r(N-2); 54 | end 55 | 56 | end 57 | % ==================================================== 58 | % *** END FUNCTION sprague 59 | % ==================================================== 60 | 61 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cie94de.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cie94de 3 | % *** 4 | % *** function [de, dl, dc, dh] = cie94de(lab1,lab2) 5 | % *** computes colour difference from CIELAB values 6 | % *** using CIE94 formula 7 | % *** inputs must be n by 3 matrices 8 | % *** and contain L*, a* and b* values 9 | % *** see also cielabde, cmcde, and cie00de 10 | function [de,dl,dc,dh] = cie94de(lab1,lab2) 11 | 12 | if (size(lab1,1)~=size(lab2,1)) 13 | disp('inputs must be the same size'); return; 14 | end 15 | 16 | if (size(lab1,2)~=3 | size(lab2,2)~=3) 17 | disp('inputs must be n by 3'); return; 18 | end 19 | 20 | de = zeros(1,size(lab1,2)); 21 | dl = zeros(1,size(lab1,2)); 22 | dc = zeros(1,size(lab1,2)); 23 | dh = zeros(1,size(lab1,2)); 24 | 25 | % first compute the CIELAB deltas 26 | dl = lab2(:,1)-lab1(:,1); 27 | dc = (lab2(:,2).^2 + lab2(:,3).^2).^0.5-(lab1(:,2).^2 + lab1(:,3).^2).^0.5; 28 | dh = ((lab2(:,2)-lab1(:,2)).^2 + (lab2(:,3)-lab1(:,3)).^2 - dc.^2); 29 | dh = (abs(dh)).^0.5; 30 | 31 | % get the polarity of the dh term 32 | dh = dh.*dhpolarity(lab1,lab2); 33 | 34 | % now compute the CIE94 weights 35 | Lweight = 1.0; 36 | [h,c] = cart2pol(lab1(:,2), lab1(:,3)); 37 | h = h*180/pi; 38 | 39 | Cweight = 1.0 + 0.045*c; 40 | Hweight = 1.0 + 0.015*c; 41 | 42 | dl = dl/(Lweight); 43 | dc = dc./(Cweight); 44 | dh = dh./Hweight; 45 | 46 | de = (dl.^2 + dc.^2 + dh.^2).^0.5; 47 | end 48 | 49 | function [p] = dhpolarity(lab1,lab2) 50 | % function [p] = dhpolarity(lab1,lab2) 51 | % computes polarity of hue difference 52 | % p = +1 if the hue of lab2 is anticlockwise 53 | % from lab1 and p = -1 otherwise 54 | [h1,c1] = cart2pol(lab1(:,2), lab1(:,3)); 55 | [h2,c2] = cart2pol(lab2(:,2), lab2(:,3)); 56 | 57 | h1 = h1*180/pi; 58 | h2 = h2*180/pi; 59 | 60 | index = (h1<0); 61 | h1 = (1-index).*h1 + index.*(h1+360); 62 | index = (h2<0); 63 | h2 = (1-index).*h2 + index.*(h2+360); 64 | 65 | index = (h1>180); 66 | h1 = (1-index).*h1 + index.*(h1-180); 67 | h2 = (1-index).*h2 + index.*(h2-180); 68 | 69 | p = (h2-h1); 70 | 71 | index = (p==0); 72 | p = (1-index).*p + index*1; 73 | index = (p>180); 74 | p = (1-index).*p + index.*(p-360); 75 | 76 | p = p./abs(p); 77 | 78 | end -------------------------------------------------------------------------------- /image_resize/edge_guided_interpolation/h_v_interp.m: -------------------------------------------------------------------------------- 1 | function [ output_image_h, output_image_v ] = h_v_interp( input_image, mask, method ) 2 | %H_V_INTERP Summary of this function goes here 3 | % Detailed explanation goes here 4 | org_sz = size(input_image); 5 | if strcmp(method, 'linear') 6 | pad_image = padarray(input_image, [1,1],'symmetric', 'both'); 7 | lay_h = zeros(org_sz(1),org_sz(2),2); 8 | lay_v = lay_h; 9 | lay_h(:,:,1) = pad_image(2:end-1,1:end-2); 10 | lay_h(:,:,2) = pad_image(2:end-1,3:end); 11 | lay_v(:,:,1) = pad_image(1:end-2,2:end-1); 12 | lay_v(:,:,2) = pad_image(3:end,2:end-1); 13 | coe = 0.5*ones(org_sz(1),org_sz(2),2); 14 | elseif strcmp(method, 'cubic_convolution') 15 | s = [1.5 0.5 -0.5 -1.5]; 16 | kernel = cubic_kernel(s); 17 | pad_image = padarray(input_image, [2,2], 'both'); 18 | lay_h = zeros(org_sz(1),org_sz(2),4); 19 | lay_v = lay_h; 20 | idx = [-2,-1,1,2]; 21 | for i = 1:4 22 | lay_h(:,:,i) = pad_image(3:end-2,3+idx(i):3+idx(i)+org_sz(2)-1); 23 | lay_v(:,:,i) = pad_image(3+idx(i):3+idx(i)+org_sz(1)-1,3:end-2); 24 | end 25 | coe = zeros(org_sz(1),org_sz(2),4); 26 | for i = 1:4 27 | coe(:,:,i) = kernel(i); 28 | end 29 | end 30 | I_h_tmp = dot(lay_h,coe,3); 31 | I_v_tmp = dot(lay_v,coe,3); 32 | output_image_h = input_image; 33 | output_image_v = input_image; 34 | output_image_h(mask) = I_h_tmp(mask); 35 | output_image_v(mask) = I_v_tmp(mask); 36 | end 37 | 38 | function [ kernel_res ] = cubic_kernel( s ) 39 | kernel_res = zeros(size(s)); 40 | kernel_res(abs(s)0 & s < 1)) = kernel_0_1(s(s>0 & s < 1)); 44 | kernel_res((s>1 & s < 2)) = kernel_1_2(s(s>1 & s < 2)); 45 | end 46 | 47 | function [ kernel_res ] = kernel_0_1( s ) 48 | s2 = s.*s; 49 | s3 = s2.*s; 50 | kernel_res = 1.5*s3 - 2.5*s2 + 1; 51 | end 52 | 53 | function [ kernel_res ] = kernel_1_2( s ) 54 | s2 = s.*s; 55 | s3 = s2.*s; 56 | kernel_res = -0.5*s3 + 2.5*s2 - 4*s + 2; 57 | end 58 | -------------------------------------------------------------------------------- /stereo_vision/rectification/estimateFundamentalMatrixNorm8Points.m: -------------------------------------------------------------------------------- 1 | % Created by Shen Quanmin on 2019/03/16. 2 | % Copyright ? 2019 Shen Quanmin. All rights reserved. 3 | function [ F ] = estimateFundamentalMatrixNorm8Points(matchPoints1,matchPoints2) 4 | % Estimate the fundamental matrix through two group of matched points. 5 | % Reference: Richard Hartley etc. Multiple View Geometry in computer 6 | % vision. Page 282: Algorithm 11.1: The normalized 8-point algorithm for F. 7 | % Main algorithm steps: 8 | % 1. Normalize the matched points separately. 9 | % 2. Compose the matrix A according to x2'*F*x1=0. And solve this for 10 | % Fnorm. 11 | % 3. Get result F from Fnorm. Remember to norm the matrix F because of the 12 | % norm of the two normalization matrix are not 1. 13 | 14 | % matchPoints1 - input points in first image. 15 | % matchPoints2 - input points in second image. 16 | % F - output fundamental matrix for the two image. 17 | 18 | % Created by Shen Quanmin on 2019/03/16. 19 | 20 | 21 | %1.Normalize the coordinates. 22 | x1 = matchPoints1; 23 | x2 = matchPoints2; 24 | T1 = NormMatrix(x1); 25 | T2 = NormMatrix(x2); 26 | normX1 = (T1*[x1';ones(1,size(x1,1))])'; 27 | normX2 = (T2*[x2';ones(1,size(x2,1))])'; 28 | 29 | %2.Solve the Fundamental Matrix for normalized coordinates. 30 | A = [normX1(:,1).*normX2(:,1),normX1(:,2).*normX2(:,1),normX2(:,1),... 31 | normX1(:,1).*normX2(:,2),normX1(:,2).*normX2(:,2),normX2(:,2),... 32 | normX1(:,1), normX1(:,2),ones(size(normX1,1),1)]; 33 | [U,S,V]=svd(A); 34 | Fnorm = V(:,end); 35 | Fnorm = reshape(Fnorm,3,3)'; 36 | [Unorm, Snorm, Vnorm] = svd(Fnorm); 37 | Snorm(3,3) = 0; 38 | Fnorm = Unorm*Snorm*Vnorm'; 39 | 40 | %3.Calculate the Fundamental Matrix for original coordinates. 41 | F = T2'*Fnorm*T1; 42 | F = F/norm(F); % For the norm of T1 and T2 are not eaqual to 1. 43 | end 44 | 45 | function [ T ] = NormMatrix(points) 46 | center = mean(points, 1); 47 | centeredPoints = [points(:,1)-center(1),points(:,2)-center(2)]; 48 | rVec = centeredPoints.^2; 49 | rVec = mean(sqrt(rVec(:,1)+rVec(:,2))); 50 | s = sqrt(2)/rVec; 51 | T = [s, 0, -s*center(1); 52 | 0, s, -s*center(2); 53 | 0, 0, 1]; 54 | end -------------------------------------------------------------------------------- /tools/3rdparty/color_science/dkl2lms.m: -------------------------------------------------------------------------------- 1 | % ============================================================================ 2 | % *** FUNCTION dkl2lms 3 | % *** 4 | % *** function [lms_t] = dkl2lms(lms_b,dkl_rad) 5 | % *** computes lms excitations from dkl coordinates (in rad). 6 | % *** the lms_b are the cone-excitations of the background. 7 | % *** dkl_rad is a vector that contains the derived DKL coordinates 8 | % *** in the order: [luminance; chromatic (L-M); chromatic S-(L+M)] in radians 9 | % *** the lms_t are the cone-excitations of the target. 10 | % ============================================================================ 11 | 12 | function [lms_t] = dkl2lms(lms_b,dkl_rad) 13 | 14 | % compute 3 by 3 matrix in Equation 7.18 15 | % note that this matrix is background-dependent 16 | B = [1 1 0; 1 -lms_b(1)/lms_b(2) 0; -1 -1 (lms_b(1)+lms_b(2))/lms_b(3)]; 17 | % compute the inverse of B as in Equation 7.19 18 | B_inv = inv(B); 19 | 20 | % set the three isolating stimuli equal to 21 | % the columns of B_inv. 22 | lum = B_inv(:,1); % luminance 23 | chro_LM = B_inv(:,2); % chromatic L+M 24 | chro_S = B_inv(:,3); % chromatic S 25 | 26 | % use the MATLAB function norm 27 | % to find the pooled cone contrast 28 | % for each mechanism as in Equation 7.13 29 | lum_pooled = norm(lum./lms_b); % k(LUM) 30 | chro_LM_pooled = norm(chro_LM./lms_b); % k(L-M) 31 | chro_S_pooled = norm(chro_S./lms_b); % k(S-LUM) 32 | 33 | % normalise each isolating stimulus 34 | % by its pooled contrast such that each mechanism 35 | % will produce unit response 36 | lum_unit = lum / lum_pooled; 37 | chroLM_unit = chro_LM / chro_LM_pooled; 38 | chroS_unit = chro_S / chro_S_pooled; 39 | 40 | % normalise B to obtain the normalising constants 41 | lum_norm = B*lum_unit; 42 | chroLM_norm = B*chroLM_unit; 43 | chroS_norm = B*chroS_unit; 44 | 45 | % use the normalising constants to rescale B and obtain unit response. 46 | % first create a diagonal matrix containing the normalising constants. 47 | D_const=[1/lum_norm(1) 0 0; 0 1/chroLM_norm(2) 0; 0 0 1/chroS_norm(3)]; 48 | % then rescale B to obtain the matrix transform T. 49 | T = D_const*B; 50 | T_inv=inv(T); 51 | % compute differencial cone excitations 52 | lms_diff = T_inv * dkl_rad; 53 | lms_t = (lms_b-lms_diff); 54 | % =================================================== 55 | % *** END FUNCTION dkl2lms 56 | % =================================================== 57 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/camera_demo1.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION camera_demo 3 | % *** 4 | % *** function camera_demo1() 5 | % *** demonstrates camera characterization 6 | % *** performs linear, second-order and third-order 7 | % *** modelling to predict XYZ from RGB 8 | % *** requires rgb_cc.mat and xyz_cc.mat are in the path 9 | % *** see also camera_demo 10 | function camera_demo1 11 | 12 | load rgb_cc.mat 13 | load xyz_cc.mat 14 | % rgb 240x3 15 | % xyz 240x3 16 | 17 | % only use a sub-set of the 240 samples for the analysis 18 | trgb = rgb([14:23 26:35 38:47 50:59 62:71 74:83 86:95 98:107 110:119 122:131 134:143 146:155 158:167 170:179 182:191 194:203 206:215],:)/255; 19 | txyz = xyz([14:23 26:35 38:47 50:59 62:71 74:83 86:95 98:107 110:119 122:131 134:143 146:155 158:167 170:179 182:191 194:203 206:215],:); 20 | 21 | 22 | % find the linear transform between trgb and txyz 23 | M1=txyz'/trgb'; 24 | % use this transform 25 | pxyz1 = (M1*trgb')'; 26 | % calculate performance 27 | pxyz1(pxyz1<0)=0; 28 | lab = xyz2lab(txyz,'d65_64'); 29 | lab1 = xyz2lab(pxyz1,'d65_64'); 30 | de1 = cie00de(lab, lab1); 31 | disp('mean and max colour differences for linear transform'); 32 | disp([mean(de1) max(de1)]) 33 | 34 | % now perform a second-order transform 35 | trgb2 = [trgb trgb(:,1).^2 trgb(:,2).^2 trgb(:,3).^2 trgb(:,1).*trgb(:,2) trgb(:,1).*trgb(:,3) trgb(:,2).*trgb(:,3) ones(170,1)]; 36 | M2=txyz'/trgb2'; 37 | pxyz2 = (M2*trgb2')'; 38 | pxyz2(pxyz2<0)=0; 39 | lab = xyz2lab(txyz,'d65_64'); 40 | lab2 = xyz2lab(pxyz2,'d65_64'); 41 | de2 = cie00de(lab, lab2); 42 | disp('mean and max colour differences for 2nd-order transform'); 43 | disp([mean(de2) max(de2)]) 44 | 45 | 46 | % now perform a third-order transform 47 | trgb3 = [trgb trgb(:,1).^2 trgb(:,2).^2 trgb(:,3).^2 trgb(:,1).*trgb(:,2) trgb(:,1).*trgb(:,3) trgb(:,2).*trgb(:,3) ... 48 | trgb(:,1).^3 trgb(:,2).^3 trgb(:,3).^3 ... 49 | trgb(:,1).*trgb(:,1).*trgb(:,2) trgb(:,1).*trgb(:,1).*trgb(:,3) ... 50 | trgb(:,2).*trgb(:,2).*trgb(:,1) trgb(:,2).*trgb(:,2).*trgb(:,3) ... 51 | trgb(:,3).*trgb(:,3).*trgb(:,1) trgb(:,3).*trgb(:,3).*trgb(:,2) ... 52 | ones(170,1)]; 53 | M3=txyz'/trgb3'; 54 | pxyz3 = (M3*trgb3')'; 55 | pxyz3(pxyz3<0)=0; 56 | lab = xyz2lab(txyz,'d65_64'); 57 | lab3 = xyz2lab(pxyz3,'d65_64'); 58 | de3 = cie00de(lab, lab3); 59 | disp('mean and max colour differences for 3rd-order transform'); 60 | disp([mean(de3) max(de3)]) 61 | 62 | end 63 | 64 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/lms2dkl.m: -------------------------------------------------------------------------------- 1 | % ============================================================================= 2 | % *** FUNCTION lms2dkl 3 | % *** 4 | % *** function [dkl_rad] = lms2dkl(lms_b,lms_t) 5 | % *** computes dkl coordinates from lms. 6 | % *** the lms_b are the cone-excitations of the background. 7 | % *** the lms_t are the cone-excitations of the target. 8 | % *** the lms_b are the cone-excitations of the background. 9 | % *** the lms_b are the cone-excitations of the background. 10 | % *** dkl_rad is a vector that contains the derived DKL coordinates 11 | % *** in the order: [luminance; chromatic (L-M); chromatic S-(L+M)] in radians 12 | % ============================================================================ 13 | function [dkl_rad] = lms2dkl(lms_b,lms_t) 14 | % compute differencial cone excitations 15 | lms_diff = (lms_b-lms_t); 16 | % compute 3 by 3 matrix in Equation 7.18 17 | % note that this matrix is background-dependent 18 | B = [1 1 0; 1 -lms_b(1)/lms_b(2) 0; -1 -1 (lms_b(1)+lms_b(2))/lms_b(3)]; 19 | % compute the inverse of B as in Equation 7.19 20 | B_inv = inv(B); 21 | 22 | % set the three isolating stimuli equal to 23 | % the columns of B_inv. 24 | lum = B_inv(:,1); % luminance 25 | chro_LM = B_inv(:,2); % chromatic L+M 26 | chro_S = B_inv(:,3); % chromatic S 27 | 28 | % use the MATLAB function norm 29 | % to find the pooled cone contrast 30 | % for each mechanism as in Equation 7.13 31 | lum_pooled = norm(lum./lms_b); % k(LUM) 32 | chro_LM_pooled = norm(chro_LM./lms_b); % k(L-M) 33 | chro_S_pooled = norm(chro_S./lms_b); % k(S-LUM) 34 | 35 | % normalise each isolating stimulus 36 | % by its pooled contrast such that each mechanism 37 | % will produce unit response 38 | lum_unit = lum / lum_pooled; 39 | chroLM_unit = chro_LM / chro_LM_pooled; 40 | chroS_unit = chro_S / chro_S_pooled; 41 | 42 | % normalise B to obtain the normalising constants 43 | lum_norm = B*lum_unit; 44 | chroLM_norm = B*chroLM_unit; 45 | chroS_norm = B*chroS_unit; 46 | 47 | % use the normalising constants to rescale B and obtain unit response. 48 | % first create a diagonal matrix containing the normalising constants. 49 | D_const=[1/lum_norm(1) 0 0; 0 1/chroLM_norm(2) 0; 0 0 1/chroS_norm(3)]; 50 | % then rescale B to obtain the matrix transform T. 51 | T = D_const*B; 52 | % compute dkl coordinates in radiant units. 53 | dkl_rad = T * lms_diff; 54 | % =================================================== 55 | % *** END FUNCTION lms2dkl 56 | % =================================================== -------------------------------------------------------------------------------- /tools/3rdparty/color_science/dkl_cart2sph.m: -------------------------------------------------------------------------------- 1 | % ============================================================================== 2 | % *** FUNCTION dkl_cart2sph 3 | % *** 4 | % *** function [dkl_deg] = dkl_cart2sph(dkl_rad) 5 | % *** transforms dkl coordinates from Cartesian to spherical 6 | % *** and then from radians to degrees. 7 | % *** dkl_rad is a vector containing the DKL coordinates in radians 8 | % *** in the order: [luminance; chromatic (L-M); chromatic S-(L+M)] in radians 9 | % *** dkl_deg is a vector containing the DKL coordinates in degrees 10 | % *** in the order: [radius azimuth elevation] 11 | % ============================================================================== 12 | 13 | function [dkl_deg] = dkl_cart2sph(dkl_rad) 14 | 15 | % compute radius, which represents the excitation of each mechanism. 16 | isolum_len = (sqrt(dkl_rad(2)^2+ dkl_rad(3)^2)); 17 | 18 | % compute elevation, which represents the relative luminance of the target. 19 | if isolum_len==0 20 | elevation_rads = atan(dkl_rad(1)/0.000000001); 21 | else 22 | elevation_rads = atan(dkl_rad(1)/isolum_len); 23 | end 24 | 25 | % compute azimuth, which represents the relative chromaticity of the 26 | % target. 27 | if dkl_rad(2)> -0.000001 & dkl_rad(2)< 0.000001 & dkl_rad(3)> -0.000001 & dkl_rad(3)< 0.000001 28 | % if target is along the luminance axis, 29 | % then chro_LM and chro_S are = 0. 30 | azimuth_rads = 0; 31 | % Therefore radius is the sqrt of the length of lum^2. 32 | radius = sqrt(dkl_rad(1)^2); 33 | else 34 | % if target is not along the luminance axis, 35 | % then the length of radius is 36 | % a vector given by chro_LM and chro_S only. 37 | azimuth_rads = atan(-dkl_rad(3)/dkl_rad(2)); 38 | radius = isolum_len; 39 | end 40 | 41 | % convert radians into degrees using the 42 | % MATLAB function radtodeg. 43 | if dkl_rad(2)>0 & dkl_rad(3)>0 44 | % if target is in the 'green' quadrant: 45 | azimuth_deg = radtodeg(azimuth_rads)+180; 46 | elseif dkl_rad(2)>0 & dkl_rad(3)<0 47 | % if target is in the 'blue' quadrant: 48 | azimuth_deg = radtodeg(azimuth_rads)+180; 49 | elseif dkl_rad(2)<0 & dkl_rad(3)<0 50 | % if target is in the 'magenta' quadrant: 51 | azimuth_deg = 360 + radtodeg(azimuth_rads); 52 | else 53 | azimuth_deg = radtodeg(azimuth_rads); 54 | end 55 | 56 | elevation_deg = -radtodeg(elevation_rads); 57 | dkl_deg = [radius azimuth_deg elevation_deg]'; 58 | % =================================================== 59 | % *** END FUNCTION dkl_cart2sph 60 | % =================================================== 61 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cmcde.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cmcde 3 | % *** 4 | % *** function [de, dl, dc, dh] = cmcde(lab1,lab2,sl,sc) 5 | % *** computes colour difference from CIELAB values 6 | % *** using CMC formula 7 | % *** inputs must be n by 3 matrices 8 | % *** and contain L*, a* and b* values 9 | % *** see also cielabde, cie94de, and cie00de 10 | function [de,dl,dc,dh] = cmcde(lab1,lab2,sl,sc) 11 | 12 | if (size(lab1,1)~=size(lab2,1)) 13 | disp('inputs must be the same size'); return; 14 | end 15 | 16 | if (size(lab1,2)~=3 | size(lab2,2)~=3) 17 | disp('inputs must be n by 3'); return; 18 | end 19 | if (nargin<4) 20 | disp('using default values of l:c') 21 | sl=1; sc=1; 22 | end 23 | 24 | de = zeros(1,size(lab1,2)); 25 | dl = zeros(1,size(lab1,2)); 26 | dc = zeros(1,size(lab1,2)); 27 | dh = zeros(1,size(lab1,2)); 28 | 29 | % first compute the CIELAB deltas 30 | dl = lab2(:,1)-lab1(:,1); 31 | dc = (lab2(:,2).^2 + lab2(:,3).^2).^0.5-(lab1(:,2).^2 + lab1(:,3).^2).^0.5; 32 | dh = ((lab2(:,2)-lab1(:,2)).^2 + (lab2(:,3)-lab1(:,3)).^2 - dc.^2); 33 | dh = (abs(dh)).^0.5; 34 | % get the polarity of the dh term 35 | dh = dh.*dhpolarity(lab1,lab2); 36 | 37 | % now compute the CMC weights 38 | Lweight = [lab1(:,1)<16]*0.511+(1-[lab1(:,1)<16]).*(0.040975*lab1(:,1))./(1 + 0.01765*lab1(:,1)); 39 | [h,c] = cart2pol(lab1(:,2), lab1(:,3)); 40 | h = h*180/pi; 41 | 42 | Cweight = 0.638 + (0.0638*c)./(1 + 0.0131*c); 43 | index = (164180); 74 | h1 = (1-index).*h1 + index.*(h1-180); 75 | h2 = (1-index).*h2 + index.*(h2-180); 76 | 77 | p = (h2-h1); 78 | 79 | index = (p==0); 80 | p = (1-index).*p + index*1; 81 | index = (p>180); 82 | p = (1-index).*p + index.*(p-360); 83 | 84 | p = p./abs(p); 85 | 86 | end -------------------------------------------------------------------------------- /tools/3rdparty/color_science/xyz2lab.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION xyz2lab 3 | % *** 4 | % *** function [lab] = xyz2lab(xyz, obs, xyzw) 5 | % *** computes LAB from XYZ 6 | % *** xyz is an n by 3 matrix 7 | % *** e.g. set obs to 'd65_64 for D65 and 1964 8 | % *** set obs to 'user' to use optional argument 9 | % *** xyzw as the white point 10 | % =================================================== 11 | 12 | function [lab] = xyz2lab(xyz,obs,xyzw) 13 | 14 | if (size(xyz,2)~=3) 15 | disp('xyz must be n by 3'); return; 16 | end 17 | lab = zeros(size(xyz,1),size(xyz,2)); 18 | 19 | if strcmp('a_64',obs) 20 | white=[111.144 100.00 35.200]; 21 | elseif strcmp('a_31', obs) 22 | white=[109.850 100.00 35.585]; 23 | elseif strcmp('c_64', obs) 24 | white=[97.285 100.00 116.145]; 25 | elseif strcmp('c_31', obs) 26 | white=[98.074 100.00 118.232]; 27 | elseif strcmp('d50_64', obs) 28 | white=[96.720 100.00 81.427]; 29 | elseif strcmp('d50_31', obs) 30 | white=[96.422 100.00 82.521]; 31 | elseif strcmp('d55_64', obs) 32 | white=[95.799 100.00 90.926]; 33 | elseif strcmp('d55_31', obs) 34 | white=[95.682 100.00 92.149]; 35 | elseif strcmp('d65_64', obs) 36 | white=[94.811 100.00 107.304]; 37 | elseif strcmp('d65_31', obs) 38 | white=[95.047 100.00 108.883]; 39 | elseif strcmp('d75_64', obs) 40 | white=[94.416 100.00 120.641]; 41 | elseif strcmp('d75_31', obs) 42 | white=[94.072 100.00 122.638]; 43 | elseif strcmp('f2_64', obs) 44 | white=[103.279 100.00 69.027]; 45 | elseif strcmp('f2_31', obs) 46 | white=[99.186 100.00 67.393]; 47 | elseif strcmp('f7_64', obs) 48 | white=[95.792 100.00 107.686]; 49 | elseif strcmp('f7_31', obs) 50 | white=[95.041 100.00 108.747]; 51 | elseif strcmp('f11_64', obs) 52 | white=[103.863 100.00 65.607]; 53 | elseif strcmp('f11_31', obs) 54 | white=[100.962 100.00 64.350]; 55 | elseif strcmp('user', obs) 56 | white=xyzw; 57 | else 58 | disp('unknown option obs'); 59 | disp('use d65_64 for D65 and 1964 observer'); return; 60 | end 61 | 62 | lab = zeros(size(xyz,1),3); 63 | 64 | fx = zeros(size(xyz,1),3); 65 | for i=1:3 66 | index = (xyz(:,i)/white(i) > (6/29)^3); 67 | fx(:,i) = fx(:,i) + index.*(xyz(:,i)/white(i)).^(1/3); 68 | fx(:,i) = fx(:,i) + (1-index).*((841/108)*(xyz(:,i)/white(i)) + 4/29); 69 | end 70 | 71 | lab(:,1)=116*fx(:,2)-16; 72 | lab(:,2) = 500*(fx(:,1)-fx(:,2)); 73 | lab(:,3) = 200*(fx(:,2)-fx(:,3)); 74 | 75 | end 76 | % ==================================================== 77 | % *** END FUNCTION xyz2lab 78 | % ==================================================== 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/xyz2luv.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION xyz2luv 3 | % *** 4 | % *** function [luv,up,vp] = xyz2lab(xyz, obs, xyzw) 5 | % *** computes LUV and uv prime from XYZ 6 | % *** xyz is an n by 3 matrix 7 | % *** e.g. set obs to 'd65_64 for D65 and 1964 8 | % *** set obs to 'user' to use optional argument 9 | % *** xyzw as the white point 10 | % =================================================== 11 | function [luv,up,vp] = xyz2luv(xyz,obs) 12 | 13 | if (size(xyz,2)~=3) 14 | disp('xyz must be n by 3'); return; 15 | end 16 | luv = zeros(size(xyz,1),size(xyz,2)); 17 | 18 | if strcmp('a_64',obs) 19 | white=[111.144 100.00 35.200]; 20 | elseif strcmp('a_31', obs) 21 | white=[109.850 100.00 35.585]; 22 | elseif strcmp('c_64', obs) 23 | white=[97.285 100.00 116.145]; 24 | elseif strcmp('c_31', obs) 25 | white=[98.074 100.00 118.232]; 26 | elseif strcmp('d50_64', obs) 27 | white=[96.720 100.00 81.427]; 28 | elseif strcmp('d50_31', obs) 29 | white=[96.422 100.00 82.521]; 30 | elseif strcmp('d55_64', obs) 31 | white=[95.799 100.00 90.926]; 32 | elseif strcmp('d55_31', obs) 33 | white=[95.682 100.00 92.149]; 34 | elseif strcmp('d65_64', obs) 35 | white=[94.811 100.00 107.304]; 36 | elseif strcmp('d65_31', obs) 37 | white=[95.047 100.00 108.883]; 38 | elseif strcmp('d75_64', obs) 39 | white=[94.416 100.00 120.641]; 40 | elseif strcmp('d75_31', obs) 41 | white=[94.072 100.00 122.638]; 42 | elseif strcmp('f2_64', obs) 43 | white=[103.279 100.00 69.027]; 44 | elseif strcmp('f2_31', obs) 45 | white=[99.186 100.00 67.393]; 46 | elseif strcmp('f7_64', obs) 47 | white=[95.792 100.00 107.686]; 48 | elseif strcmp('f7_31', obs) 49 | white=[95.041 100.00 108.747]; 50 | elseif strcmp('f11_64', obs) 51 | white=[103.863 100.00 65.607]; 52 | elseif strcmp('f11_31', obs) 53 | white=[100.962 100.00 64.350]; 54 | elseif strcmp('user', obs) 55 | white=xyzw; 56 | else 57 | disp('unknown option obs'); 58 | disp('use d65_64 for D65 and 1964 observer'); return; 59 | end 60 | 61 | 62 | % compute u' v' for sample 63 | up = 4*xyz(:,1)./(xyz(:,1) + 15*xyz(:,2) + 3*xyz(:,3)); 64 | vp = 9*xyz(:,2)./(xyz(:,1) + 15*xyz(:,2) + 3*xyz(:,3)); 65 | % compute u' v' for white 66 | upw = 4*white(1)/(white(1) + 15*white(2) + 3*white(3)); 67 | vpw = 9*white(2)/(white(1) + 15*white(2) + 3*white(3)); 68 | 69 | index = (xyz(:,2)/white(2) > 0.008856); 70 | luv(:,1) = luv(:,1) + index.*(116*(xyz(:,2)/white(2)).^(1/3) - 16); 71 | luv(:,1) = luv(:,1) + (1-index).*(903.3*(xyz(:,2)/white(2))); 72 | 73 | luv(:,2) = 13*luv(:,1).*(up - upw); 74 | luv(:,3) = 13*luv(:,1).*(vp - vpw); 75 | 76 | end 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/r2xyz.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION r2xyz 3 | % *** 4 | % *** function [xyz] = r2xyz(p, startw, endw, obs) 5 | % *** computes XYZ from reflectance p 6 | % *** p is an n by w matrix of n spectra 7 | % *** e.g. set obs to 'd65_64 for D65 and 1964 8 | % *** the startw and endw variables denote first and 9 | % *** last wavelengths (e.g. 400 and 700) for p which 10 | % *** must be 10-nm data in the range 360-780 11 | % =================================================== 12 | 13 | function [xyz] = r2xyz(p, startw, endw, obs) 14 | 15 | if ((endw>780) | (startw<360) | (rem(endw,10)~=0) | (rem(startw,10)~=0)) 16 | disp('startw and endw must be divisible by 10') 17 | disp('wavelength range must be 360-780 or less'); 18 | return; 19 | end 20 | 21 | load weights.mat 22 | % weights.mat contains the tables of weights 23 | if strcmp('a_64',obs) 24 | cie = a_64; 25 | elseif strcmp('a_31', obs) 26 | cie = a_31; 27 | elseif strcmp('c_64', obs) 28 | cie = c_64; 29 | elseif strcmp('c_31', obs) 30 | cie = c_31; 31 | elseif strcmp('d50_64', obs) 32 | cie = d50_64; 33 | elseif strcmp('d50_31', obs) 34 | cie = d50_31; 35 | elseif strcmp('d55_64', obs) 36 | cie = d55_64; 37 | elseif strcmp('d55_31', obs) 38 | cie = d55_31; 39 | elseif strcmp('d65_64', obs) 40 | cie = d65_64; 41 | elseif strcmp('d65_31', obs) 42 | cie = d65_31; 43 | elseif strcmp('d75_64', obs) 44 | cie = d75_64; 45 | elseif strcmp('d75_31', obs) 46 | cie = d75_31; 47 | elseif strcmp('f2_64', obs) 48 | cie = f2_64; 49 | elseif strcmp('f2_31', obs) 50 | cie = f2_31; 51 | elseif strcmp('f7_64', obs) 52 | cie = f7_64; 53 | elseif strcmp('f7_31', obs) 54 | cie = f7_31; 55 | elseif strcmp('f11_64', obs) 56 | cie = f11_64; 57 | elseif strcmp('f11_31', obs) 58 | cie = f11_31; 59 | else 60 | disp('unknown option obs'); 61 | disp('use d65_64 for D65 and 1964 observer'); 62 | return; 63 | end 64 | 65 | % check dimensions of P 66 | dim = size(p); 67 | N = ((endw-startw)/10 + 1); 68 | if (dim(2) ~= N) 69 | disp('dimensions of p inconsistent'); 70 | return; 71 | end 72 | 73 | % deal with possible truncation of reflectance 74 | i = (startw - 360)/10 + 1; 75 | if (i>1) 76 | cie(i,:) = cie(i,:) + sum(cie(1:i-1,:)); 77 | end 78 | j = i + N - 1; 79 | if (j<43) 80 | cie(j,:) = cie(j,:) + sum(cie(j+1:43,:)); 81 | end 82 | cie = cie(i:j,:); 83 | 84 | % the main calculation 85 | xyz = (p*cie)*100/sum(cie(:,2)); 86 | 87 | end 88 | % ==================================================== 89 | % *** END FUNCTION r2xyz 90 | % ==================================================== 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /image_denoise/nl_mean.m: -------------------------------------------------------------------------------- 1 | % Created by Shen Quanmin on 2019/02/24. 2 | % Copyright ? 2018 Shen Quanmin. All rights reserved. 3 | % Reference articles: 4 | % 1. Antoni Buades, etc. A non-local algorithms for image denoising. 2005 5 | % 2. Antoni Buades, etc. Non-Local Means Denoising. 2011 6 | % (http://dx.doi.org/10.5201/ipol.2011.bcm_nlm) 7 | function [ res_image ] = nl_mean(image, sigma, k, half_patch_sz, half_search_sz) 8 | %NL_MEAN nonlocal mean denoising algorithm implementation. 9 | % image -- input image. 10 | % sigma -- input image noise variance. 11 | % k -- input factor to calculate h for denoising. 12 | % half_patch_sz -- half size of block to find similar patches. 13 | % half_search_sz -- half size of the search window. 14 | if size(image,3) > 1 15 | error('Only support gray image'); 16 | end 17 | 18 | Ss = half_search_sz; 19 | Ps = half_patch_sz; 20 | Pnum = (2*Ps+1)^2; 21 | [w,h] = size(image); 22 | pad_image = paddarray_symmetric(image, Ps+Ss); 23 | 24 | sigma22 = sigma*sigma; 25 | h2 = k*k*sigma22; 26 | 27 | ref_image = pad_image(1+Ss:h+2*Ps+Ss, 1+Ss:w+2*Ps+Ss); 28 | weight_sum = zeros([w,h]); 29 | res_image = zeros([w,h]); 30 | 31 | for r = -Ss:Ss 32 | for c = -Ss:Ss 33 | %1. Get cumsum of the difference image. 34 | diff = pad_image(1+Ss+r:h+2*Ps+Ss+r,1+Ss+c:w+2*Ps+Ss+c) - ref_image; 35 | diff2 = diff .^ 2; 36 | cumsum_diff2 = cumsum(diff2, 1); 37 | cumsum_diff2 = cumsum(cumsum_diff2, 2); 38 | pad_cum_diff2 = padarray(cumsum_diff2, [1,1], 0, 'pre'); 39 | %2. Get weight of every patch. 40 | block_diff_sum2 = pad_cum_diff2(2+2*Ps:end,2+2*Ps:end) + ... 41 | pad_cum_diff2(1:end-2*Ps-1,1:end-2*Ps-1) - ... 42 | pad_cum_diff2(2+2*Ps:end,1:end-2*Ps-1) - ... 43 | pad_cum_diff2(1:end-2*Ps-1,2+2*Ps:end); 44 | dist = block_diff_sum2 ./ Pnum; 45 | weight = exp(-max(dist-sigma22, 0)./h2); 46 | weight_sum = weight_sum + weight; 47 | %3. Add weighted image. 48 | res_image = res_image + weight .* pad_image(1+Ps+Ss+r:Ps+Ss+r+h,... 49 | 1+Ps+Ss+c:Ps+Ss+c+w); 50 | end 51 | end 52 | %4. Get denoised image. 53 | res_image = res_image ./ weight_sum; 54 | end 55 | 56 | %% Algorithm steps 57 | % 1. For every pixel, compute the patch distances d with the reference patch. 58 | % 2. According these distances, get these weights w = 59 | % exp(-max(d-2*sigma2,0)/h2). 60 | % 3. Aggregate the corresponding pixel values with weights w. 61 | 62 | % Advantages: 63 | % 1. Use the spatial local similarity of images with geometrical 64 | % configuration. 65 | % 2. Compare to spatial filter, it can preserve local texture. 66 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cie00de.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cie00de 3 | % *** 4 | % *** function [de,dl,dc,dh] = cie00de(lab1,lab2,sl,sc,sh) 5 | % *** computes colour difference from CIELAB values 6 | % *** using CIEDE2000 formula 7 | % *** inputs must be n by 3 matrices 8 | % *** and contain L*, a* and b* values 9 | % *** see also cielabde, cmcde, and cie94de 10 | function [de,dl,dc,dh] = cie00de(lab1,lab2,sl,sc,sh) 11 | 12 | if (size(lab1,1)~=size(lab2,1)) 13 | disp('inputs must be the same size'); return; 14 | end 15 | 16 | if (size(lab1,2)~=3 | size(lab2,2)~=3) 17 | disp('inputs must be n by 3'); return; 18 | end 19 | if (nargin<5) 20 | disp('using default values of l:c') 21 | sl=1; sc=1; sh=1; 22 | end 23 | 24 | de = zeros(1,size(lab1,2)); 25 | dl = zeros(1,size(lab1,2)); 26 | dc = zeros(1,size(lab1,2)); 27 | dh = zeros(1,size(lab1,2)); 28 | 29 | % convert the cartesian a*b* to polar chroma and hue 30 | [h1,c1] = cart2pol(lab1(:,2), lab1(:,3)); 31 | [h2,c2] = cart2pol(lab2(:,2), lab2(:,3)); 32 | h1 = h1*180/pi; 33 | h2 = h2*180/pi; 34 | meanC = (c2+c1)/2; 35 | 36 | % compute G factor using the arithmetic mean chroma 37 | G = 0.5 - 0.5*(((meanC.^7)./(meanC.^7 + 25^7)).^0.5); 38 | 39 | % transform the a* values 40 | lab1(:,2) = (1 + G).*lab1(:,2); 41 | lab2(:,2) = (1 + G).*lab2(:,2); 42 | 43 | % recompute the polar coordinates using the new a* 44 | [h1,c1] = cart2pol(lab1(:,2), lab1(:,3)); 45 | [h2,c2] = cart2pol(lab2(:,2), lab2(:,3)); 46 | h1 = h1*180/pi; 47 | h2 = h2*180/pi; 48 | 49 | % compute the mean values for use later 50 | meanC = (c2+c1)/2; 51 | meanL = (lab2(:,1)+lab1(:,1))/2; 52 | 53 | meanH = (h1+h2)/2; 54 | % Identify positions for which abs hue diff exceeds 180 degrees 55 | meanH = meanH - (abs(h1-h2)>180)*180; 56 | % rollover ones that come -ve 57 | meanH = meanH + (meanH < 0)*360; 58 | % Check if one of the chroma values is zero, in which case set 59 | % mean hue to the sum which is equivalent to other value 60 | index = find(c1.*c2 == 0); 61 | meanH(index) = h1(index)+h2(index); 62 | 63 | 64 | % compute the basic delta values 65 | dh = (h2-h1); 66 | index = dh>180; 67 | dh = (index).*(dh-360) + (1-index).*dh; 68 | dh = 2*((c1.*c2).^0.5).*sin((dh/2)*pi/180); 69 | dl = lab2(:,1)-lab1(:,1); 70 | dc = c2-c1; 71 | 72 | T = 1 - 0.17*cos((meanH-30)*pi/180) + 0.24*cos((2*meanH)*pi/180); 73 | T = T + 0.32*cos((3*meanH + 6)*pi/180) - 0.20*cos((4*meanH - 63)*pi/180); 74 | 75 | dthe = 30*exp(-((meanH-275)/25).^2); 76 | rc = 2*((meanC.^7)./(meanC.^7 + 25^7)).^0.5; 77 | rt = -sin(2*dthe*pi/180).*rc; 78 | 79 | Lweight = 1 + (0.015*(meanL-50).^2)./((20 + (meanL-50).^2).^0.5); 80 | Cweight = 1 + 0.045*meanC; 81 | Hweight = 1 + 0.015*meanC.*T; 82 | 83 | dl = dl./(Lweight*sl); 84 | dc = dc./(Cweight*sc); 85 | dh = dh./(Hweight*sh); 86 | 87 | %disp([G T Lweight Cweight Hweight rt]) 88 | 89 | de = sqrt(dl.^2 + dc.^2 + dh.^2 + rt.*dc.*dh); 90 | 91 | 92 | -------------------------------------------------------------------------------- /image_resize/cubic_convolution/test_demo.m: -------------------------------------------------------------------------------- 1 | nth_zero = 23; 2 | sz = [64 64]; 3 | h = (sqrt(2*nth_zero*pi) - sqrt(2*(nth_zero-1)*pi)) / 2; 4 | sampled_array = sample_rad([h,h], sz); 5 | figure('Name', 'Orignal array(64x64)'); 6 | imshow(sampled_array, [-1, 1]); 7 | imwrite(sampled_array, '../../temp/original_sampled_array_64x64.jpg'); 8 | 9 | x_max = h*(sz(1)-1); 10 | y_max = x_max; 11 | sz_1 = [336 350]; 12 | h_1 = [x_max y_max] ./ (sz_1-1); 13 | org_sampled_array = sample_rad(h_1, sz_1); 14 | figure('Name', 'Original array(350x336)'); 15 | imshow(org_sampled_array, [-1, 1]); 16 | imwrite(org_sampled_array, '../../temp/original_array_350x336.jpg'); 17 | 18 | figure('Name', 'Scale array by nearest(350x336)'); 19 | %scaled_array_nearest = imresize(sampled_array, sz_1, 'nearest'); 20 | scaled_array_nearest = fast_nn_resize(sampled_array, sz_1); 21 | imshow(scaled_array_nearest, [-1,1]); 22 | imwrite(scaled_array_nearest, '../../temp/scaled_array_nearest_350x336.jpg'); 23 | 24 | figure('Name', 'Scale array by bilinear(350x336)'); 25 | %scaled_array_bilinear = imresize(sampled_array, sz_1, 'bilinear'); 26 | scaled_array_bilinear = bilinear_resize(sampled_array, sz_1); 27 | imshow(scaled_array_bilinear, [-1,1]); 28 | imwrite(scaled_array_bilinear, '../../temp/scaled_array_bilinear_350x336.jpg'); 29 | 30 | scaled_array_cubic_conv = cubic_conv(sampled_array, sz_1); 31 | figure('Name', 'Scaled array cubic convolution(350x336)'); 32 | imshow(scaled_array_cubic_conv, [-1, 1]); 33 | imwrite(scaled_array_cubic_conv, '../../temp/scaled_array_cubic_conv_350x336.jpg'); 34 | 35 | figure('Name', 'Scale array by matlab(350x336)'); 36 | scaled_array_matlab = imresize(sampled_array, sz_1, 'cubic'); 37 | imshow(scaled_array_matlab, [-1,1]); 38 | imwrite(scaled_array_matlab, '../../temp/scaled_array_matlab_350x336.jpg'); 39 | 40 | %Compute absolute error 41 | nearest_error = abs(org_sampled_array - scaled_array_nearest); 42 | linear_error = abs(org_sampled_array - scaled_array_bilinear); 43 | cubic_conv_error = abs(org_sampled_array - scaled_array_cubic_conv); 44 | cubic_matlab_error = abs(org_sampled_array - scaled_array_matlab); 45 | max_error = max(linear_error(:)) 46 | figure('Name', 'Error compare'); 47 | subplot(2,2,1); 48 | imshow(nearest_error, [0, max_error]); 49 | imwrite(nearest_error, '../../temp/nearest_error.jpg') 50 | title('Nearest Error'); 51 | subplot(2,2,2); 52 | imshow(linear_error, [0, max_error]); 53 | title('Bilinear Error'); 54 | imwrite(linear_error, '../../temp/lineare_error.jpg'); 55 | subplot(2,2,3); 56 | imshow(cubic_conv_error, [0, max_error]); 57 | imwrite(cubic_conv_error, '../../temp/cubic_conv_error.jpg'); 58 | title('Cubic convolution Error'); 59 | subplot(2,2,4); 60 | imshow(cubic_matlab_error, [0, max_error]); 61 | title('Cubic matlab Error'); 62 | imwrite(cubic_matlab_error, '../../temp/cubic_matlab_error.jpg'); 63 | 64 | % x = [1 2 4 8 16 32 64 128; 1 2 4 8 16 32 64 128; 1 2 4 8 16 32 64 128]; 65 | % x_conv = cubic_conv(x, [3 16]) -------------------------------------------------------------------------------- /image_resize/edge_guided_interpolation/diag_interp.m: -------------------------------------------------------------------------------- 1 | function [ I_45, I_135 ] = diag_interp( input_image, method ) 2 | %DIAG_INTERP Summary of this function goes here 3 | % Detailed explanation goes here 4 | I_45 = zeros(size(input_image)); 5 | I_135 = I_45; 6 | if strcmp(method, 'linear') 7 | pad_image = padarray(input_image, [1, 1], 'symmetric', 'post'); 8 | kernel_45 = [0, 0.5; 0.5, 0]; 9 | kernel_135 = [0.5 0; 0, 0.5]; 10 | I_45 = conv2(pad_image, kernel_45, 'valid'); 11 | I_135 = conv2(pad_image, kernel_135, 'valid'); 12 | elseif strcmp(method, 'cubic_convolution') 13 | org_sz = size(input_image); 14 | s = [1.5 0.5 -0.5 -1.5]; 15 | kernel = cubic_kernel(s); 16 | % Calculate I_135 17 | pad_image = padarray(input_image, [1, 1], 'symmetric', 'pre'); 18 | pad_image = padarray(pad_image, [2, 2], 'symmetric', 'post'); 19 | image_3d_135 = zeros(org_sz(1),org_sz(2),4); 20 | image_3d_45 = image_3d_135; 21 | image_3d_135(:,:,1) = pad_image(1:org_sz(1),1:org_sz(2))*kernel(1); 22 | image_3d_135(:,:,2) = pad_image(2:org_sz(1)+1,2:org_sz(2)+1)*kernel(2); 23 | image_3d_135(:,:,3) = pad_image(3:org_sz(1)+2,3:org_sz(2)+2)*kernel(3); 24 | image_3d_135(:,:,4) = pad_image(4:org_sz(1)+3,4:org_sz(2)+3)*kernel(4); 25 | 26 | % image_3d_135 = [pad_image(1:org_sz(1),1:org_sz(2))*kernel(1), pad_image(2:org_sz(1)+1,2:org_sz(2)+1)*kernel(2), ... 27 | % pad_image(3:org_sz(1)+2,3:org_sz(2)+2)*kernel(3), pad_image(4:org_sz(1)+3,4:org_sz(2)+3)*kernel(4)]; 28 | I_135 = sum(image_3d_135,3); 29 | % Calculate I_45 30 | image_3d_45(:,:,1) = pad_image(1:org_sz(1),4:org_sz(2)+3)*kernel(1); 31 | image_3d_45(:,:,2) = pad_image(2:org_sz(1)+1,3:org_sz(2)+2)*kernel(2); 32 | image_3d_45(:,:,3) = pad_image(3:org_sz(1)+2,2:org_sz(2)+1)*kernel(3); 33 | image_3d_45(:,:,4) = pad_image(4:org_sz(1)+3,1:org_sz(2))*kernel(4); 34 | % image_3d_45 = [pad_image(1:org_sz(1),4:org_sz(2)+3)*kernel(1), pad_image(2:org_sz(1)+1,3:org_sz(2)+2)*kernel(2), ... 35 | % pad_image(3:org_sz(1)+2,2:org_sz(2)+1)*kernel(3), pad_image(4:org_sz(1)+3,1:org_sz(2))*kernel(4)]; 36 | I_45 = sum(image_3d_45,3); 37 | end 38 | end 39 | 40 | 41 | function [ kernel_res ] = cubic_kernel( s ) 42 | kernel_res = zeros(size(s)); 43 | kernel_res(abs(s)0 & s < 1)) = kernel_0_1(s(s>0 & s < 1)); 47 | kernel_res((s>1 & s < 2)) = kernel_1_2(s(s>1 & s < 2)); 48 | end 49 | 50 | function [ kernel_res ] = kernel_0_1( s ) 51 | s2 = s.*s; 52 | s3 = s2.*s; 53 | kernel_res = 1.5*s3 - 2.5*s2 + 1; 54 | end 55 | 56 | function [ kernel_res ] = kernel_1_2( s ) 57 | s2 = s.*s; 58 | s3 = s2.*s; 59 | kernel_res = -0.5*s3 + 2.5*s2 - 4*s + 2; 60 | end 61 | 62 | -------------------------------------------------------------------------------- /demosaic/high_quality_linear_interp/grad_bilinear_demosaic.m: -------------------------------------------------------------------------------- 1 | % Copyright (C) 2018 Shen QM 2 | % 3 | % This program is free software: you can redistribute it and/or modify 4 | % it under the terms of the GNU General Public License as published by 5 | % the Free Software Foundation, either version 3 of the License, or 6 | % (at your option) any later version. 7 | % 8 | % This program is distributed in the hope that it will be useful, 9 | % but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | % GNU General Public License for more details. 12 | % 13 | % You should have received a copy of the GNU General Public License 14 | % along with this program. If not, see . 15 | 16 | % This is a implement of "High-quality Linear Interpolation for Demosaicing of 17 | % Bayer-patterned Color Images". 18 | function [ rgb_image ] = grad_bilinear_demosaic( cfa_image, cfa_pattern ) 19 | %GRAD_BILINEAR_DEMOSAIC Summary of this function goes here 20 | % Detailed explanation goes here 21 | if isequal(cfa_pattern,[1 2 2 3]) 22 | rgb_image = grad_bilinear_kernel_rggb(cfa_image); 23 | else 24 | end 25 | end 26 | 27 | function [ rgb_image ] = grad_bilinear_kernel_rggb(cfa_image) 28 | % 1. Filter. 29 | kernel_g_rb = [0 0 -1 0 0; 30 | 0 0 2 0 0; 31 | -1 2 4 2 -1; 32 | 0 0 2 0 0; 33 | 0 0 -1 0 0] / 8; 34 | kernel_rb_g_0 = [ 0 0 1/2 0 0; 35 | 0 -1 0 -1 0; 36 | -1 4 5 4 -1; 37 | 0 -1 0 -1 0; 38 | 0 0 1/2 0 0] / 8; 39 | kernel_rb_g_1 = kernel_rb_g_0'; 40 | kernel_rb_br = [ 0 0 -3/2 0 0; 41 | 0 2 0 2 0; 42 | -3/2 0 6 0 -3/2; 43 | 0 2 0 2 0; 44 | 0 0 -3/2 0 0] / 8; 45 | padded_cfa = paddarray_symmetric(cfa_image, 2); 46 | filter_cfa_g_rb = filter2(kernel_g_rb, padded_cfa, 'valid'); 47 | filter_cfa_rb_g_0 = filter2(kernel_rb_g_0, padded_cfa, 'valid'); 48 | filter_cfa_rb_g_1 = filter2(kernel_rb_g_1, padded_cfa, 'valid'); 49 | filter_cfa_rb_br = filter2(kernel_rb_br, padded_cfa, 'valid'); 50 | 51 | % 2. Get the rgb image. 52 | rgb_image = zeros(size(cfa_image,1),size(cfa_image,2),3); 53 | % g channel 54 | rgb_image(:,:,2) = cfa_image; 55 | rgb_image(1:2:end,1:2:end,2) = filter_cfa_g_rb(1:2:end,1:2:end); 56 | rgb_image(2:2:end,2:2:end,2) = filter_cfa_g_rb(2:2:end,2:2:end); 57 | % r channel 58 | rgb_image(:,:,1) = cfa_image; 59 | rgb_image(1:2:end,2:2:end,1) = filter_cfa_rb_g_0(1:2:end,2:2:end); 60 | rgb_image(2:2:end,1:2:end,1) = filter_cfa_rb_g_1(2:2:end,1:2:end); 61 | rgb_image(2:2:end,2:2:end,1) = filter_cfa_rb_br(2:2:end,2:2:end); 62 | % b channel 63 | rgb_image(:,:,3) = cfa_image; 64 | rgb_image(1:2:end,2:2:end,3) = filter_cfa_rb_g_1(1:2:end,2:2:end); 65 | rgb_image(2:2:end,1:2:end,3) = filter_cfa_rb_g_0(2:2:end,1:2:end); 66 | rgb_image(1:2:end,1:2:end,3) = filter_cfa_rb_br(1:2:end,1:2:end); 67 | end -------------------------------------------------------------------------------- /tools/3rdparty/color_science/lab2xyz.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION lab2xyz 3 | % *** 4 | % *** function [xyz] = lab2xyz(lab, obs, xyzw) 5 | % *** computes XYZ from LAB 6 | % *** lab is an n by 3 matrix 7 | % *** e.g. set obs to 'd65_64 for D65 and 1964 8 | % *** set obs to 'user' to use optional argument 9 | % *** xyzw as the white point 10 | % =================================================== 11 | 12 | function [xyz] = lab2xyz(lab,obs,xyzw) 13 | 14 | if strcmp('a_64',obs) 15 | white=[111.144 100.00 35.200]; 16 | elseif strcmp('a_31', obs) 17 | white=[109.850 100.00 35.585]; 18 | elseif strcmp('c_64', obs) 19 | white=[97.285 100.00 116.145]; 20 | elseif strcmp('c_31', obs) 21 | white=[98.074 100.00 118.232]; 22 | elseif strcmp('d50_64', obs) 23 | white=[96.720 100.00 81.427]; 24 | elseif strcmp('d50_31', obs) 25 | white=[96.422 100.00 82.521]; 26 | elseif strcmp('d55_64', obs) 27 | white=[95.799 100.00 90.926]; 28 | elseif strcmp('d55_31', obs) 29 | white=[95.682 100.00 92.149]; 30 | elseif strcmp('d65_64', obs) 31 | white=[94.811 100.00 107.304]; 32 | elseif strcmp('d65_31', obs) 33 | white=[95.047 100.00 108.883]; 34 | elseif strcmp('d75_64', obs) 35 | white=[94.416 100.00 120.641]; 36 | elseif strcmp('d75_31', obs) 37 | white=[94.072 100.00 122.638]; 38 | elseif strcmp('f2_64', obs) 39 | white=[103.279 100.00 69.027]; 40 | elseif strcmp('f2_31', obs) 41 | white=[99.186 100.00 67.393]; 42 | elseif strcmp('f7_64', obs) 43 | white=[95.792 100.00 107.686]; 44 | elseif strcmp('f7_31', obs) 45 | white=[95.041 100.00 108.747]; 46 | elseif strcmp('f11_64', obs) 47 | white=[103.863 100.00 65.607]; 48 | elseif strcmp('f11_31', obs) 49 | white=[100.962 100.00 64.350]; 50 | elseif strcmp('user', obs) 51 | white=xyzw; 52 | else 53 | disp('unknown option obs'); 54 | disp('use d65_64 for D65 and 1964 observer'); return; 55 | end 56 | 57 | if (size(lab,2)~=3) 58 | disp('lab must be n by 3'); return; 59 | end 60 | 61 | xyz = zeros(size(lab,1),size(lab,2)); 62 | 63 | % compute Y 64 | index = (lab(:,1) > 7.9996); 65 | xyz(:,2) = xyz(:,2) + index.*(white(2)*((lab(:,1)+16)/116).^3); 66 | xyz(:,2) = xyz(:,2) + (1-index).*(white(2)*lab(:,1)/903.3); 67 | 68 | % compute fy for use later 69 | fy = xyz(:,2)/white(2); 70 | index = (fy > 0.008856); 71 | fy = zeros(size(lab,1),1); 72 | fy = fy + (index).*(xyz(:,2)/white(2)).^(1/3); 73 | fy = fy + (1-index).*(7.787*xyz(:,2)/white(2) + 16/116); 74 | 75 | % compute X 76 | index = ((lab(:,2)/500 + fy).^3 > 0.008856); 77 | xyz(:,1) = xyz(:,1) + (index).*(white(1)*(lab(:,2)/500 + fy).^3); 78 | xyz(:,1) = xyz(:,1) + (1-index).*(white(1)*((lab(:,2)/500 + fy) - 16/116)/7.787); 79 | 80 | % compute Z 81 | index = ((fy - lab(:,3)/200).^3 > 0.008856); 82 | xyz(:,3) = xyz(:,3) + (index).*(white(3)*(fy - lab(:,3)/200).^3); 83 | xyz(:,3) = xyz(:,3) + (1-index).*(white(3)*((fy - lab(:,3)/200) - 16/116)/7.787); 84 | 85 | if lab(1)>7.9996 86 | t(1) = white(1)*(lab(2)/500 +(lab(1)+16)/116)^3; 87 | t(2) = white(2)*((lab(1)+16)/116)^3; 88 | t(3) = white(3)*(-lab(3)/200+(lab(1)+16)/116)^3; 89 | else 90 | t(1) = white(1)*(lab(2)/500 +lab(1)/116)/7.787; 91 | t(2) = white(2)*lab(1)/(116*7.787); 92 | t(3) = white(3)*(-lab(3)/200+lab(1)/116)/7.787; 93 | end 94 | disp([xyz; t]) 95 | 96 | 97 | 98 | 99 | 100 | end 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cielabplot.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cielabplot 3 | % *** 4 | % *** function cielabplot 5 | % *** creates a CIELAB figure representation 6 | % *** see also cieplot 7 | % =================================================== 8 | plot([0 0],[-60 60],'k','LineWidth',2) 9 | hold on 10 | plot([-60 60],[0 0],'k','LineWidth',2) 11 | axis([-60 60 -60 60]) 12 | gr = [0.7 0.7 0.7]; 13 | r = [.9 0 0]; 14 | g = [0 .9 0]; 15 | y = [.9 .9 0]; 16 | bl = [0 0 .9]; 17 | index = 0; 18 | % first quadrant 19 | index = index+1; 20 | a = 50; 21 | b = 0; 22 | ab(index,:)=[a b]; 23 | col(index,:) = r; 24 | for i=5:5:85 25 | index = index+1; 26 | a = cos(i*pi/180)*50; 27 | b = sin(i*pi/180)*50; 28 | ab(index,:)=[a b]; 29 | c = (a*r+(50-a)*y)/50; 30 | col(index,:)=c; 31 | end 32 | index = index+1; 33 | a = 0; 34 | b = 50; 35 | ab(index,:)=[a b]; 36 | col(index,:) = y; 37 | % grey 38 | index = index+1; 39 | a = 0; 40 | b = 0; 41 | ab(index,:)=[a b]; 42 | col(index,:) = gr; 43 | 44 | patch('Vertices',ab, 'Faces',[1:size(ab,1)], 'EdgeColor','none', ... 45 | 'FaceVertexCData',col,'FaceColor','interp') 46 | clear ab; 47 | 48 | index=0; 49 | % second quadrant 50 | index = index+1; 51 | a = 0; 52 | b = 50; 53 | ab(index,:)=[a b]; 54 | col(index,:) = y; 55 | for i=95:5:175 56 | index = index+1; 57 | a = cos(i*pi/180)*50; 58 | b = sin(i*pi/180)*50; 59 | ab(index,:)=[a b]; 60 | c=(b*y+(50-b)*g)/50; 61 | col(index,:)=c; 62 | end 63 | index = index+1; 64 | a = -50; 65 | b = 0; 66 | ab(index,:)=[a b]; 67 | col(index,:) = g; 68 | % grey 69 | index = index+1; 70 | a = 0; 71 | b = 0; 72 | ab(index,:)=[a b]; 73 | col(index,:) = gr; 74 | 75 | 76 | patch('Vertices',ab, 'Faces',[1:size(ab,1)], 'EdgeColor','none', ... 77 | 'FaceVertexCData',col,'FaceColor','interp') 78 | clear ab; 79 | 80 | index=0; 81 | % third quadrant 82 | index = index+1; 83 | a = -50; 84 | b = 0; 85 | ab(index,:)=[a b]; 86 | col(index,:) = g; 87 | for i=185:5:265 88 | index = index+1; 89 | a = cos(i*pi/180)*50; 90 | b = sin(i*pi/180)*50; 91 | ab(index,:)=[a b]; 92 | c=(-b*bl+(50+b)*g)/50; 93 | col(index,:)=c; 94 | end 95 | index = index+1; 96 | a = 0; 97 | b = -50; 98 | ab(index,:)=[a b]; 99 | col(index,:) = bl; 100 | % grey 101 | index = index+1; 102 | a = 0; 103 | b = 0; 104 | ab(index,:)=[a b]; 105 | col(index,:) = gr; 106 | 107 | patch('Vertices',ab, 'Faces',[1:size(ab,1)], 'EdgeColor','none', ... 108 | 'FaceVertexCData',col,'FaceColor','interp') 109 | clear ab; 110 | index=0; 111 | % fourth quadrant 112 | index = index+1; 113 | a = 0; 114 | b = -50; 115 | ab(index,:)=[a b]; 116 | col(index,:) = bl; 117 | for i=275:5:355 118 | index = index+1; 119 | a = cos(i*pi/180)*50; 120 | b = sin(i*pi/180)*50; 121 | ab(index,:)=[a b]; 122 | c = (a*r+(50-a)*bl)/50; 123 | col(index,:)=c; 124 | end 125 | index = index+1; 126 | a = 50; 127 | b = 0; 128 | ab(index,:)=[a b]; 129 | col(index,:) = r; 130 | % grey 131 | index = index+1; 132 | a = 0; 133 | b = 0; 134 | ab(index,:)=[a b]; 135 | col(index,:) = gr; 136 | 137 | patch('Vertices',ab, 'Faces',[1:size(ab,1)], 'EdgeColor','none', ... 138 | 'FaceVertexCData',col,'FaceColor','interp') 139 | clear ab; 140 | plot([0 0],[-60 60],'k','LineWidth',2) 141 | plot([-60 60],[0 0],'k','LineWidth',2) 142 | 143 | % ==================================================== 144 | % *** END FUNCTION cband 145 | % ==================================================== 146 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/printer_demo1.m: -------------------------------------------------------------------------------- 1 | clear 2 | 3 | e = 0.000001; 4 | p = 4.5; 5 | 6 | % load 746 standard xyz and cmyk values 7 | load train.mat 8 | % separate X,Y,Z into one single column 9 | ciexstd = xyz(:,1); 10 | cieystd = xyz(:,2); 11 | ciezstd = xyz(:,3); 12 | % separate X,Y,Z into one single column 13 | cstd = cmyk(:,1); 14 | mstd = cmyk(:,2); 15 | ystd = cmyk(:,3); 16 | kstd = cmyk(:,4); 17 | 18 | % load 104 test xyz and cmyk values 19 | load test.mat 20 | ctest = cmyk(:,1); 21 | mtest = cmyk(:,2); 22 | ytest = cmyk(:,3); 23 | ktest = cmyk(:,4); 24 | 25 | % calculate the distance between standard and test RGBs 26 | for j=1:104 27 | 28 | % compute the errors for the jth samples 29 | for i=1:746 30 | distance(i) = ((ctest(j)-cstd(i))^2+(mtest(j)-mstd(i))^2+(ytest(j)-ystd(i))^2+(ktest(j)-kstd(i))^2)^(1/2); 31 | distance(i) = (distance(i))^(p) + e; 32 | end 33 | 34 | % now sort the values 35 | temp = [ciexstd cieystd ciezstd cstd mstd ystd kstd distance']; 36 | temp1 = sortrows(temp,8); 37 | % find the first 10 with smallest distance 38 | temp2 = temp1(1:10,:); 39 | 40 | for n=1:10 41 | cdis(n) = (ctest(j)-temp2(n,4)); 42 | mdis(n) = (mtest(j)-temp2(n,5)); 43 | ydis(n) = (ytest(j)-temp2(n,6)); 44 | kdis(n) = (ktest(j)-temp2(n,7)); 45 | end 46 | 47 | temp3 = [temp2 cdis' mdis' ydis' kdis']; 48 | temp4 = sortrows(temp3,8); 49 | temp5 = sortrows(temp3,9); 50 | temp6 = sortrows(temp3,10); 51 | temp7 = sortrows(temp3,11); 52 | 53 | % find the smallest positive and smallest negative values for each plane 54 | index1=0; 55 | for n=1:9 56 | if temp4(n,8)*temp4(n+1,8) <= 0 57 | index1 = n; 58 | index2 = n+1; 59 | end 60 | end 61 | if (index1==0) 62 | t = sprintf('no switch point found in sample %d cyan plane', j); 63 | disp(t) 64 | index1 = 1; 65 | index2 = 2; 66 | end 67 | 68 | index3 = 0; 69 | for n=1:9 70 | if temp5(n,9)*temp5(n+1,9) <= 0 71 | index3 = n; 72 | index4 = n+1; 73 | end 74 | end 75 | if (index3==0) 76 | t = sprintf('no switch point found in sample %d megenta plane', j); 77 | disp(t) 78 | index3 = 1; 79 | index4 = 2; 80 | end 81 | 82 | index5 = 0; 83 | for n=1:9 84 | if temp6(n,10)*temp6(n+1,10) <= 0 85 | index5 = n; 86 | index6 = n+1; 87 | end 88 | end 89 | if (index5==0) 90 | t = sprintf('no switch point found in sample %d yellow plane', j); 91 | disp(t) 92 | index5 = 1; 93 | index6 = 2; 94 | end 95 | 96 | index7 = 0; 97 | for n=1:9 98 | if temp7(n,11)*temp7(n+1,11) <= 0 99 | index7 = n; 100 | index8 = n+1; 101 | end 102 | end 103 | if (index7==0) 104 | t = sprintf('no switch point found in sample %d black plane', j); 105 | disp(t) 106 | index7 = 1; 107 | index8 = 2; 108 | end 109 | 110 | temp7(1,:) = temp4(index1,:); 111 | temp7(2,:) = temp4(index2,:); 112 | temp7(3,:) = temp5(index3,:); 113 | temp7(4,:) = temp5(index4,:); 114 | temp7(5,:) = temp6(index5,:); 115 | temp7(6,:) = temp6(index6,:); 116 | temp7(7,:) = temp6(index7,:); 117 | temp7(8,:) = temp6(index8,:); 118 | 119 | sample = 1./temp7(:,8); 120 | 121 | sample = sample/sum(sample); 122 | 123 | temp7(:,8) = sample; 124 | 125 | % find estimated XYZs for test samples 126 | Xest = temp7(:,1).*temp7(:,8); 127 | Xest = sum(Xest); 128 | 129 | Yest = temp7(:,2).*temp7(:,8); 130 | Yest = sum(Yest); 131 | 132 | Zest = temp7(:,3).*temp7(:,8); 133 | Zest = sum(Zest); 134 | 135 | xyzest(j,:) = [Xest Yest Zest]; 136 | end 137 | 138 | Xest = xyzest(:,1); 139 | Yest = xyzest(:,2); 140 | Zest = xyzest(:,3); 141 | 142 | disp([xyz xyzest]) -------------------------------------------------------------------------------- /tools/3rdparty/color_science/ciecam02.m: -------------------------------------------------------------------------------- 1 | function [j,c,hq,m,h,s,q]=ciecam02(xyz,xyzw,la,yb,para) 2 | 3 | % function [j,c,hq,m,h,s,q,cd]=ciecam97s(xyz,xyzw,la,yb,para) 4 | % implements the CIECAM97s colour appearance model 5 | % operates on 1 by 3 matrix xyz containing tristimulus 6 | % values of the stimulus under the test illuminant 7 | % xyzt and xyzr are 1 by 3 matrices containing the 8 | % white points for the test and reference conditions 9 | % la and yb are the luminance and Y tristimulus values of 10 | % the achromatic background against which the sample is viewed 11 | % para is a 1 by 4 matrix containing c, Nc, Fll and F 12 | 13 | f = para(1); c = para(2); nc = para(3); 14 | MH = [0.38971 0.68898 -0.07868; -0.22981 1.18340 0.04641; 0.0 0.0 1.0]; 15 | M02 = [0.7328 0.4296 -0.1624; -0.7036 1.6975 0.0061; 0.0030 0.0136 0.9834]; 16 | Minv = [1.096124 -0.278869 0.182745; 0.454369 0.473533 0.072098; -0.009628 -0.005698 1.015326]; 17 | 18 | 19 | k = 1/(5*la+1); 20 | fl = (k^4)*la + 0.1*((1-k^4)^2)*((5*la)^(1/3)); 21 | n = yb/xyzw(2) 22 | ncb = 0.725*(1/n)^0.2; 23 | nbb = ncb; 24 | z = 1.48+sqrt(n); 25 | 26 | % step 1 27 | rgb = M02*xyz' 28 | rgbw = M02*xyzw' 29 | 30 | 31 | % step 2 32 | D = f*(1-(1/36)*exp((-la-42)/(92))) 33 | D=0.98 34 | 35 | % step 3 36 | Dr = (xyzw(2)/rgbw(1))*D+1-D 37 | Dg = (xyzw(2)/rgbw(2))*D+1-D 38 | Db = (xyzw(2)/rgbw(3))*D+1-D 39 | 40 | rgbc = rgb; 41 | rgbc(:,1)=Dr*rgb(:,1); 42 | rgbc(:,1)=Dr*rgb(:,1); 43 | rgbc(:,1)=Dr*rgb(:,1); 44 | disp(rgbc) 45 | pause 46 | 47 | rgbc(1) = (d*(rgbwr(2)/rgbw(2)) + 1 - d)*rgb(:,1); 48 | rgbc(2) = (d*(rgbwr(2)/rgbw(2)) + 1 - d)*rgb(:,2); 49 | rgbc(3) = (d*(rgbwr(2)/rgbw(2)) + 1 - d)*rgb(:,3); 50 | 51 | rgbwc(1) = (d*(rgbwr(2)/rgbw(2)) + 1 - d)*rgbw(1); 52 | rgbwc(2) = (d*(rgbwr(2)/rgbw(2)) + 1 - d)*rgbw(2); 53 | rgbwc(2) = (d*(rgbwr(2)/rgbw(2)) + 1 - d)*rgbw(3); 54 | 55 | 56 | rgbp = MH*Minv*rgbc; 57 | rgbpw = MH*Minv*rgbwc; 58 | 59 | rgbpa(:,1) = (400*(fl*rgbp(:,1)/100).^0.42)./(27.13+(fl*rgbp(:,1)/100).^0.42)+0.1; 60 | rgbpa(:,2) = (400*(fl*rgbp(:,2)/100).^0.42)./(27.13+(fl*rgbp(:,2)/100).^0.42)+0.1; 61 | rgbpa(:,3) = (400*(fl*rgbp(:,3)/100).^0.42)./(27.13+(fl*rgbp(:,3)/100).^0.42)+0.1; 62 | 63 | rgbpwa(:,1) = (400*(fl*rgbpw(:,1)/100)^0.42)/(27.13+(fl*rgbpw(:,1)/100)^0.42)+0.1; 64 | rgbpwa(:,2) = (400*(fl*rgbpw(:,2)/100)^0.42)/(27.13+(fl*rgbpw(:,2)/100)^0.42)+0.1; 65 | rgbpwa(:,3) = (400*(fl*rgbpw(:,3)/100)^0.42)/(27.13+(fl*rgbpw(:,3)/100)^0.42)+0.1; 66 | 67 | a = rgbpa(:,1) - 12*rgbpa(:,2)/11 + rgbpa(:,3)/11; 68 | b = (rgbpa(:,1) + rgbpa(:,2) - 2*rgbpa(:,3))/9; 69 | 70 | % step 7 71 | h = 180*car2pol(a, b)/pi; 72 | 73 | % step 8 74 | ehH = [ 20.14 90.00 164.25 237.53 380.14 75 | 0.8 0.7 1.0 1.2 0.8 76 | 0.0 100.0 200.0 300.0 400.0 ]; 77 | hh=h; 78 | hh = (1-(hh<20.14)).*hh + (hh<20.14).*(360+20.14); 79 | hh=(hh>=20.14)+(hh>=90)+(hh>=164.25)+(hh>=237.53)+(h>=380.14); 80 | 81 | e=ehH(2,i)+(ehH(2,i+1)-ehH(2,i))*(hh-ehH(1,i))/(ehH(1,i+1)-ehH(1,i)); 82 | hq=ehH(3,i)+100.0*( (hh-ehH(1,i))/ehH(2,i) )/ ( (hh-ehH(1,i))/ehH(2,i) + (ehH(1,i+1)-hh)/ehH(2,i+1) ); 83 | k=floor(hq/100); 84 | Hp=floor(100.0*(hq/100-k)+0.5); 85 | 86 | % step 9 87 | A = (2*rgbpa(1) + rgbpa(2) + rgbpa(3)/20 - 2.05)*nbb; 88 | Aw = (2*rgbpwa(1) + rgbpwa(2) + rgbpwa(3)/20 - 2.05)*nbb; 89 | 90 | % step 10 91 | z = 1 + sqrt(fll*n); 92 | j = 100*(A/Aw)^(c*z); 93 | 94 | % step 11 95 | q = (1.24/c)*((j/100)^0.67)*((Aw + 3)^0.9); 96 | 97 | % step 12 98 | s = (5000*sqrt(a^2+b^2)*e*10*nc*nbb/13)/(rgbpa(1) + rgbpa(2) + 21*rgbpa(3)/20); 99 | 100 | % step 13 101 | c = 2.44*s^0.69*(j/100.)^(0.67*n)*(1.64-0.29^n); 102 | 103 | % step 14 104 | m = c*fl^0.15; 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/printer_demo.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cband 3 | % *** 4 | % *** Stearns-Stearns spectral bandpass correction 5 | % *** operates on matrix P of dimensions n by m 6 | % *** n spectra each at m wavelengths 7 | % =================================================== 8 | function printer_demo 9 | wave = linspace(400,700,31); 10 | load halftone.mat 11 | % conc is 120x2 12 | % P is 120x31 13 | % W is 1x31 14 | 15 | n = 20; 16 | 17 | % get the colour ramp for magenta ink 18 | mag = [W; P([11 22 33 44 55 66 77 88 99 110],:)]; 19 | figure; plot(wave,mag) 20 | % get the colour ramp for yellow ink 21 | yel = [W; P(1:10,:)]; 22 | figure; plot(wave,yel) 23 | 24 | % get tone reproduction curves 25 | dig = linspace(0,1,11); 26 | [mag_trc] = gettrc(dig,mag,W,mag(11,:),n); 27 | [yel_trc] = gettrc(dig,yel,W,yel(11,:),n); 28 | 29 | for i=1:120 30 | 31 | conc = concs(i,:); 32 | meas = P(i,:); 33 | 34 | mag_dig = polyval(mag_trc, conc(1)); 35 | yel_dig = polyval(yel_trc, conc(2)); 36 | 37 | % get the areas using Dimechel 38 | Am = mag_dig*(1-yel_dig); 39 | Ay = yel_dig*(1-mag_dig); 40 | Aw = (1-mag_dig)*(1-yel_dig); 41 | Ao = mag_dig*yel_dig; 42 | 43 | % get the colour of the overlap region 44 | overlap = P(120,:); 45 | 46 | for w = 1:31 47 | pred(i,w)=(Am*(mag(11,w))^(1/n) + ... 48 | Ay*(yel(11,w))^(1/n) + ... 49 | Ao*(overlap(w))^(1/n) + Aw*(W(w))^(1/n))^n; 50 | end 51 | 52 | % figure 53 | % plot(wave,meas,'ro') 54 | % hold on 55 | % plot(wave,pred,'b-') 56 | end 57 | 58 | xyz = r2xyz([W; P],400,700,'d65_64'); 59 | rgbm = xyz2srgb(xyz/100); 60 | lab=xyz2lab(xyz,'d65_64'); 61 | 62 | xyz = r2xyz([W; pred],400,700,'d65_64'); 63 | rgbp = xyz2srgb(xyz/100); 64 | labp=xyz2lab(xyz,'d65_64'); 65 | 66 | de = cie00de(lab,labp); 67 | disp(mean(de)) 68 | 69 | 70 | figure 71 | subplot(2,2,1) 72 | plot(wave,P(32,:),'ro') 73 | hold on 74 | plot(wave,pred(32,:),'k-') 75 | xlabel('wavelength') 76 | ylabel('reflectance') 77 | axis([400 700 0 1]) 78 | subplot(2,2,2) 79 | plot(wave,P(50,:),'ro') 80 | hold on 81 | plot(wave,pred(50,:),'k-') 82 | xlabel('wavelength') 83 | ylabel('reflectance') 84 | axis([400 700 0 1]) 85 | subplot(2,2,3) 86 | plot(wave,P(65,:),'ro') 87 | hold on 88 | plot(wave,pred(65,:),'k-') 89 | xlabel('wavelength') 90 | ylabel('reflectance') 91 | axis([400 700 0 1]) 92 | subplot(2,2,4) 93 | plot(wave,P(112,:),'ro') 94 | hold on 95 | plot(wave,pred(112,:),'k-') 96 | xlabel('wavelength') 97 | ylabel('reflectance') 98 | axis([400 700 0 1]) 99 | 100 | end 101 | % ==================================================== 102 | % *** END FUNCTION cband 103 | % ==================================================== 104 | 105 | function [p] = gettrc(dig,R,W,Solid,n); 106 | 107 | % function [p] = gettrc(dig,R,W,Solid,n,graphs) 108 | % gettrc function to compute the trc for an ink 109 | % function [p] = gettrc(dig,R,W,Solid,n,graphs); 110 | % dig is an 1 by n matrix of target area coverages 111 | % R is an n by m matrix of measured reflectance values 112 | % W is a 1 by m matrix of reflectance for the white substrate 113 | % Solid is a 1 by m matrix of reflectance for the solid ink 114 | % n is a free parameter > 0 115 | % p is a matrix containing the coefficients of a polynomial to 116 | % relate target coverage to actual coverage 117 | 118 | 119 | num = length(dig); 120 | 121 | R = R.^(1/n); 122 | W = W.^(1/n); 123 | Solid = Solid.^(1/n); 124 | 125 | for i=1:num 126 | c(i) = sum((Solid - R(i,:)).*(Solid - W))/sum((Solid - W).*(Solid - W)); 127 | end 128 | 129 | c = 1-c; 130 | 131 | [p,s]=polyfit(dig,c,3); 132 | figure 133 | plot(dig,c,'k*') 134 | x = linspace(0,1,101); 135 | y = polyval(p,x); 136 | hold on 137 | plot(x,y,'k-') 138 | xlabel('target coverage') 139 | ylabel('actual coverage') 140 | 141 | end 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /stereo_vision/rectification/estimateFundamentalMatrixRANSAC.m: -------------------------------------------------------------------------------- 1 | % Created by Shen Quanmin on 2019/03/17. 2 | % Copyright ? 2019 Shen Quanmin. All rights reserved. 3 | function [F, inlierIndex, n] = estimateFundamentalMatrixRANSAC(matchPoints1,matchPoints2,varargin) 4 | %ESTIMATE FUNDAMENTAL MATRIX RANSAC: Estimate fundamental matrix through 5 | %RANSAC method. 6 | %Reference: 7 | % 1.Richard Hartley etc. Multiple View Geometry in computer. 8 | % 2.Matlab implementation document of estimateFundamentalMatrix. 9 | 10 | % Input: 11 | % matchPoints1 - input points in first image. 12 | % matchPoints2 - input points in second image. 13 | % option: 14 | % confidence - the confidence that we find a sample with all points are 15 | % inliers. 16 | % maxIter - input max iteration number. If not set, we will calculate one. 17 | % inlierPercentage - inlier match percentage. 18 | % distanceThreshold - distance threshold to judge outliers. 19 | % Output: 20 | % F - output fundamental matrix for the two image. 21 | % inlierIndex - inlier of matched points. 22 | 23 | % Created by Shen Quanmin on 2019/03/17. 24 | 25 | matchPointsNum = size(matchPoints1,1); 26 | n = 0; 27 | t = 0.01; 28 | p = 0.99; 29 | r = 0.5; 30 | Nmax = 500; 31 | 32 | opt_num = nargin - 2; 33 | if opt_num > 0 34 | for i = 1:opt_num-1 35 | name = varargin{i}; 36 | value = varargin{i+1}; 37 | if strcmp(name, 'confidence') 38 | p = value; 39 | elseif strcmp(name, 'maxIter') 40 | Nmax = value; 41 | elseif strcmp(name, 'inlierPercentage') 42 | r = value; 43 | elseif strcmp(name, 'distanceThreshold') 44 | t = value; 45 | else 46 | disp(['Unknow parameter name: ', name]); 47 | end 48 | end 49 | end 50 | 51 | N = min(Nmax,log(1-p)/log(1-r^8)); 52 | F = zeros(3,3); 53 | inlierIndex = zeros(matchPointsNum,1); 54 | 55 | inlierNum = 0; 56 | 57 | %1.Normalize the coordinates. 58 | x1 = matchPoints1; 59 | x2 = matchPoints2; 60 | T1 = NormMatrix(x1); 61 | T2 = NormMatrix(x2); 62 | normX1 = (T1*[x1';ones(1,size(x1,1))])'; 63 | normX2 = (T2*[x2';ones(1,size(x2,1))])'; 64 | 65 | while n < N 66 | n = n+1; 67 | index = randperm(matchPointsNum,8); 68 | Ftemp = estimateFundamentalMatrixNorm8Points(normX1(index,1:2),normX2(index,1:2)); 69 | %dist = diag(normX2*Ftemp*normX1').^2; 70 | dist = sampsonDistance(normX1, Ftemp, normX2); 71 | inlierIndexTemp = (dist < t); 72 | inlierNumTemp = sum(inlierIndexTemp); 73 | if inlierNumTemp > inlierNum 74 | inlierNum = inlierNumTemp; 75 | inlierIndex = inlierIndexTemp; 76 | r = inlierNumTemp/matchPointsNum; 77 | NTemp = log(1-p)/log(1-r^8); 78 | N = min(N, NTemp); 79 | end 80 | end 81 | 82 | %3.Calculate the Fundamental Matrix for original coordinates. 83 | F = estimateFundamentalMatrixNorm8Points(normX1(inlierIndex,1:2),normX2(inlierIndex,1:2)); 84 | F = T2'*F*T1; 85 | F = F/norm(F); % For the norm of T1 and T2 are not eaqual to 1. 86 | end 87 | 88 | function [ T ] = NormMatrix(points) 89 | center = mean(points, 1); 90 | centeredPoints = [points(:,1)-center(1),points(:,2)-center(2)]; 91 | rVec = centeredPoints.^2; 92 | rVec = mean(sqrt(rVec(:,1)+rVec(:,2))); 93 | s = sqrt(2)/rVec; 94 | T = [s, 0, -s*center(1); 95 | 0, s, -s*center(2); 96 | 0, 0, 1]; 97 | end 98 | 99 | function [ dist ] = sampsonDistance(x1, F, x2) 100 | dist = diag(x2*F*x1').^2; 101 | Fx1 = F*x1'; 102 | Ftx2 = F'*x2'; 103 | nominator = Fx1(1,:).^2 + Fx1(2,:).^2 + Ftx2(1,:).^2 + Ftx2(2,:).^2; 104 | dist = dist(:) ./ nominator(:); 105 | end -------------------------------------------------------------------------------- /tools/3rdparty/color_science/camera_demo.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION camera_demo 3 | % *** 4 | % *** function camera_demo(linflag, spflag) 5 | % *** demonstrates camera characterization 6 | % *** performs linearization and spatial correction if 7 | % *** linflag and spflag are set respectively 8 | % *** requires cc.tif and grey.mat are in the path 9 | % *** see also camera_demo1 10 | % =================================================== 11 | function camera_demo(linflag, spflag) 12 | data = double(imread('cc.tif','tif'))/255; 13 | imshow(uint8(255*data)) 14 | 15 | if (linflag) % perform linearization 16 | load grey.mat 17 | % greyy 13x1 18 | % greyrgb 13x3 19 | 20 | figure 21 | greyrgb=greyrgb/255; 22 | plot(greyrgb(:,1),greyy,'ro') 23 | hold on 24 | plot(greyrgb(:,2),greyy,'go') 25 | hold on 26 | plot(greyrgb(:,3),greyy,'bo') 27 | 28 | % compute nonlinearity of each channel 29 | x1=linspace(0,1,101); 30 | % red channel 31 | x = 1; 32 | options = optimset; 33 | x = fminsearch(@gtest,x,options,greyrgb(:,1), greyy(:,1)); 34 | gamma(1) = x; 35 | y1 = x1.^gamma(1); 36 | hold on 37 | plot(x1,y1,'r-'); 38 | % green channel 39 | x = 1; 40 | options = optimset; 41 | x = fminsearch(@gtest,x,options,greyrgb(:,2), greyy(:,1)); 42 | gamma(2) = x; 43 | y1 = x1.^gamma(2); 44 | hold on 45 | plot(x1,y1,'g-'); 46 | % blue channel 47 | x = 1; 48 | options = optimset; 49 | x = fminsearch(@gtest,x,options,greyrgb(:,3), greyy(:,1)); 50 | gamma(3) = x; 51 | y1 = x1.^gamma(3); 52 | hold on 53 | plot(x1,y1,'b-'); 54 | 55 | greyrgb(:,1) = greyrgb(:,1).^gamma(1); 56 | greyrgb(:,2) = greyrgb(:,2).^gamma(2); 57 | greyrgb(:,3) = greyrgb(:,3).^gamma(3); 58 | 59 | figure 60 | plot(greyrgb(:,1),greyy,'ro') 61 | hold on 62 | plot(greyrgb(:,2),greyy,'go') 63 | hold on 64 | plot(greyrgb(:,3),greyy,'bo') 65 | 66 | data(:,:,1)=data(:,:,1).^gamma(1); 67 | data(:,:,2)=data(:,:,2).^gamma(2); 68 | data(:,:,3)=data(:,:,3).^gamma(3); 69 | 70 | disp(gamma) 71 | 72 | imwrite(uint8(255*data),'cc_lin.tif','tif'); 73 | figure 74 | imshow(uint8(255*data)) 75 | else 76 | gamma = [1 1 1]; % needed in case spatial correction is called 77 | end 78 | 79 | if (spflag) 80 | % spatial correction 81 | grey = (double(imread('ccgrey.tif','tif')))/255; 82 | grey(:,:,1)=grey(:,:,1).^gamma(1); 83 | grey(:,:,2)=grey(:,:,2).^gamma(2); 84 | grey(:,:,3)=grey(:,:,3).^gamma(3); 85 | black = (double(imread('ccblack.tif','tif')))/255; 86 | black(:,:,1)=black(:,:,1).^gamma(1); 87 | black(:,:,2)=black(:,:,2).^gamma(2); 88 | black(:,:,3)=black(:,:,3).^gamma(3); 89 | 90 | meangrey = mean(mean(grey)); 91 | meanblack = mean(mean(black)); 92 | 93 | data(:,:,1) = (meangrey(1)-meanblack(1))*(data(:,:,1)-black(:,:,1))./(grey(:,:,1)-black(:,:,1)); 94 | data(:,:,2) = (meangrey(2)-meanblack(2))*(data(:,:,2)-black(:,:,2))./(grey(:,:,3)-black(:,:,2)); 95 | data(:,:,3) = (meangrey(3)-meanblack(3))*(data(:,:,3)-black(:,:,3))./(grey(:,:,3)-black(:,:,3)); 96 | 97 | imwrite(uint8(255*data),'cc_lin_sp.tif','tif'); 98 | figure 99 | imshow(uint8(255*data)) 100 | end 101 | 102 | index = 0; 103 | for col = 80:35:745 104 | for row=65:35:450 105 | index = index+1; 106 | rgb(index,:)=mean(mean(data(row-5:row+5,col-5:col+5,:))); 107 | end 108 | end 109 | save 'rgb_cc.mat' rgb 110 | 111 | end 112 | 113 | function [err] = gtest(x,rgb,y) 114 | % force to be row matrices 115 | rgb = rgb(:)'; 116 | y = y(:)'; 117 | gamma=x; 118 | if (length(rgb) ~= length(y)) 119 | disp('vectors must be the same length'); 120 | err = 0; 121 | return 122 | end 123 | 124 | % compute predictions with gamma 125 | for i=1:length(rgb) 126 | if (rgb(i)) <= 0 127 | pred(i)=0; 128 | else 129 | pred(i)=rgb(i)^gamma; 130 | end 131 | end 132 | pred = pred(:)'; 133 | % compute rms error 134 | err = sqrt((sum((y-pred).*(y-pred)))/length(y)); 135 | end 136 | -------------------------------------------------------------------------------- /maths/optimization/lmlsq.m: -------------------------------------------------------------------------------- 1 | function [x_res, x_iter, f_iter, cnt] = lmlsq(fun, x0, varargin) 2 | % LMLSQ The Levenberg-Marquardt method for optimization 3 | % fun - The function to be optimized. In fact, the cost function is 4 | % F(x)=0.5*fun(x)'*fun(x). 5 | % x0 - The initial x for iteration. 6 | % There are some option parameters: 7 | % jacobian - The analytical jacobian matrix. If no analytical jacobian 8 | % matrix inputed, we use numeric finite jacobian matrix. Default: no 9 | % analytical jacobian matrix. 10 | % maxIter - The maximum number of iterations for calculate the result. 11 | % Default: 100. 12 | % tao - The factor used to initialize u. Default:0.001. 13 | % ks1 - Used to judge if the gradient small enough to stop iteration. 14 | % ks2 - Used to judge if x change is small enought to stop iteration. 15 | 16 | % output: 17 | % x_res - The result for optimization. 18 | % x_iter - Record x for every iteration. 19 | % f_iter - Record fun value for every iteration. 20 | % cnt - The number of changes x. 21 | % k - The number of total iterations. 22 | 23 | %Reference: K. Madsen, H.B. Nielson etc."Method for nonlinear least squares problems" 24 | % Created by Shen Quanmin on 2019/03/10. 25 | 26 | maxiter = 100; 27 | tao = 0.001; 28 | ks1 = 1e-7; 29 | ks2 = 1e-7; 30 | jac = 0; 31 | analyze_jac = false; 32 | 33 | opt_num = nargin - 2; 34 | if opt_num > 0 35 | for i = 1:opt_num-1 36 | name = varargin{i}; 37 | value = varargin{i+1}; 38 | if strcmp(name, 'jacobian') 39 | jac = value; 40 | analyze_jac = true; 41 | elseif strcmp(name, 'maxIter') 42 | maxiter = value; 43 | elseif strcmp(name, 'tao') 44 | tao = value; 45 | elseif strcmp(name, 'ks1') 46 | ks1 =value; 47 | elseif strcmp(name, 'ks2') 48 | ks2 = value; 49 | else 50 | disp(['Unknow parameter name: ', name]); 51 | end 52 | end 53 | end 54 | 55 | ks1_sq = ks1*ks1; 56 | ks2_sq = ks2*ks2; 57 | k = 1; 58 | v = 2; 59 | x = x0; 60 | delta = ones(size(x))*1e-7; 61 | f = feval(fun, x); 62 | if analyze_jac 63 | j = feval(jac, x); 64 | else 65 | j = jacobian_eval(fun, f, x, delta); 66 | end 67 | A = j'*j; 68 | g = j'*f; 69 | found = (max(g)<=ks1_sq); 70 | u = tao * max(diag(A)); 71 | I = eye(size(j,2),size(j,2)); 72 | 73 | temp = 1/3; 74 | 75 | x_res = x0; 76 | x_iter = zeros(size(x0,1),maxiter); 77 | x_iter(:,1) = x0; 78 | f_iter = zeros(size(f,1),maxiter); 79 | f_iter(:,1) = f; 80 | cnt = 1; 81 | 82 | while (~found) && k < maxiter 83 | k = k+1; 84 | h = -(A+u*I)\g; 85 | if h'*h <= ks2_sq*(x'*x+ks2_sq) 86 | found = true; 87 | else 88 | xnew = x + h; 89 | fnew = feval(fun, xnew); 90 | pro = (f'*f-fnew'*fnew)/(h'*(u*h-g)); 91 | if pro > 0 92 | x = xnew; 93 | if analyze_jac 94 | j = feval(jac, x); 95 | else 96 | j = jacobian_eval(fun, fnew, x, delta); 97 | end 98 | A = j'*j; 99 | g = j'*fnew; 100 | found = (max(g)<=ks1_sq); 101 | u = u * max(temp, 1-(2*pro-1)^3); 102 | v = 2; 103 | 104 | cnt = cnt+1; 105 | x_iter(:,cnt) = x; 106 | x_res = x; 107 | f_iter(:,cnt) = fnew; 108 | else 109 | u = u*v; 110 | v = 2*v; 111 | end 112 | end 113 | end 114 | end 115 | 116 | function jac_value = jacobian_eval(fun, fun_x_val, x, delta) 117 | % numerical approximation to Jacobi matrix 118 | 119 | delta(delta==0) = eps; 120 | jac_value = zeros(size(x,1),size(fun_x_val,1)); 121 | for i = 1:size(x,1) 122 | xd = x; 123 | xd(i) = xd(i) + delta(i); 124 | fun_x_new = feval(fun, xd); 125 | dy = fun_x_new - fun_x_val; 126 | jac_value(:,i) = dy/delta(i); 127 | end 128 | end -------------------------------------------------------------------------------- /demosaic/demosaic_bilinear.m: -------------------------------------------------------------------------------- 1 | function [ demosaiced_img ] = demosaic_bilinear( cfa_image, cfa_pattern ) 2 | %DEMOSAIC_BILINEAR Summary of this function goes here 3 | % Detailed explanation goes here 4 | demosaiced_img = zeros(size(cfa_image,1), size(cfa_image, 2), 3); 5 | demosaiced_img(:,:,2) = calc_g_channel(cfa_image,cfa_pattern); 6 | [demosaiced_img(:,:,1),demosaiced_img(:,:,3)] = ... 7 | calc_rb_channel(cfa_image, cfa_pattern); 8 | end 9 | 10 | function [ g_channel ] = calc_g_channel(cfa_image, cfa_pattern) 11 | kernel = [0 1/4 0; 1/4 0 1/4; 0 1/4 0]; 12 | padded_cfa_image = zeros(size(cfa_image,1)+2,size(cfa_image,2)+2); 13 | padded_cfa_image(2:end-1,2:end-1) = cfa_image; 14 | padded_cfa_image(2:end-1,1) = padded_cfa_image(2:end-1,3); 15 | padded_cfa_image(2:end-1,end) = padded_cfa_image(2:end-1,end-2); 16 | padded_cfa_image(1,:) = padded_cfa_image(3,:); 17 | padded_cfa_image(end,:) = padded_cfa_image(end-2,:); 18 | filtered_cfa = filter2(kernel, padded_cfa_image, 'valid'); 19 | 20 | g_channel = cfa_image; 21 | if cfa_pattern(1) == 2 && cfa_pattern(4) == 2 22 | g_channel(1:2:end,2:2:end) = filtered_cfa(1:2:end,2:2:end); 23 | g_channel(2:2:end,1:2:end) = filtered_cfa(2:2:end,1:2:end); 24 | elseif cfa_pattern(2) == 2 && cfa_pattern(3) == 2 25 | g_channel(1:2:end,1:2:end) = filtered_cfa(1:2:end,1:2:end); 26 | g_channel(2:2:end,2:2:end) = filtered_cfa(2:2:end,2:2:end); 27 | end 28 | end 29 | 30 | function [ r_channel, b_channel ] = calc_rb_channel(cfa_image, cfa_pattern) 31 | kernel_v = [0 1/2 0; 0 0 0; 0 1/2 0]; 32 | kernel_h = [0 0 0; 1/2 0 1/2; 0 0 0]; 33 | kernel_d = [1/4 0 1/4; 0 0 0; 1/4 0 1/4]; 34 | 35 | padded_cfa_image = zeros(size(cfa_image,1)+2,size(cfa_image,2)+2); 36 | padded_cfa_image(2:end-1,2:end-1) = cfa_image; 37 | padded_cfa_image(2:end-1,1) = padded_cfa_image(2:end-1,3); 38 | padded_cfa_image(2:end-1,end) = padded_cfa_image(2:end-1,end-2); 39 | padded_cfa_image(1,:) = padded_cfa_image(3,:); 40 | padded_cfa_image(end,:) = padded_cfa_image(end-2,:); 41 | 42 | filtered_v = filter2(kernel_v, padded_cfa_image, 'valid'); 43 | filtered_h = filter2(kernel_h, padded_cfa_image, 'valid'); 44 | filtered_d = filter2(kernel_d, padded_cfa_image, 'valid'); 45 | 46 | r_channel = cfa_image; 47 | b_channel = r_channel; 48 | if cfa_pattern(1) == 2 && cfa_pattern(4) == 2 49 | if cfa_pattern(2) == 3 && cfa_pattern(3) == 1 50 | b_channel(1:2:end,1:2:end) = filtered_h(1:2:end,1:2:end); 51 | b_channel(2:2:end,2:2:end) = filtered_v(2:2:end,2:2:end); 52 | b_channel(2:2:end,1:2:end) = filtered_d(2:2:end,1:2:end); 53 | r_channel(1:2:end,1:2:end) = filtered_v(1:2:end,1:2:end); 54 | r_channel(1:2:end,2:2:end) = filtered_d(1:2:end,2:2:end); 55 | r_channel(2:2:end,2:2:end) = filtered_h(2:2:end,2:2:end); 56 | else 57 | r_channel(1:2:end,1:2:end) = filtered_h(1:2:end,1:2:end); 58 | r_channel(2:2:end,2:2:end) = filtered_v(2:2:end,2:2:end); 59 | r_channel(2:2:end,1:2:end) = filtered_d(2:2:end,1:2:end); 60 | b_channel(1:2:end,1:2:end) = filtered_v(1:2:end,1:2:end); 61 | b_channel(1:2:end,2:2:end) = filtered_d(1:2:end,2:2:end); 62 | b_channel(2:2:end,2:2:end) = filtered_h(2:2:end,2:2:end); 63 | end 64 | elseif cfa_pattern(2) == 2 && cfa_pattern(3) == 2 65 | if cfa_pattern(1) == 1 && cfa_pattern(4) == 3 66 | r_channel(1:2:end,2:2:end) = filtered_h(1:2:end,2:2:end); 67 | r_channel(2:2:end,1:2:end) = filtered_v(2:2:end,1:2:end); 68 | r_channel(2:2:end,2:2:end) = filtered_d(2:2:end,2:2:end); 69 | b_channel(1:2:end,1:2:end) = filtered_d(1:2:end,1:2:end); 70 | b_channel(1:2:end,2:2:end) = filtered_v(1:2:end,2:2:end); 71 | b_channel(2:2:end,1:2:end) = filtered_h(2:2:end,1:2:end); 72 | else 73 | b_channel(1:2:end,2:2:end) = filtered_h(1:2:end,2:2:end); 74 | b_channel(2:2:end,1:2:end) = filtered_v(2:2:end,1:2:end); 75 | b_channel(2:2:end,2:2:end) = filtered_d(2:2:end,2:2:end); 76 | r_channel(1:2:end,1:2:end) = filtered_d(1:2:end,1:2:end); 77 | r_channel(1:2:end,2:2:end) = filtered_v(1:2:end,2:2:end); 78 | r_channel(2:2:end,1:2:end) = filtered_h(2:2:end,1:2:end); 79 | end 80 | end 81 | end -------------------------------------------------------------------------------- /tools/3rdparty/color_science/cieplot.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION cieplot 3 | % *** 4 | % *** function = cieplot() 5 | % *** colour representation of chromaticity diagram 6 | % =================================================== 7 | function [] = cieplot() 8 | % load spectral locus xy values at 1-nm intervals 9 | load locus.mat 10 | plot(locus(:,1),locus(:,2),'k','LineWidth',2) 11 | grid on 12 | hold on 13 | axis([0.0 0.85 0.0 0.85]) 14 | xlabel('x') 15 | ylabel('y') 16 | % plot the non-spectral locus 17 | plot([locus(1,1) locus(end,1)], [locus(1,2) locus(end,2)],'k','LineWidth',2) 18 | % chromaticity coordinates of spectrum locus 19 | x = [ 0.175596 0.172787 0.170806 0.170085 0.160343 0.146958 0.139149 ... 20 | 0.133536 0.126688 0.115830 0.109616 0.099146 0.091310 0.078130 ... 21 | 0.068717 0.054675 0.040763 0.027497 0.016270 0.008169 0.004876 ... 22 | 0.003983 0.003859 0.004646 0.007988 0.013870 0.022244 0.027273 ... 23 | 0.032820 0.038851 0.045327 0.052175 0.059323 0.066713 0.074299 ... 24 | 0.089937 0.114155 0.138695 0.154714 0.192865 0.229607 0.265760 ... 25 | 0.301588 0.337346 0.373083 0.408717 0.444043 0.478755 0.512467 ... 26 | 0.544767 0.575132 0.602914 0.627018 0.648215 0.665746 0.680061 ... 27 | 0.691487 0.700589 0.707901 0.714015 0.719017 0.723016 0.734674 ]'; 28 | y = [ 0.005295 0.004800 0.005472 0.005976 0.014496 0.026643 0.035211 ... 29 | 0.042704 0.053441 0.073601 0.086866 0.112037 0.132737 0.170464 ... 30 | 0.200773 0.254155 0.317049 0.387997 0.463035 0.538504 0.587196 ... 31 | 0.610526 0.654897 0.675970 0.715407 0.750246 0.779682 0.792153 ... 32 | 0.802971 0.812059 0.819430 0.825200 0.829460 0.832306 0.833833 ... 33 | 0.833316 0.826231 0.814796 0.805884 0.781648 0.754347 0.724342 ... 34 | 0.692326 0.658867 0.624470 0.589626 0.554734 0.520222 0.486611 ... 35 | 0.454454 0.424252 0.396516 0.372510 0.351413 0.334028 0.319765 ... 36 | 0.308359 0.299317 0.292044 0.285945 0.280951 0.276964 0.265326 ]'; 37 | N = length(x); 38 | i = 1; 39 | e = 1/3; 40 | steps = 25; 41 | xy4rgb = zeros(N*steps*4,5,'double'); 42 | for w = 1:N % wavelength 43 | w2 = mod(w,N)+1; 44 | a1 = atan2(y(w) -e,x(w) -e); % start angle 45 | a2 = atan2(y(w2) -e,x(w2) -e); % end angle 46 | r1 = ((x(w) - e)^2 + (y(w) - e)^2)^0.5; % start radius 47 | r2 = ((x(w2) - e)^2 + (y(w2) - e)^2)^0.5; % end radius 48 | for c = 1:steps % colourfulness 49 | % patch polygon 50 | xyz(1,1) = e+r1*cos(a1)*c/steps; 51 | xyz(1,2) = e+r1*sin(a1)*c/steps; 52 | xyz(1,3) = 1 - xyz(1,1) - xyz(1,2); 53 | xyz(2,1) = e+r1*cos(a1)*(c-1)/steps; 54 | xyz(2,2) = e+r1*sin(a1)*(c-1)/steps; 55 | xyz(2,3) = 1 - xyz(2,1) - xyz(2,2); 56 | xyz(3,1) = e+r2*cos(a2)*(c-1)/steps; 57 | xyz(3,2) = e+r2*sin(a2)*(c-1)/steps; 58 | xyz(3,3) = 1 - xyz(3,1) - xyz(3,2); 59 | xyz(4,1) = e+r2*cos(a2)*c/steps; 60 | xyz(4,2) = e+r2*sin(a2)*c/steps; 61 | xyz(4,3) = 1 - xyz(4,1) - xyz(4,2); 62 | % compute sRGB for vertices 63 | rgb = xyz2srgb(xyz'); 64 | % store the results 65 | xy4rgb(i:i+3,1:2) = xyz(:,1:2); 66 | xy4rgb(i:i+3,3:5) = rgb'; 67 | i = i + 4; 68 | end 69 | end 70 | [rows cols] = size(xy4rgb); 71 | f = [1 2 3 4]; 72 | v = zeros(4,3,'double'); 73 | for i = 1:4:rows 74 | v(:,1:2) = xy4rgb(i:i+3,1:2); 75 | patch('Vertices',v, 'Faces',f, 'EdgeColor','none', ... 76 | 'FaceVertexCData',xy4rgb(i:i+3,3:5),'FaceColor','interp') 77 | end 78 | end 79 | function [rgb] = xyz2srgb(xyz) 80 | M = [ 3.2406 -1.5372 -0.4986; -0.9689 1.8758 0.0415; 0.0557 -0.2040 1.0570 ]; 81 | [rows cols ] = size(xyz); 82 | rgb = M*xyz; 83 | for c = 1:cols 84 | for ch = 1:3 85 | if rgb(ch,c) <= 0.0031308 86 | rgb(ch,c) = 12.92*rgb(ch,c); 87 | else 88 | rgb(ch,c) = 1.055*(rgb(ch,c)^(1.0/2.4)) - 0.055; 89 | end 90 | % clip RGB 91 | if rgb(ch,c) < 0 92 | rgb(ch,c) = 0; 93 | elseif rgb(ch,c) > 1 94 | rgb(ch,c) = 1; 95 | end 96 | end 97 | end 98 | end 99 | % ==================================================== 100 | % *** END FUNCTION cieplot 101 | % ==================================================== -------------------------------------------------------------------------------- /tools/3rdparty/color_science/crtdemo.m: -------------------------------------------------------------------------------- 1 | % =================================================== 2 | % *** FUNCTION crtdemo 3 | % *** 4 | % *** function = crtdemo 5 | % *** demonstrates use of GOG model to 6 | % *** characterize a CRT monitor 7 | function crtdemo 8 | % RGB Yxy measured data 9 | rawdata = [255 0 0 17.30 0.610 0.349; ... 10 | 0 225 0 61.00 0.296 0.598; ... 11 | 0 0 255 8.99 0.145 0.070; ... 12 | 0 0 0 0.34 0.360 0.331; 13 | 25 25 25 3.36 0.298 0.328 ; 14 | 50 50 50 8.91 0.290 0.325; 15 | 80 80 80 16.60 0.285 0.320; 16 | 120 120 120 29.30 0.284 0.317; 17 | 160 160 160 45.80 0.283 0.316; 18 | 200 200 200 63.80 0.282 0.313; 19 | 220 220 220 73.70 0.282 0.312; 20 | 255 255 255 85.40 0.284 0.315; 21 | 110 40 170 14.70 0.231 0.159; 22 | 250 187 160 63.40 0.327 0.344; 23 | 10 180 230 46.20 0.202 0.261; 24 | 5 20 240 10.20 0.150 0.084; 25 | 240 20 5 17.90 0.585 0.362; 26 | 5 240 20 57.40 0.292 0.579; 27 | 34 40 32 6.40 0.295 0.363; 28 | 220 210 195 69.00 0.294 0.325]; 29 | 30 | for i=1:20 31 | Y = rawdata(i,4); 32 | x = rawdata(i,5); 33 | y = rawdata(i,6); 34 | z = 1 - x - y; 35 | X = x*Y/y; 36 | Z = z*Y/y; 37 | XYZ(i,:) = [X Y Z]; 38 | end 39 | 40 | % use the white of the display for CIELAB 41 | white = XYZ(12,:); 42 | LAB = xyz2lab(XYZ,'user',white); 43 | 44 | M = [XYZ(1,1) XYZ(2,1) XYZ(3,1); XYZ(1,2) XYZ(2,2) XYZ(3,2); XYZ(1,3) XYZ(2,3) XYZ(3,3)]; 45 | disp(M) 46 | 47 | % get the neutral samples 48 | nXYZ = XYZ(4:12,:); 49 | % get their linear RGB values 50 | nRGB = (inv(M)*nXYZ')'; 51 | % and the corresponding non-linear RGBs 52 | dacs=rawdata(4:12,1:3)/255; 53 | 54 | % compute the GOG values for each channel 55 | x1=linspace(0,1,101); 56 | % red channel 57 | x = [1, 1]; 58 | options = optimset; 59 | x = fminsearch(@gogtest,x,options,dacs(:,1), nRGB(:,1)); 60 | gogvals(1,:) = x; 61 | figure 62 | plot(dacs(:,1),nRGB(:,1),'r*') 63 | y1 = compgog(gogvals(1,:),x1); 64 | hold on 65 | plot(x1,y1,'r-') 66 | % green channel 67 | x = [1, 1]; 68 | options = optimset; 69 | x = fminsearch(@gogtest,x,options,dacs(:,2), nRGB(:,2)); 70 | gogvals(2,:) = x; 71 | hold 72 | plot(dacs(:,2),nRGB(:,2),'g*') 73 | y2 = compgog(gogvals(2,:),x1); 74 | hold on 75 | plot(x1,y2,'g-') 76 | % blue channel 77 | x = [1, 1]; 78 | options = optimset; 79 | x = fminsearch(@gogtest,x,options,dacs(:,3), nRGB(:,3)); 80 | gogvals(3,:) = x; 81 | hold on 82 | plot(dacs(:,3),nRGB(:,3),'b*') 83 | y3 = compgog(gogvals(3,:),x1); 84 | hold on 85 | plot(x1,y3,'b-') 86 | disp(gogvals) 87 | 88 | 89 | % now takes the dacs of the test samples 90 | % and linearize them using the gogvals 91 | red = rawdata(13:20,1)/255; 92 | RGB(:,1) = compgog(gogvals(1,:), red); 93 | green = rawdata(13:20,2)/255; 94 | RGB(:,2) = compgog(gogvals(2,:), green); 95 | blue = rawdata(13:20,3)/255; 96 | RGB(:,3) = compgog(gogvals(3,:), blue); 97 | 98 | linXYZ = (M*RGB')'; 99 | linLAB = xyz2lab(linXYZ,'user',white); 100 | DE = cmcde(LAB(13:20,:),linLAB,2,1); 101 | 102 | disp([mean(DE) max(DE)]) 103 | end 104 | 105 | % function [err] = gogtest(gogs,dacs,rgbs) 106 | % computes the error between measured and predicted 107 | % linearized dac values for a given set of GOG values 108 | % gogs is a 2 by 1 matrix that contains the gamma and gain 109 | % dacs is an n by 1 matrix that contains the actual RGB values 110 | % obtained by dividing the RGB values by 255 111 | % rgbs is an n by 1 matrix that is obtained from a linear 112 | % transform of measured XYZ values 113 | function [err] = gogtest(gogs,dacs,rgbs) 114 | 115 | gamma = gogs(1); 116 | gain = gogs(2); 117 | 118 | % force to be row matrices 119 | dacs = dacs(:)'; 120 | rgbs = rgbs(:)'; 121 | 122 | if (length(dacs) ~= length(rgbs)) 123 | disp('dacs and rgbs vectors must be the same length'); 124 | err = 0; 125 | return 126 | end 127 | 128 | % compute gog model predictions 129 | for i=1:length(dacs) 130 | if (gain*dacs(i) + (1-gain)) <= 0 131 | pred(i)=0; 132 | else 133 | pred(i)=(gain*dacs(i) + (1-gain))^gamma; 134 | end 135 | end 136 | 137 | % force to be a row matrix 138 | pred = pred(:)'; 139 | % compute rms error 140 | err = sqrt((sum((rgbs-pred).*(rgbs-pred)))/length(dacs)); 141 | end 142 | 143 | % function [rgb] = compgog(gogs,dacs) 144 | % computes the linearized RGB values 145 | % from the normalized RGB values 146 | % for a given set of gog values 147 | % gog is a 2 by 1 matrix that contains the gamma and gain 148 | % dacs is an n by 1 matrix that contains the RGB values 149 | % rgb is an n by 1 matrix of linearized RGB values 150 | function [rgb] = compgog(gogs,dacs) 151 | 152 | gamma = gogs(1); 153 | gain = gogs(2); 154 | for i=1:length(dacs) 155 | if (gain*dacs(i) + (1-gain)) <= 0 156 | rgb(i)=0; 157 | else 158 | rgb(i)=(gain*dacs(i) + (1-gain))^gamma; 159 | end 160 | end 161 | % force output to be a column vector 162 | rgb=rgb(:); 163 | end 164 | 165 | -------------------------------------------------------------------------------- /tools/3rdparty/color_science/plotDKLspace.m: -------------------------------------------------------------------------------- 1 | function plotDKLspace 2 | % Plots the DKL coordinates (after Derrington, Krauskopf and Lennie, 3 | % 1984) of the phosphors and secondary colours. Generate a 3-D solid 4 | % representing the colour gamut of a 21-inch Sony F520 Trinitron monitor. 5 | % 6 | % 09-Dec -2011 kr Wrote it. 7 | 8 | % Set DKL coordinates of the phosphors. 9 | dkl_deg_red = [0.5484 58.8425 -56.9676]; 10 | dkl_deg_green = [1.0982 99.7294 19.8041]; 11 | dkl_deg_blue = [1.5547 266.3804 -39.5537]; 12 | dkl_deg_white = [1.7321 0 90.0000]; 13 | dkl_deg_black = [1.7321 0 -90.0000]; 14 | dkl_deg_cyan = [ 0.5484 238.8425 56.9676]; 15 | dkl_deg_magenta = [1.0982 279.7294 -19.8041]; 16 | dkl_deg_yellow = [1.5547 86.3804 39.5537]; 17 | 18 | 19 | DEGS_TO_RADS = 2*pi/360; 20 | max_elevation = DEGS_TO_RADS*90; 21 | el_white = (max_elevation); 22 | 23 | % Plot phosphors in cartesian space. 24 | figure(1) 25 | set(gcf,'color','w'); 26 | [theta, rho] = meshgrid (0:(2*pi)/36:2*pi+.2, 0:0.1:1); 27 | x = cos(theta).*rho; 28 | y = sin(theta).*rho; 29 | surf(x,y,zeros(size(x)),'FaceColor','none'); 30 | hold on 31 | 32 | % Plot axes 33 | line_width = 4; 34 | red_line = [255/255 102/255 153/255]; 35 | green_line = [0 204/255 153/255]; 36 | blue_line = [51/255 153/255 255/255]; 37 | yellow_line = [204/255 255/255 0]; 38 | 39 | plot3([0 1], [0 0],[0 0],'Color',red_line, 'LineWidth',line_width) 40 | plot3([-1 0], [0 0],[0 0],'Color',green_line,'LineWidth',line_width) 41 | 42 | plot3([0 0], [0 1], [0 0],'Color',yellow_line, 'LineWidth',line_width) 43 | plot3([0 0], [-1 0],[0 0],'Color',blue_line,'LineWidth',line_width) 44 | 45 | plot3([0 0], [0 0],[0 1], 'Color',[0.8 0.8 0.8],'LineWidth',line_width) 46 | plot3([0 0], [0 0],[-1 0],'Color',[0.4 0.4 0.4],'LineWidth',line_width) 47 | 48 | % Define DKL coordinates in radians. 49 | symbol_size = 6; 50 | red_azimuth = dkl_deg_red(2) * DEGS_TO_RADS; 51 | red_elev = dkl_deg_red(3)* DEGS_TO_RADS; 52 | green_azimuth = dkl_deg_green(2) * DEGS_TO_RADS; 53 | green_elev = dkl_deg_green(3)* DEGS_TO_RADS; 54 | blue_azimuth = dkl_deg_blue(2) * DEGS_TO_RADS; 55 | blue_elev = dkl_deg_blue(3)* DEGS_TO_RADS; 56 | 57 | % Define DKL coordinates of secondary colours in radians. 58 | cyan_azimuth = dkl_deg_cyan(2) * DEGS_TO_RADS; 59 | cyan_elev = dkl_deg_cyan(3)* DEGS_TO_RADS; 60 | magenta_azimuth = dkl_deg_magenta(2) * DEGS_TO_RADS; 61 | magenta_elev = dkl_deg_magenta(3)* DEGS_TO_RADS; 62 | yellow_azimuth = dkl_deg_yellow(2) * DEGS_TO_RADS; 63 | yellow_elev = dkl_deg_yellow(3)* DEGS_TO_RADS; 64 | white_azimuth = dkl_deg_white(2) * DEGS_TO_RADS; 65 | white_elev = dkl_deg_white(3)* DEGS_TO_RADS; 66 | black_azimuth = dkl_deg_black(2) * DEGS_TO_RADS; 67 | black_elev = dkl_deg_black(3)* DEGS_TO_RADS; 68 | 69 | [x_red y_red z_red] = sph2cart(red_azimuth,red_elev, dkl_deg_red(1)); 70 | z_red= (red_elev)/max_elevation; 71 | [x_green y_green z_green] = sph2cart(green_azimuth,green_elev, dkl_deg_green(1)); 72 | z_green = z_green/max_elevation; 73 | [x_blue y_blue z_blue] = sph2cart(blue_azimuth,blue_elev, dkl_deg_blue(1)); 74 | z_blue= blue_elev/max_elevation; 75 | 76 | [x_cyan y_cyan z_cyan] = sph2cart(cyan_azimuth,cyan_elev, dkl_deg_cyan(1)); 77 | z_cyan= cyan_elev/max_elevation; 78 | 79 | [x_magenta y_magenta z_magenta] = sph2cart(magenta_azimuth,magenta_elev, dkl_deg_magenta(1)); 80 | z_magenta= magenta_elev/max_elevation; 81 | 82 | [x_yellow y_yellow z_yellow] = sph2cart(yellow_azimuth,yellow_elev, dkl_deg_yellow(1)); 83 | z_yellow= yellow_elev/max_elevation; 84 | 85 | [x_white y_white z_white] = sph2cart(white_azimuth,white_elev, dkl_deg_white(1)); 86 | z_white= white_elev/max_elevation; 87 | 88 | [x_black y_black z_black] = sph2cart(black_azimuth,black_elev, dkl_deg_black(1)); 89 | z_black= black_elev/max_elevation; 90 | 91 | plot3(x_red, y_red, z_red); hold on 92 | plot3(x_green, y_green, z_green) ; hold on 93 | plot3(x_blue, y_blue, z_blue) ; hold on 94 | plot3(x_cyan, y_cyan, z_cyan) ; hold on 95 | plot3(x_magenta, y_magenta,z_magenta) ; hold on 96 | plot3(x_yellow, y_yellow, z_yellow) ; hold on 97 | plot3(x_white, y_white, z_white) ; hold on 98 | plot3(x_black, y_black, z_black) ; hold on 99 | 100 | % Plot colour gamut of display device. 101 | vertex_matrix=[x_black y_black z_black; 102 | x_magenta y_magenta z_magenta; 103 | x_red y_red z_red; 104 | x_yellow y_yellow z_yellow; 105 | x_green y_green z_green; 106 | x_cyan y_cyan z_cyan; 107 | x_blue y_blue z_blue; 108 | x_white y_white z_white]; 109 | 110 | faces_matrix=[1 2 3; 111 | 1 3 4; 112 | 1 4 5; 113 | 1 5 6; 114 | 1 6 7; 115 | 1 7 2; 116 | 2 3 8; 117 | 3 4 8; 118 | 4 5 8; 119 | 5 6 8; 120 | 6 7 8; 121 | 7 2 8]; 122 | 123 | vertex_colour=[0 0 0; 124 | 1 0 1; 125 | 1 0 0; 126 | 1 1 0; 127 | 0 1 0; 128 | 0 1 1; 129 | 0 0 1; 130 | 1 1 1]; 131 | 132 | patch('Vertices',vertex_matrix,'Faces',faces_matrix,... 133 | 'FaceVertexCData',vertex_colour,'FaceColor','interp','EdgeColor','interp'); 134 | 135 | 136 | for i=0:0.05:pi 137 | az_arc=0; rad_arc=1; el_arc=i; 138 | [x_arc y_arc z_arc] = sph2cart(az_arc,el_arc, rad_arc); 139 | plot3(x_arc, y_arc, z_arc,'ko','MarkerFaceColor','k',... 140 | 'MarkerSize',1) ; hold on 141 | plot3(x_arc, y_arc, -z_arc,'ko','MarkerFaceColor','k',... 142 | 'MarkerSize',1) ; hold on 143 | end 144 | 145 | for i=0:0.05:pi 146 | az_arc=pi/2; rad_arc=1; el_arc=i; 147 | [x_arc y_arc z_arc] = sph2cart(az_arc,el_arc, rad_arc); 148 | plot3(x_arc, y_arc, z_arc,'ko','MarkerFaceColor','k',... 149 | 'MarkerSize',1) ; hold on 150 | plot3(x_arc, y_arc, -z_arc,'ko','MarkerFaceColor','k',... 151 | 'MarkerSize',1) ; hold on 152 | end 153 | 154 | text_size=12; 155 | text(1.1,0,'0','Color','k','FontSize',text_size,'FontWeight','bold'); 156 | text(1.3,0,'(L - M)','Color',red_line,'FontSize',text_size,'FontWeight','bold'); 157 | text(0,1.2,'90','Color','k','FontSize',text_size,'FontWeight','bold'); 158 | text(-1.2,0,'180','Color','k','FontSize',text_size,'FontWeight','bold'); 159 | text(0,-1.3,'270','Color','k','FontSize',text_size,'FontWeight','bold'); 160 | text(0,-2.2,'[S - (L + M)]','Color',blue_line,'FontSize',text_size,'FontWeight','bold'); 161 | 162 | text(0,0,1.3,'90','Color','k','FontSize',text_size,'FontWeight','bold'); 163 | text(0,0.,-1.3,'-90','Color','k','FontSize',text_size,'FontWeight','bold'); 164 | text(0,-0.2,1.7,'(L + M)','Color','k','FontSize',text_size,'FontWeight','bold'); 165 | 166 | view(60,30); 167 | axis off; --------------------------------------------------------------------------------