~~NOTOC~~ ====== Homework 06 - Panorama ====== ==== Input Images ==== Consider the images were captured with the following EXIF info (focal length is in milimeters): ^ Tag ^ Name ^ Value ^ | 0xa002 | ExifImageWidth | 2400 | | 0xa003 | ExifImageHeight | 1800 | | 0xa20e | FocalPlaneXResolution | 2160000/225 | | 0xa20f | FocalPlaneYResolution | 1611200/168 | | 0xa210 | FocalPlaneResolutionUnit | inch | | 0x920a | FocalLength | 7400/1000 | The images were then resized. | 07 | 06 | 05 | **04 - reference** | 03 | 02 | 01 | |{{http://cw.felk.cvut.cz/brute/data/ae/release/2020l_gvg/gvg_ae/data/bridge/bridge_07.jpg?direct&90|bridge_07.jpg}}|{{http://cw.felk.cvut.cz/brute/data/ae/release/2020l_gvg/gvg_ae/data/bridge/bridge_06.jpg?direct&90|bridge_06.jpg}}|{{http://cw.felk.cvut.cz/brute/data/ae/release/2020l_gvg/gvg_ae/data/bridge/bridge_05.jpg?direct&90|bridge_05.jpg}}| {{http://cw.felk.cvut.cz/brute/data/ae/release/2020l_gvg/gvg_ae/data/bridge/bridge_04.jpg?direct&90|bridge_04.jpg}} |{{http://cw.felk.cvut.cz/brute/data/ae/release/2020l_gvg/gvg_ae/data/bridge/bridge_03.jpg?direct&90|bridge_03.jpg}}|{{http://cw.felk.cvut.cz/brute/data/ae/release/2020l_gvg/gvg_ae/data/bridge/bridge_02.jpg?direct&90|bridge_02.jpg}}|{{http://cw.felk.cvut.cz/brute/data/ae/release/2020l_gvg/gvg_ae/data/bridge/bridge_01.jpg?direct&90|bridge_01.jpg}}| ==== Description ==== {{courses:gvg:labs:gvg_panorama.pdf|Panorama}} ==== Steps ==== - Download the images above. - Download point correspondences between every pair of adjacent images (10 matches each) from the upload system (InputData). The correspondences are stored in a single array (cell matrix in matlab), such that for image pair ''i-j'', the points in the image ''i'' are in ''U[i-1,j-1]'' (python) or ''U{i,j}'' (matlab) and in the image ''j'' are in ''U[j-1,i-1]'' or ''U{j,i}''. - Find homographies ''H_ij'' for every pair of adjacent images by the same method (optimizing 4 over 10) as in HW-05; use your ''u2h_optim'' function for each homography. - Draw graph of transfer errors, sorted from lower to higher, of all neighboring pairs into a single image. Use different colour for every image pair, export as ''06_errors.pdf''. - Compute homographies ''H_i4'' for every i ∈ <1,7> that maps the images above into the reference image 04 (thus ''H_44'' is identity). Also construct inverse homographies ''H_4i''. - Plot the image borders of the images 02 to 06 transformed by appropriate homography to the image plane of the image 04. Export as ''06_borders.pdf''. - Construct a projective panoramic image from the images 03, 04, and 05, in the image plane of the image 04. Save as ''06_panorama.png''. - Construct calibration matrix ''K'' using the actual image size and the original EXIF. All the images share the same calibration. Store it in ''06_data.mat'' - Establish a transformation between each image plane and the coordinate system of the cylinder, described below. - Plot the image borders of all the images mapped onto the cylinder (''06_borders_c.pdf''). - Construct a panoramic image from all the images mapped onto the cylinder (''06_panorama_c.png''). ^ Example plot of errors ^ | {{courses:gvg:labs:06_errors.png|}} | ^ Example of image borders (origin not shifted) ^^ | {{courses:gvg:labs:06_borders.png|}} | {{courses:gvg:labs:06_borders_c.png|}} | ^ Example of projective panorama (images 3-4-5) ^ | {{courses:gvg:labs:07_panorama.jpg|}} | ^ Example of cylindrical panorama (all images) ^ | {{courses:gvg:labs:07_panorama_c.jpg|}} | ==== The cylinder ==== {{courses:gvg:labs:07_cylinder.png?direct&200|}} The cylinder is defined in the coordinate system γ (blue) of the image 04 (green) such that: * cylinder axis is equal to c2 axis of γ, * image plane of the image 04 is tangential to the cylinder, * image coordinate system defined on the cylinder surface has square pixels and equal horizontal resolution in the line where it touches the image 04. This leads that the cylinder has radius = 1 in the γ system. The cylinder surface is a set of points $[x_{\gamma} y_{\gamma} z_{\gamma}]^\top$ such that $$x_{\gamma}^2 + z_{\gamma}^2 = 1$$ For parametrisation of the cylinder surface we define two coordinate systems: the first (magenta) is based on γ, second (red) is pixel-based system of panoramic image. First, the surface of the cylinder is parametrised by circumference length (equal to angle since radius=1) and by the $y_{\gamma}$ coordinate. The ray $\lambda [x_{\gamma} y_{\gamma} z_{\gamma}]^\top$ intersects the cylinder in the point $$\lambda=\frac{1}{\sqrt{x_{\gamma}^2 + z_{\gamma}^2}}$$ $$[ a_{c\gamma}; y_{c\gamma} ] = [ \mbox{the angle given by } x_{\gamma} \mbox{ and } z_{\gamma}; \frac{y_{\gamma}}{\sqrt{x_{\gamma}^2 + z_{\gamma}^2}} ]$$ Second, the pixel size must be applied and image origin adjusted. Since the horizontal pixel size is 1/K(1,1) measured in units given by γ system, this leads to $$[ x_c; y_c ] = K_{11} [ a_{c\gamma}; y_{c\gamma} ] + [x_{0c}; y_{0c} ]$$ where the origin $[x_{0c}; y_{0c}]$ must be found such that all pixels from the input images will fit into the resulting panorama. ==== Upload ==== Upload an archive consisting of: - ''06_data.mat'' - ''06_histograms.pdf'' - ''06_borders.pdf'' - ''06_panorama.png'' - ''06_borders_c.pdf'' - ''06_panorama_c.png'' - ''hw06.m'' or ''hw06.py'' script solving the task, and any other files needed by the script