Digital Image Processing with C++: Implementing Reference Algorithms with the CImg Library 1st Edition David Tschumperle - Own the complete ebook with all chapters in PDF format
Digital Image Processing with C++: Implementing Reference Algorithms with the CImg Library 1st Edition David Tschumperle - Own the complete ebook with all chapters in PDF format
com
https://ebookmeta.com/product/digital-image-processing-with-
c-implementing-reference-algorithms-with-the-cimg-
library-1st-edition-david-tschumperle/
OR CLICK HERE
DOWLOAD EBOOK
https://ebookmeta.com/product/digital-image-processing-with-
application-to-digital-cinema-1st-edition-ks-thyagarajan/
ebookmeta.com
https://ebookmeta.com/product/digital-image-processing-4th-edition-
global-edition-rafael-c-gonzalez/
ebookmeta.com
https://ebookmeta.com/product/digital-image-processing-using-
matlab-4th-edition-rafael-c-gonzalez/
ebookmeta.com
https://ebookmeta.com/product/extractive-metallurgy-of-copper-6th-
edition-mark-e-schlesinger/
ebookmeta.com
The Developing Mind How Relationships and the Brain
Interact to Shape Who We Are 3rd Edition Daniel J Siegel
https://ebookmeta.com/product/the-developing-mind-how-relationships-
and-the-brain-interact-to-shape-who-we-are-3rd-edition-daniel-j-
siegel/
ebookmeta.com
https://ebookmeta.com/product/salads-for-lunch-discover-new-and-
delicious-salad-recipes-for-lunch-2nd-edition-booksumo-press/
ebookmeta.com
https://ebookmeta.com/product/practical-equine-dermatology-2nd-
edition-janet-d-littlewood/
ebookmeta.com
https://ebookmeta.com/product/what-every-engineer-should-know-about-
cyber-security-and-digital-forensics-joanna-f-defranco/
ebookmeta.com
The Right to Development in the African Human Rights
System 1st Edition Serges Djoyou Kamga
https://ebookmeta.com/product/the-right-to-development-in-the-african-
human-rights-system-1st-edition-serges-djoyou-kamga/
ebookmeta.com
Digital Image Processing
with C++
Digital Image Processing with C++: Implementing Reference Algorithms with the Clmg Library
presents the theory of digital image processing and implementations of algorithms using a dedi-
cated library. Processing a digital image means transforming its content (denoising, stylizing,
etc.) or extracting information to solve a given problem (object recognition, measurement, mo-
tion estimation, etc.). This book presents the mathematical theories underlying digital image
processing as well as their practical implementation through examples of algorithms implement-
ed in the C++ language using the free and easy-to-use CImg library.
Chapters cover the field of digital image processing in a broad way and propose practical and
functional implementations of each method theoretically described. The main topics covered
include filtering in spatial and frequency domains, mathematical morphology, feature extraction
and applications to segmentation, motion estimation, multispectral image processing and 3D
visualization.
Students or developers wishing to discover or specialize in this discipline and teachers and re-
searchers hoping to quickly prototype new algorithms or develop courses will all find in this
book material to discover image processing or deepen their knowledge in this field.
David Tschumperlé is a permanent CNRS research scientist heading the IMAGE team at the
GREYC Laboratory in Caen, France. He’s particularly interested in partial differential equations
and variational methods for processing multi-valued images in a local or non-local way. He has
authored more than 40 papers in journals or conferences and is the project leader of CImg and
G’MIC, two open-source software/libraries.
David Tschumperlé
Christophe Tilmant
Vincent Barra
First edition published 2023
by CRC Press
6000 Broken Sound Parkway NW, Suite 300, Boca Raton, FL 33487-2742
Title of the original French edition, Le traitement numerique des images en C++. Implementation
d’algorithmes avec la bibliotheque CIMG- published by Ellipses - Copyright 2021, Edition Marketing S. A.
Reasonable efforts have been made to publish reliable data and information, but the author and publisher
cannot assume responsibility for the validity of all materials or the consequences of their use. The authors
and publishers have attempted to trace the copyright holders of all material reproduced in this publica-
tion and apologize to copyright holders if permission to publish in this form has not been obtained. If any
copyright material has not been acknowledged please write and let us know so we may rectify in any future
reprint.
Except as permitted under U.S. Copyright Law, no part of this book may be reprinted, reproduced, trans-
mitted, or utilized in any form by any electronic, mechanical, or other means, now known or hereafter
invented, including photocopying, microfilming, and recording, or in any information storage or retrieval
system, without written permission from the publishers.
For permission to photocopy or use material electronically from this work, access www.copyright.com or
contact the Copyright Clearance Center, Inc. (CCC), 222 Rosewood Drive, Danvers, MA 01923, 978-750-
8400. For works that are not available on CCC please contact [email protected]
Trademark notice: Product or corporate names may be trademarks or registered trademarks and are used
only for identification and explanation without intent to infringe.
DOI: 10.1201/9781003323693
Publisher’s note: This book has been prepared from camera-ready copy provided by the author.
Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
Preamble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
I I NTRODUCTION TO CImg
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
4 Mathematical Morphology . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.1 Binary images 54
4.1.1 Dilation and erosion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.1.2 Opening and closing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
4.2 Gray-level images 58
4.3 Some applications 59
4.3.1 Kramer-Bruckner filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.3.2 Alternating sequential filters . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.3.3 Morphological gradients . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.3.4 Skeletonization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
5 Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
5.1 Spatial filtering 69
5.1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
5.1.2 Low-pass filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
5.1.3 High-pass filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
5.1.4 Adaptive filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
5.1.5 Adaptive window filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
5.2 Recursive filtering 84
5.2.1 Optimal edge detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
5.2.2 Deriche filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
5.3 Frequency filtering 94
5.3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
5.3.2 The Fourier transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
5.3.3 Frequency filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
5.3.4 Processing a Moiré image . . . . . . . . . . . . . . . . . . . . . . . . . . 105
5.4 Diffusion filtering 110
5.4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
5.4.2 Physical basis of diffusion . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
5.4.3 Linear diffusion filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Table of contents vii
7 Segmentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
7.1 Edge-based approaches 151
7.1.1 Introduction to implicit active contours . . . . . . . . . . . . . . . . 151
7.1.2 Implicit representation of a contour . . . . . . . . . . . . . . . . . . . 156
7.1.3 Evolution equation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
7.1.4 Discretization of the evolution equation . . . . . . . . . . . . . . . . 160
7.1.5 Geodesic model propagation algorithm . . . . . . . . . . . . . . . 161
7.2 Region-based approaches 163
7.2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
7.2.2 Histogram-based methods . . . . . . . . . . . . . . . . . . . . . . . . . . 163
7.2.3 Thresholding by clustering . . . . . . . . . . . . . . . . . . . . . . . . . . 167
7.2.4 Transformation of regions . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
7.2.5 Super-pixels partitioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
viii Table of contents
10 3D Visualisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
10.1 Structuring of 3D mesh objects 227
10.2 3D plot of a function z = f (x, y) 229
10.3 Creating complex 3D objects 233
10.3.1 Details on vertex structuring . . . . . . . . . . . . . . . . . . . . . . . . . 233
10.3.2 Details on primitive structuring . . . . . . . . . . . . . . . . . . . . . . . 234
10.3.3 Details on material structuring . . . . . . . . . . . . . . . . . . . . . . . 235
10.3.4 Details on opacity structuring . . . . . . . . . . . . . . . . . . . . . . . . 235
10.4 Visualization of a cardiac segmentation in MRI 236
10.4.1 Description of the input data . . . . . . . . . . . . . . . . . . . . . . . . 236
10.4.2 Extraction of the 3D surface of the ventricle . . . . . . . . . . . . 237
10.4.3 Adding 3D motion vectors . . . . . . . . . . . . . . . . . . . . . . . . . . 238
10.4.4 Adding cutting planes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
10.4.5 Final result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Table of contents ix
Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
Taylor & Francis
Taylor & Francis Group
http://taylorandfrancis.com
Preface
It is with great pleasure that I accepted to preface this book, which is the successful
outcome of several years of research and experience by a trio of authors who are
experts in digital image processing, combining both its theoretical aspects and its
software implementations.
After promising results, David continued his work in a PhD thesis, under my su-
pervision. And very quickly, it became obvious that we needed to develop a reference
C/C++ library to process images with more than three channels or volume images
with any values (matrices, tensors, . . . ) to develop our research work.
Through the implemented algorithms, tests, successes and failures, David grad-
ually built his own personal C++ library of reusable features, in order to complete
his thesis work. The originality of David’s research work, the need to optimize and
develop software that survives his PhD period and that is “reusable” by the members
of the team constitute in my opinion the basis of the CImg library’s genesis.
At the end of David’s thesis, the ease of use of CImg had already seduced the new
PhD students and permanent members of the team. At the end of 2003, we decided,
in agreement with Inria’s development department, to distribute CImg more widely
as free software, naturally using the new French free license CeCILL, which had just
been created jointly by Inria, CEA and CNRS.
More than 20 years after its first lines of code, CImg is now an image processing
library used by thousands of people around the world, at the heart of dozens of free
projects, and just as importantly, continuously and actively maintained.
At the origin of this remarkable success is, first of all, the nature and the quality of
the methodological work carried out throughout the doctoral program, as well as its
implementation guided by the development of processing algorithms that must work
on images of types and modalities from the field of computer vision (cameras, video,
velocity fields) as well as in the satellite or medical fields, in particular neuroimaging,
with magnetic resonance diffusion imaging and its well-known model called the diffu-
sion tensor.
This aspect of data genericity was very quickly a central element in the design and
success of the library. With a focus on simplicity of design and use, and a constant
and coherent development of the library API, the authors have clearly succeeded in
coupling ease of use with the genericity of the processing that the library allows. The
free distribution of the library has allowed the academic world, as well as the research
and industrial world, to discover the prototyping and implementation of efficient image
processing algorithms in a gentle and enjoyable way.
Preface xiii
For teachers, researchers, students or engineers, this book will provide you with
an introduction to the vast field of image processing, as well as an introduction to the
CImg library for the development of state-of-the-art algorithms.
This book is expected to spark new passions for image processing, e.g., for begin-
ners or more experienced C++ developers who are interested in getting started in this
discipline. But this book will also shed new light on the field of image processing for
users and readers interested in recent advances in artificial intelligence, deep learning,
and neural networks. You will learn, for example, that it is not necessary to have a
neural network with 500 million weights, nor a million training images, to extract
the edges of an image, to segment it, to detect geometric features as segments and
circles, or objects located in it, to estimate displacement vectors in video sequences,
etc. And even better, you will be able to study the implementations of corresponding
algorithms, disseminated and explained throughout this book, made with the CImg
library, while testing them on your own data.
Rachid Deriche
Sophia Antipolis, June 22, 2022.
Taylor & Francis
Taylor & Francis Group
http://taylorandfrancis.com
Preamble
The practical realization of these methods depends on the nature of the image. In
the vast majority of cases, they are in digital form, i.e., sampled and quantified signals.
One carries out digital image processing which processes data-processing algorithms
on numerical machines (computers or dedicated circuits).
W HAT IS AN IMAGE ?
An image is a d dimensional signal. In order to process it, we associate this signal with
the notion of abstract signal. In this book we will only consider deterministic signals
to which we associate a function. In the context of random or stochastic signals, we
can use for example random processes.
I : Z ⊂ Rd → Rc I : Ω ⊂ Nd → Zc
(1)
(x1 , . . . , xd ) 7→ I (x1 , . . . , xd ) [i1 , . . . , id ] 7→ I [i1 , . . . , id ]
| {z } | {z }
Continuous image Digital (or numerical) image
x i
Sampling-Quantification
y I : Z ⊂ R2 → R3 I : Ω ⊂ N2 → Z3
j
(x, y) 7→ I (x, y) [i, j] 7→ I [i, j]
The conversion of a continuous signal (or image) to a digital (or numerical) signal
(or image) is carried out in two stages (Fig. 2):
• Sampling: discretize the evolution parameters (time, distances) ;
• Quantization: discretize the signal values.
3 3 3
2 2 2
1 1 1
2 4 6 8 10 12 14 2 4 6 8 10 12 14 2 4 6 8 10 12 14
With this book, we would like to offer you an enchanting, yet pragmatic walk
through the wonderful world of image processing:
This intertwining of theory and implementation is the essence of this book, and its
content is therefore intended for a variety of readers:
It is important to underline that we will only use simple concepts of the C++ lan-
guage and that the proposed programs will therefore be readable enough to be easily
transcribed into other languages if necessary. The CImg library, on which we rely,
has been developed for several years by researchers in computer science and image
processing (from CNRS - French National Centre for Scientific Research, INRIA -
French National Institute for Research in Digital Science and Technology, and the
University), mainly to allow rapid prototyping of new algorithms. It is also used as
a development tool in the practical work of several courses given at the bachelor’s,
master’s or engineering school level. Its use is therefore perfectly adapted to the
pedagogical approach that we wish to develop in this book.
The book is structured to allow, on the one hand, a quick appropriation of the
concepts of the CImg library (which motivates the first part of this book), and on
the other hand, its practical use in many fields of image processing, through various
workshops (constituting the second part of the book). The set of examples proposed,
ranging from the simplest application to more advanced algorithms, helps developing
a joint know-how in theory, algorithmic and implementation in the field of image
processing. Note that all the source codes published in this book are also available in
digital format, on the following repository:
https://github.com/CImg-Image-Processing-Book.
Image processing took off in the 1960s, with the advent of computers and the devel-
opment (or rediscovery) of signal processing techniques (the Fourier transform, for
example). From then on, in all the domains that this book proposes to approach in its
second part, many algorithms have been developed, always more powerful and precise,
that are able to process images of increasingly important size and in consequent
number.
In parallel to this development, since the 2000s, machine learning, and more
particularly deep learning, has achieved unequalled performance in computer vision,
even surpassing human capacities in certain areas. A deep neural network is now able
to annotate a scene by identifying all the objects, to realistically colorize a grayscale
image, or to restore highly noisy images.
So why are we still interested in “classical” image processing ? The shift from
image processing to deep learning is accompanied by a paradigm shift in data process-
ing: classical techniques first compute features on the original images (Chapter 6) and
then use them for the actual processing (segmentation: Chapter 7, tracking: Chapter
8, . . . ). The computation of these features is possibly preceded by pre-processing
(Chapters 3, 4 and 5) facilitating their extraction. In contrast, deep learning learns
these features, most often through convolution layers in deep networks, and uses these
learned features to perform processing.
And this is where the major difference comes in: to perform its task, the deep
network must learn. And to do this, it must have a training set made up of several
thousands (or even millions) of examples, telling it what it must do. For example, to
be able to recognize images of cats and dogs, the network must learn on thousands of
pairs (x, y), where x is an image of a cat or a dog and y is the associated label, before
being able to decide on an unknown image (Fig. 1.1).
However, obtaining this data is far from being an easy task. If, in some domains
(such as object recognition), well-established labeled databases are available (for
example, ImageNet1 , composed of more than 14 million different images distributed
in 21800 categories), it is most often very difficult, if not impossible, to constitute a
sufficiently well-supplied and constituted training set to train a neural network.
Moreover, beyond this problem of training data availability, deep neural networks
often require, during their learning phase, significant computing power and hardware
resources (via the use of GPUs - Graphics Processing Units - and TPUs - Tensor
Processing Units). Power that the student, or the engineer in search of a quick result,
will not necessarily have at his disposal.
1 http://www.image-net.org
6 Chapter 1. Introduction
Learning Inferring
So, even if the field of deep neural network learning has been expanding rapidly
for the last twenty years, and provides impressive results, classical image processing
has certainly not said its last word!
Among the plethora of existing programming languages, the C++ language has
the following advantages:
• The use of C++ templates eases the manipulation of generic image data, for
example, when the pixel values of images you process have different numerical
types (Boolean, integer, floating point, etc.).
One has to realize that writing such features from scratch is actually a tedious
task. Today, classic file formats have indeed a very complex binary structure: images
are mostly stored on disk in compressed form, each format uses its own compression
method that can be destructive or not. In practice, each image format is associated
with an advanced third-party library (e.g., libjpeg, libpng, libtiff, . . . ), each
being focused on loading and saving image data in its own file format. Similarly,
displaying an image in a window is a more complex task than it seems, and is al-
ways done through the use of third-party libraries, either specialized in “raw” display
(libX11, Wayland under Unix, or gdi32 under Windows), or in the display of
more advanced graphical interfaces with widgets (GTK, Qt, . . . ).
Finally, basic processing algorithms themselves are not always trivial to implement,
especially when optimized versions are required. For all these reasons, one usually
resorts to a high-level third-party library specialized in image processing, to work
comfortably in this domain in C++.
Why only these six libraries? Because they are well-established ones (all of them
existing for more than 15 years), widely used in the image processing community
8 Chapter 1. Introduction
and therefore well-proven in terms of performance and robustness. They are also still
under active development, free to use, multi-platform, and extensive enough to allow
the development of complex and diversified image processing programs. We have
voluntarily put aside libraries that are either distributed under a proprietary license,
or that are too young, or not actively maintained, or with a too restrictive application
domain (for example, libraries that are only capable of reading/writing images in a
few file formats, or that propose a too limited panel of image processing algorithms).
This diversity of choice actually reflects the various application domains that were
initially targeted by the authors of these different libraries.
d) OpenCV e) Magick++
Figure 1.2 – Logos of the main opensource C++ libraries for image processing (note
that the libvips library does not have an official logo).
CImg is a lightweight C++ library, which has been around for more than 20
years. It is a free library, whose source code is open (distributed under the CeCILL-C
open-source license), and which runs on various operating systems (Windows, Linux,
Mac OSX, FreeBSD, etc.). CImg gives the programmer access to classes and methods
for manipulating images or sequences of images, an image being defined here in the
broadest sense of the term, as a volumetric array with up to three spatial coordinates
10 Chapter 1. Introduction
(x, y, z) and containing vector values of any size and type. The library allows the
programmer to be relieved of the usual “low-level” tasks of manipulating images on
a computer, such as managing memory allocations and I/O, accessing pixel values,
displaying images, user interaction, etc. It also offers a fairly complete range of
common processing algorithms, in several areas including:
Compared to its competitors, the properties of the CImg library make it particularly
interesting in a pedagogical context such as the one we want to develop with this book:
• CImg is powerful. Most of its algorithms can be run in parallel, using the
different cores of the available processor(s). Parallelization is done through the
use of the OpenMP library, which can be optionally activated when compiling a
CImg-based program.
• CImg is an open source library, whose development is currently led by the
GREYC (Research lab in digital science of the CNRS), a public research lab-
oratory located in Caen, France. This ensures that the development of CImg
is scientifically and financially independent from any private interest. The
source code of CImg is and will remain open, freely accessible, studyable by
anyone, and thus favoring the reproducibility and sharing of image processing
algorithms. Its permissive free license (CeCILL-C) authorizes its use in any
type of computer program (including those with closed source code, intended
to be distributed under a proprietary license).
All these features make it an excellent library for practicing image processing in C++,
either to develop and prototype new algorithms from scratch, or to have a complete and
powerful collection of image processing algorithms already implemented, immediately
usable in one’s own programs.
The CImg API is simple: the library exposes four classes (two of them with a
template parameter) and two namespaces (Fig. 1.3).
• cimg_library: this namespace includes all the classes and functions of the
library. A source code using CImg usually starts with the following two lines:
12 Chapter 1. Introduction
#include "CImg.h"
using namespace cimg_library;
Thus, the programmer will have direct access to the library classes, without
having to prefix them with the namespace identifier cimg_library::.
• cimg: this namespace contains some utility functions of the library, which
are not linked to particular classes, and which can be useful for the devel-
oper. For example, functions cimg::sqr() (returns the square of a number),
cimg::factorial() (returns the factorial of a number), cimg::gcd()
(returns the greatest common divisor between two numbers) or
cimg::maxabs() (compute the maximum absolute value between two num-
bers) are some of the functions defined in the cimg:: namespace.
CImg defines four classes:
• CImg<T>: this is the most essential and populated class of the library. An
instance of CImg<T> represents an “image” that the programmer can manip-
ulate in his C++ program. The numerical type T of the pixel values can be
anything. The default type T is float, so we can write CImg<> instead of
CImg<float>.
• CImgList<T>: this class represents a list of CImg<T> images. It is used for
example to store sequences of images, or sets of images (that may have different
sizes). The default type T is float, so you can write CImgList<> instead of
CImgList<float>.
• CImgDisplay: this class represents a window that can display an image on
the screen, and interact through user events. It can be used to display animations
or to create applications requiring some user interactions (e.g., placement of
key points on an image, moving them, . . . ).
• CImgException: this is the class used to handle library exceptions, i.e.,
errors that occur when classes and functions of the library are misused. The pro-
grammer never instantiates objects of this class, but can catch the corresponding
exceptions raised with this class by the library to manage errors.
This concise design of the library makes it easy to learn, even for novice C++ pro-
grammers.
At first sight, this conception may seem surprising: in C/C++, the libraries that
one encounters are generally organized in the form of one or more header files (most
often, one header file per different structure or class defined by the library), completed
by a binary file (.a or .so files under Linux, .lib or .dll files under Windows),
which contains the library’s functions in compiled form.
Our teaching experience with CImg has shown that the first question raised by
new users of the library is: “Why is everything put in one file?”. Here we answer this
frequent question, by listing the technical choices justifying this kind of structuring,
and by pointing out the advantages (and disadvantages) of it. The global answer takes
into account several different aspects of the C++ language, and requires consideration
of the following points:
Because the library is generic. The CImg<T> image and CImgList<T> image
structures exposed by the library have a template parameter T, which corresponds
to the type of pixels considered for these images. However, the types T that will be
selected by the user of CImg classes are a priori unknown.
Of course, the most commonly used types T are in practice the basic C++ types
for representing numbers, i.e.,: bool (Boolean), unsigned char (unsigned 8-bit
integer), unsigned short (unsigned 16-bit integer), short (signed 16-bit inte-
ger), unsigned int (unsigned 32-bit integer), int (signed 32-bit integer), float
(float value, 32-bit), double (float value, 64-bit), etc. However, it is not uncom-
mon to see source codes that uses images of other types, such as CImg<void*>,
CImg<unsigned long long> or CImg<std::complex>.
One might think that pre-compiling the methods of the two classes CImg<T> and
CImgList<T> for these ten or so most common types T would be a good idea. This
is to overlook the fact that many of these methods take as arguments values whose
types are themselves CImg<t> images or CImgList<t> image lists, with another
template parameter t potentially different from T.
One can easily see that the multiplicity of possible combinations of types for the
arguments of the library’s methods makes it unwise to precompile these functions in
the form of binary files. The size of the generated file(s) would simply be huge, and
the functions actually used by the programmer would in practice only represent a tiny
portion of the pre-compiled functions.
The correct approach is therefore to let the compiler instantiate the methods and
functions of the CImg classes only for those combinations of template types that are
actually exploited in the user’s program. In this way, lighter and more optimized
binary objects or executables are generated, compared to what would be done with
a static binding to a large pre-compiled library. The main disadvantage is that the
functions of the CImg library used in the program must be compiled at the same time
as those of the program itself, which leads to an additional compilation overhead.
First, because unlike the C++ standard library, CImg defines only four different
classes, which turn out to be strongly interdependent. Moreover, the algorithms
operating on these class instances are defined as methods of the classes, not as external
functions acting on “containers”. This differs a lot from how the C++ standard library
is designed.
In practice, methods of the CImg<T> class need methods of CImgList<T>
(even if this is sometimes invisible to the user), simply because implementations
of CImg<T> methods require the functionality of CImgList<T> (and vice versa).
Similarly, CImgException is a ubiquitous class in CImg, since it is used to handle
errors that occur when library functions are misused. If the programmer does not want
to handle these errors, this class might seem useless to include. However, it is required
during compilation, since it is obviously used by the library core, which is, after all,
compiled at the same time as the user’s program.
This class interdependence means that if we wanted to have one header file per
CImg class, the first thing it would do is probably include the header files for the other
Introduction 15
classes. From a purely technical point of view, the gain from such a split would be
null: the four header files would be systematically included as soon as only one of
the classes in the library is used. In consequence, CImg proposes only one header file,
rather than one per class, without any real consequences on the compilation time.
But the fact that CImg is distributed in the form of a single header file is not only
due to the satisfaction of technical constraints bound to the C++ language. In practice,
this is indeed an undeniable advantage for the library user:
• Easy to install: copying a single file to a folder to get access to the functions
of a complete image processing library is comfortable (a thing that few current
libraries actually offer).
will tell CImg to use the functions of the libtiff and libjpeg libraries
when it needs to read or write images in TIFF or JPEG format (it is then of
course necessary to link the generated binary, statically or dynamically, with
these two libraries). There are a lot of such configuration macros that can be set
to activate specific features of CImg, when compiling a program.
On the other hand, this means that it is also possible to compile a CImg-based
program without activating any dependencies on external libraries. This flexibil-
ity in the control of dependencies is very important: using CImg does not imply
an automatic dependency on dozens of “low-level” third-party libraries, whose
functionalities might not be used by the programmer. Yet this is what happens
with most of the competing image processing libraries!
16 Chapter 1. Introduction
But one of the great strengths of the CImg library is its ease of use, and its ability to
express image processing algorithms in a clear and concise way in C++. This is what
we will show you in the rest of this book.
2. Getting Started with the CImg Library
Figure 2.1 – Goal of our first CImg-based program: decompose an image into blocks
of different sizes, and visualize the result in an interactive way.
The most informed readers will notice a parallel with the so-called quadtree
decomposition. The same type of decomposition is proposed here, but by putting
aside the tree structure of the decomposition (so, in practice, we only keep the leaves
of the quadtree).
All the necessary third-party libraries are expected to be installed, so let’s write
our first code:
Code 2.1 – A first code using CImg.
// first_code.cpp:
// My first code using CImg.
#include "CImg.h"
using namespace cimg_library;
int main() {
CImg<unsigned char> img("kingfisher.bmp");
img.display("Hello World!");
return 0;
}
As you can guess, the purpose of this first program is to instantiate an image object of
type CImg<unsigned char> (i.e., each pixel channel stored as an 8-bit unsigned
integer), by reading the image from the file kingfisher.bmp (the bmp format is
generally uncompressed, so it doesn’t require any additional external dependencies),
and displaying this image in a window.
In order to compile this program, we must specify that the program has to be
linked with the necessary libraries for display. Under Linux, with the g++ compiler,
we will for instance write the following minimal compilation command:
$ g++ -o first_code first_code.cpp -lX11 -lpthread
Under Windows, with the Visual C++ compiler, we will write in a similar way:
> cl.exe /EHsc first_code.cpp /link gdi32.lib user32.lib
shell32.lib
Running the corresponding binary does indeed display the image kingfisher.bmp
in an interactive window, and it allows us to explore the pixel values and zoom in
to see the details of the image (Fig. 2.2). At this point, we are ready to use more
advanced features of CImg to decompose this image into several blocks.
With CImg, obtaining such an image of smoothed and normalized brightness can
be written as:
CImg<> lum = img.get_norm().blur(sigma).normalize(0,255);
Here, we notice that the calculation of the lum image is realized by pipelining three
calls to methods of the CImg<T> class:
Thus, with a single line of code, we have defined a processing pipeline that returns
an image of type CImg<> (i.e., CImg<float>), providing information about the
luminosity of the colors in the original image (Fig. 2.3). The CImg architecture makes
it very easy to write this kind of pipelines, which are often found in source codes
based on this library.
22 Chapter 2. Getting Started with the CImg Library
Figure 2.3 – Computation of the lum image of color brightness, from an input image.
Now let’s look at the variations of this brightness image. Since the calculation
of the gradient ∇I is a basic operation in image processing, it is already implemented
in CImg via the method CImg<>::get_gradient(), that we are going to use
here:
CImgList<> grad = lum.get_gradient("xy");
CImg has many methods for applying mathematical functions to pixel values, and
the usual arithmetic operators are redefined to allow writing such expressions. Here,
calls to the CImg<float>::get_sqr() method return images where each pixel
value has been squared. These two images are then summed via the CImg method
CImg<float>::operator+() which returns a new image of the same size. Fi-
nally, CImg<float>::sqrt() replaces each value of this summed image by its
square root.
2.3 Computing the variations 23
Here again, we chose to use the get and non-get versions of the methods in
order to minimize the number of image copies. With this in mind, we can even use
CImg<float>::operator+=(), which can be seen as the non-get version of
CImg<float>::operator+(), and which avoids an additional creation of an
image in memory:
Figure 2.4 shows a detail of the different images of variations that we obtain. Re-
member: at any time, in a CImg program, the content of an image or a list of images can
be displayed by calling the CImg<T>::display() and CImgList<T>::display()
methods, which proves to be very useful for checking the correct step-by-step imple-
mentation of a program.
∂I
a) lum b) grad[0] = ∂x
∂I
c) grad[1] = ∂y
d) normgrad = k∇Ik
Figure 2.4 – Computation of the gradient image and its norm, from image lum (detail).
Another Random Document on
Scribd Without Any Related Topics
Yacht, ‘Southhampton’ changed to ‘Southampton,’ “to Cowes and
to Southampton”
Yacht, ‘for-forfeit’ changed to ‘forfeit,’ “shall forfeit all claim to
the prize”
Yacht, ‘regrad’ changed to ‘regard,’ “with regard to the sailing”
Yarwhip, ‘twelves’ changed to ‘twelve,’ “weight about twelve
ounces”
Zoology, double quote inserted after ‘body,’ “and move the
body.””
*** END OF THE PROJECT GUTENBERG EBOOK THE FIELD BOOK:
OR, SPORTS AND PASTIMES OF THE UNITED KINGDOM ***
1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside
the United States, check the laws of your country in addition to
the terms of this agreement before downloading, copying,
displaying, performing, distributing or creating derivative works
based on this work or any other Project Gutenberg™ work. The
Foundation makes no representations concerning the copyright
status of any work in any country other than the United States.
1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if
you provide access to or distribute copies of a Project
Gutenberg™ work in a format other than “Plain Vanilla ASCII” or
other format used in the official version posted on the official
Project Gutenberg™ website (www.gutenberg.org), you must,
at no additional cost, fee or expense to the user, provide a copy,
a means of exporting a copy, or a means of obtaining a copy
upon request, of the work in its original “Plain Vanilla ASCII” or
other form. Any alternate format must include the full Project
Gutenberg™ License as specified in paragraph 1.E.1.
• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”
• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.
1.F.
Most people start at our website which has the main PG search
facility: www.gutenberg.org.