function readme
% It is an example that shows how to deal with the synthetic image dataset proposed in
% "Direct Pose Estimation for Planar Objects," CVIU, 2018.
clc; clear; close all;

% 1. Download the poses.zip and synthetic_dataset.zip files.
% 2. Unzip them.
% 3. Randomly choose an image from the dataset and render a box according to the related pose.

if ~exist('poses', 'dir')
    if ~exist('poses.zip', 'file')
        disp('==> downloading pose files ...');
        if strcmp('win64', computer('arch'))
            system(['powershell -Command "Invoke-WebRequest ', ...
                    'http://media.ee.ntu.edu.tw/research/DPE/datasets/poses.zip ', ...
                    '-OutFile poses.zip"']);
        else
            system(['wget ', ...
                    'http://media.ee.ntu.edu.tw/research/DPE/datasets/poses.zip']);
        end
    end
    unzip('poses')
    delete poses.zip;
end
if ~exist('synthetic_dataset', 'dir')
    if ~exist('synthetic_dataset.zip', 'file')
        disp('==> downloading synthetic_dataset images ...');
        if strcmp('win64', computer('arch'))
            system(['powershell -Command "Invoke-WebRequest ', ...
                    'http://media.ee.ntu.edu.tw/research/DPE/datasets/synthetic_dataset.zip ', ...
                    '-OutFile synthetic_dataset.zip"']);
        else
            system(['wget ', ...
                    'http://media.ee.ntu.edu.tw/research/DPE/datasets/synthetic_dataset.zip']);
        end
    end
    unzip('synthetic_dataset');
    delete synthetic_dataset.zip;
end

tmps = {
    'BumpSign'; ...
    'StopSign'; ...
    'Lucent'; ...
    'MacMiniBoard'; ...
    'Isetta'; ...
    'Philadelphia'; ...
    'Grass'; ...
    'Wall'};
    
degradation = 'nbijt';
tmp_idx = randi(8);
deg_idx = randi(5);
if deg_idx == 1
    level = 0;
else
    level = randi(5);
end
img_idx = randi(50);
deg_type = sprintf('%s_%s%d', lower(tmps{tmp_idx}(1:2)), degradation(deg_idx), level);
img = imread(sprintf('synthetic_dataset/%s/%s/%02d.png', tmps{tmp_idx}, deg_type, img_idx));
poses = load(['poses/', deg_type, '.txt']);
ex_mat = eye(4);
ex_mat(1:3, 1:4) = reshape(poses(img_idx, :), 3, 4);

% in_mat
Ih = 600;
Iw = 800;
fx = norm([Iw, Ih]);
fy = fx;
cx = (Iw+1)/2;
cy = (Ih+1)/2;
in_mat = [fx,0,cx,0;0,fy,cy,0;0,0,1,0;0,0,0,1];

% world coordinate
min_dim = 0.5;
tmp_real_w  = min_dim * 640 / 480;
tmp_real_h = min_dim;

M = in_mat * ex_mat;
colors = {[0, 0, 255]; [0, 255, 255]; [0, 255, 0]};
imshow(img);
drawBox(M, tmp_real_w, tmp_real_h, colors);
set(gcf,'name',sprintf('[%s] %02d', deg_type, img_idx),'numbertitle','off') 

function coor2D = coorTrans3Dto2D(M, coor3D)
% Transform the coordinate from coor3D (x, y, z) to coor2D (u, v) via M
%
% Usage:
%   coor2D = coorTrans3Dto2D( M, coor3D )
%
% Inputs:
%   M = 4x4 transformation matrix
%   coor3D = original 3d coordinates (size = n*3)
%
% Outputs:
%   coor2D = new 2d coordinate (size = n*2)
%
% Details:
%   [hu] =[M11 M12 M13 M14]   [x]
%   [hv] =[M21 M22 M23 M24] * [y] 
%   [h ] =[M31 M32 M33 M34]   [z]
%   [1 ] =[M41 M42 M43 M44]   [1]

B = [coor3D, ones(size(coor3D, 1), 1)];
A = B * M.';
coor2D = A(:,1:2) ./ repmat(A(:,3), 1, 2);

function drawBox(M, u, v, colors)
c = cell(4, 1);
c{1} = [uint8(colors{1}), 1].';
c{4} = [uint8(colors{3}), 1].';
c{2} = [uint8(colors{1} * (1/3) + colors{2} * (2/3)), 1].';
c{3} = [uint8(colors{3} * (1/3) + colors{2} * (2/3)), 1].';
x = [-u, u];
y = [-v, v];
z = [ 0, v];
B1 = coorTrans3Dto2D(M,[x(2),y(2),z(1)]);
B2 = coorTrans3Dto2D(M,[x(2),y(1),z(1)]);
B3 = coorTrans3Dto2D(M,[x(1),y(1),z(1)]);
B4 = coorTrans3Dto2D(M,[x(1),y(2),z(1)]);
T1 = coorTrans3Dto2D(M,[x(2),y(2),z(2)]);
T2 = coorTrans3Dto2D(M,[x(2),y(1),z(2)]);
T3 = coorTrans3Dto2D(M,[x(1),y(1),z(2)]);
T4 = coorTrans3Dto2D(M,[x(1),y(2),z(2)]);
hold on;
line_width = 2;
p = plot([B1(1);B2(1)], [B1(2);B2(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{3}, c{1}]);
p = plot([B2(1);B3(1)], [B2(2);B3(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{1}, c{1}]);
p = plot([B3(1);B4(1)], [B3(2);B4(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{1}, c{3}]);
p = plot([B4(1);B1(1)], [B4(2);B1(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{3}, c{3}]);
p = plot([B1(1);T1(1)], [B1(2);T1(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{3}, c{4}]);
p = plot([B2(1);T2(1)], [B2(2);T2(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{1}, c{2}]);
p = plot([B3(1);T3(1)], [B3(2);T3(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{1}, c{2}]);
p = plot([B4(1);T4(1)], [B4(2);T4(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{3}, c{4}]);
p = plot([T1(1);T2(1)], [T1(2);T2(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{4}, c{2}]);
p = plot([T2(1);T3(1)], [T2(2);T3(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{2}, c{2}]);
p = plot([T3(1);T4(1)], [T3(2);T4(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{2}, c{4}]);
p = plot([T4(1);T1(1)], [T4(2);T1(2)], 'LineWidth', line_width, 'LineStyle', '-');
drawnow;
set(p.Edge, 'ColorBinding','interpolated', 'ColorData', [c{4}, c{4}]);
hold off;
drawnow;