======= macs_io ======= A minimal C++ library for reading and writing MACS images. The latest version can be found `here `_. You can also download a `test dataset `_. ============ Installation ============ To build the library you need: * `CMake `_ * A C++ compiler (GCC/Clang or MSVC have been tested) * The `Qt library `_ .. rubric:: Make based systems .. code-block:: bash $ cmake -DCMAKE_INSTALL_PREFIX= $ make $ make install .. rubric:: Visual Studio .. code-block:: bash $ cmake ^ -G"Visual Studio 15 2017 Win64"^ -DCMAKE_PREFIX_PATH=C:\Qt\5.11.3\msvc2017_64\lib\cmake # open macs_io.sln ============ Usage ============ To use the library, you can either use cmake .. code-block:: cmake :caption: CMakeLists.txt cmake_minimum_required(VERSION 2.8.12) project(my_sample C CXX) find_package(macs_io REQUIRED) add_executable(my_sample main.cpp) target_link_libraries(my_sample macs_io) or simply add the source files ``macs_io.cpp`` and ``MacsMetaData.cpp`` to your project. ============ Examples ============ There are three examples included: .. rubric:: macs_decode The sample ``macs_decode`` shows how to use macs_io to read a MACS image and write a jpg/tif/png. It takes the following options: .. code-block:: bash $ macs_decode -h Usage: macs_decode [options] in.macs out.jpg where options are: Stretch: stretch_min=0.0 stretch factor min stretch_max=1.0 stretch factor max gamma=1.0 gamma correction Devignetting: devignette_a=0.0 model based devignetting parameter devignette_b=0.0 model based devignetting parameter devignette_c=0.0 model based devignetting parameter devignette_offset=0 model based devignetting parameter devignette_factor=1.0 model based devignetting parameter Color balance: color_balance_r=1.0 color balance parameter color_balance_g=1.0 color balance parameter color_balance_b=1.0 color balance parameter Distortion: cx=w/2 principal point cy=h/2 principal point k1=0.0 radial lens distortion parameter k2=0.0 radial lens distortion parameter k3=0.0 radial lens distortion parameter .. tabs:: .. group-tab:: Original .. code-block:: bash $ macs_decode helgoland.macs helgoland.tif .. group-tab:: & Stretch .. code-block:: bash $ macs_decode stretch_min=0 stretch_max=0.4 helgoland.macs helgoland_stretch.tif .. group-tab:: & Gamma .. code-block:: bash $ macs_decode stretch_min=0.1 stretch_max=0.53 gamma=0.5 helgoland.macs helgoland_gamma.tif .. group-tab:: & Devignetting .. code-block:: bash $ macs_decode stretch_min=0.08 stretch_max=0.53 gamma=0.5 devignette_a=-0.313252 devignette_b=-2.59249 devignette_c=2.2651 helgoland.macs helgoland_devignetted.tif .. tabs:: .. group-tab:: Original .. image:: ./images/helgoland.jpg .. group-tab:: & Stretch .. image:: ./images/helgoland_stretch.jpg .. group-tab:: & Gamma .. image:: ./images/helgoland_gamma.jpg .. group-tab:: & Devignetting .. image:: ./images/helgoland_devignetted.jpg .. code-block:: bash $ macs_decode img1.macs img1.jpg .. rubric:: macs_encode which reads a jpg/tif/png and writes a macs image, with metadata. You need to pass the information if the input image is a single channel (gray) image or should be interpreted as a bayer mosaic. .. tabs:: .. group-tab:: Original .. code-block:: bash $ macs_encode color=BGGR poster_raw.tif poster.macs .. group-tab:: & Debayer .. code-block:: bash $ macs_decode poster.macs poster.tif .. group-tab:: & Color Correction .. code-block:: bash $ macs_decode poster.macs poster_cc.tif color_balance_g=0.9 color_balance_r=1.0 color_balance_b=1.3 .. tabs:: .. group-tab:: Original .. image:: ./images/poster_raw.jpg .. group-tab:: & Debayer .. image:: ./images/poster.jpg .. group-tab:: & Color Correction .. image:: ./images/poster_cc.jpg .. rubric:: macs_info which prints the basic metadata of a macs image .. literalinclude:: macs_info.txt :language: bash =============================================================== Theory =============================================================== Lens distortion =============== We use the `radial lens distortion model `_ commonly used in computer vision. .. math:: {\displaystyle x_{\mathrm {u} }=x_{\mathrm {c} }+{\frac {x_{\mathrm {d} }-x_{\mathrm {c} }}{1+K_{1}r^{2}+K_{2}r^{4}+K_{3}r^{6} }}} \\ \\ {\displaystyle y_{\mathrm {u} }=y_{\mathrm {c} }+{\frac {y_{\mathrm {d} }-y_{\mathrm {c} }}{1+K_{1}r^{2}+K_{2}r^{4}+K_{3}r^{6} }}} Where - :math:`(x_{\mathrm {d} },\ y_{\mathrm {d} }) =` distorted image point as projected on image plane using specified lens, - :math:`(x_{\mathrm {u} },\ y_{\mathrm {u} }) =` undistorted image point as projected by an ideal pinhole camera, - :math:`(x_{\mathrm {c} },\ y_{\mathrm {c} }) =` distortion center, - :math:`K_{\mathrm {n} } =` radial distortion coefficient, and - :math:`{\displaystyle {r = \sqrt {(x_{\mathrm {d} }-x_{\mathrm {c} })^{2}+(y_{\mathrm {d} }-y_{\mathrm {c} })^{2}}}}` Sometimes there is a need to convert from a different photogrammetric parametrization (like Inpho, or Pictran). Here are some code snippets to perform that conversion. .. rubric:: Converting the Inpho distortion model to the CV model .. code:: ipython3 # Input in Inpho format w = 7920 h = 6002 # pixel size in mm ps_mm = 4.6/1000 # principal point in mm cx_mm = 0.306176 cy_mm = 0.160448 inpho_k1 = -1.476649e-05 inpho_k2 = -3.085708e-08 inpho_k3 = 0 .. code:: ipython3 # Inpho to CV cx_px = w/2 + cx_mm/ps_mm cy_px = h/2 - cy_mm/ps_mm k1 = inpho_k1*ps_mm**2 k2 = inpho_k2*ps_mm**4 k3 = inpho_k3*ps_mm**6 (cx_px, cy_px), (k1,k2,k3) ((4026.56, 2966.12), (-3.124589284e-10, -1.3816121798848e-17, 0.0)) .. rubric:: Converting the Pictran distortion model to the CV model .. code:: ipython3 # Input in Pictran format w = 7920 h = 6002 # pixel size in mm ps_mm = 4.6/1000 # principal point in mm x0 = 0.306176 y0 = 0.160448 A1 = -1.476649e-05 A2 = -3.085708e-08 .. code:: ipython3 #Pictran to CV cx_px = w/2 + x0/ps_mm; cy_px = h/2 - y0/ps_mm; k1 = A1*ps_mm**2 k2 = A2*ps_mm**4 k3 = 0.0 (cx_px, cy_px), (k1,k2,k3) ((4026.56, 2966.12), (-3.124589284e-10, -1.3816121798848e-17, 0.0)) Devignetting =============== We use a parametric devignetting function which multiplies each pixel by a gain function which is defined as follows: .. math:: {\displaystyle {g(r) = 1 + a r^2 + b r^4 + cr^6 }} where .. math:: {\displaystyle {r = \frac{\sqrt {(x-\bar{x})^{2}+(y-\bar{y})^{2}}}{\sqrt {\bar{x}^{2}+\bar{y}^{2}}}}} .. is the normalized radius of :math:`(x, y)`, i.e., the Euclidean distance of :math:`(x, y)` from the image center :math:`(\bar{x}, \bar{y})`, divided by the image diagonal. Thus, :math:`r = 0` in the image center and :math:`r = 1` in each of the four corners. [Rohlfing]_ ============ API ============ The entire interface is contained in ``macs_io.h``: .. literalinclude:: ../include/macs_io.h :language: c++ :start-after: #include ============ Bibliography ============ .. [Rohlfing] T. Rohlfing, **Single-Image Vignetting Correction by Constrained Minimization of log-Intensity Entropy**