Preface

This book is a work in permanent progress in the fields of Digital Image Processing (DIP) and Computer Vision (CV), conceived as interactive instructional material for undergraduate and graduate courses in Computer Science, Engineering, and related fields.

ImportantHighlight

The work is grounded in the methodology described in Zampirolli et al. (2025) — an extension of Zampirolli et al. (2024), an award-winning paper in the Educational Resources and Environments track of EduComp 2024. The content integrates the morph.py library, developed by the author.

This is not a static book. Its content evolves continuously as examples are refined, new sections are added, and pedagogical approaches are improved based on usage experience and feedback from students and instructors. The work is thus treated as a project in constant evolution, aiming to keep pace with both technological advances and best teaching practices in DIP and CV.

Context of the first edition

The content of this edition was developed between May and August 2026, during the first offering of the Digital Image Processing course based on this instructional material. The course was taught to two undergraduate sections — composed mostly of Computer Science students, in the morning period — and one graduate section in Computer Science, all at UFABC. This first edition represents the outcome of that initial offering, consolidating the content developed, tested, and continuously refined throughout the term.

The teaching methodology followed a structured sequence in each class. First, a short video, averaging 7 minutes, generated with Gemini Notebook, was shown, alternating between presenting the conceptual part of the chapter and solving the Programming Exercises (EPs). In the latter case, nearly all EPs were solved during the class itself. Next, a set of about 12 slides, also generated with Gemini Notebook, was presented, using the book’s complete PDF and the morph.py file as sources. These slides were produced from a specific prompt for generating the theoretical and practical content of each chapter.

After this initial stage, about 100 minutes of class time remained for exploring the chapter’s two Colab notebooks — one theoretical and one practical — with an emphasis on the interactive simulators and running the code blocks, allowing students to modify parameters and observe their effects. In classes held in the lab, students transferred the answers to the EPs developed in Colab directly to the Moodle VPL activities, where they were automatically graded. This publication and use process for the EPs is presented at the end of this preface.

Ongoing assessment included biweekly practice tests, administered with the SEB (Safe Exam Browser) in Moodle, containing EPs similar to those in the exercise sets. Each practice test granted a 5% bonus on the final grade. The course’s two exams also used SEB, but were composed of parameterized questions generated in MCTest, whose description combines LaTeX and parameters in the [[code:variable]] format, defined in Python snippets delimited by [[def: ... ]] within the question itself. This process made it possible to generate 110 exam variations, individually assigned to students at random.

Appendix A details the creation of these questions in MCTest and their export to Moodle; Appendix B describes the configuration of the VPL activities, including the process of publishing the EPs; Appendix C presents the SEB configuration for the practice tests and exams; Appendix D describes the generation of the videos and slides used in class with Gemini Notebook; and Appendix E details the use of Artificial Intelligence (AI) in generating Socratic feedback for formative and summative activities, complementing the automatic grading performed by VPL.

How this book is produced

The content of this book is developed in Quarto and stored in the all folder of the github.com/fzampirolli/pdi-vc repository. From a single source, the book is automatically generated and published in different formats, shown in Table 1.

While the PDF edition records the state of the work at the end of the course’s first offering in 2026, development of the book continues on an ongoing basis. Every update to the GitHub repository automatically generates new versions of the HTML pages, the PDF, and the notebooks, immediately making improvements available to readers.

Table 1: Different publication formats automatically generated from the same source.
Format Description
HTML Web version, with interactive simulators and navigation between chapters: fzampirolli.github.io/pdi-vc/
PDF Version suited for printing or offline reading: livro.pt.py.pdf
Notebooks (.ipynb) Compatible with Jupyter and Google Colab, allowing readers to run, modify, and experiment with code examples and Programming Exercises (EPs). A custom filter preserves cross-references, figure and table numbering, and automatically formats citations according to the ABNT standard.

The work is published in ten combinations — each code track (Python and C++) in five languages (Portuguese, English, French, Spanish, and Italian). With the translation cache already populated, a full regeneration (translation, re-execution of the notebooks, HTML and PDF rendering, and publication) takes about 72 minutes, with a real average parallelism of ~5 processes (peak of 8); the first generation of a new language, with an empty cache, is much slower — about 80 minutes per combination, as observed for the first generations of Spanish and Italian. Table 2 summarizes each combination (with the cache already populated): PDF page count and rendering time. This wall-clock total is much lower than the sum of each individual combination’s time (over 5 hours if run one at a time): on a multi-core CPU, several combinations run at the same time, so the total time is not simply the sum of the individual ones.

Table 2: PDF page count and rendering time per combination (real average parallelism of ~5 processes, peak of 8). The base Python/Portuguese combination only renders the outputs already stored in the source notebooks; the others re-execute all the code.
Combination Track Language Pages Rendering time
py.pt Python Portuguese (base) 654 ~7 min
py.en Python English 644 ~31 min
py.fr Python French 666 ~31 min
py.es Python Spanish 666 ~31 min
py.it Python Italian 658 ~31 min
cpp.pt C++ Portuguese 434 ~26 min
cpp.en C++ English 426 ~34 min
cpp.fr C++ French 434 ~38 min
cpp.es C++ Spanish 430 ~37 min
cpp.it C++ Italian 428 ~35 min

Validation status. Only the py.pt combination (Python, Portuguese) is the curated source: it is where the author writes, reviews, and validates all the content. The other nine combinations — the C++ tracks and the translations into English, French, Spanish, and Italian — are generated automatically, by language-model translation and code transpilation, and still require detailed review. The main concern is the text embedded in some figures: where the translated version has not yet been produced, the image appears with Portuguese text (each translated figure follows the same language suffix as the other generated files, e.g. image_en.png).

The HTML pages, the PDF, and the notebooks available in the project always reflect the most recent state of development. When an official edition is published, it is identified by a tag in the GitHub repository, allowing the content corresponding to that edition to be reproduced exactly. This way, readers can follow both the continuous evolution of the project and retrieve any previously published official edition.

git clone https://github.com/fzampirolli/pdi-vc.git
cd pdi-vc
git checkout <version-tag>

Each chapter provides two Run on Colab buttons (Figure 1), which link to complementary environments:

  1. Theoretical Part, located at the beginning of each chapter, containing the concepts presented and executable code examples;
  2. Practical Part, in the Practical Part with Programming Exercises (EPs) section, dedicated to the exercises and their interactive simulators.

Figure 1: Clickable Run on Colab button, available at the beginning of the Theoretical and Practical parts of each chapter, allowing interactive execution of the examples and exercises. In the PDF version, there is a direct HTML link between the simulator image and its caption.

Notebook generation is fully automated by the gerar_notebooks_alunos.py script, which adapts the content for interactive environments, allowing it to run without installing Quarto.

Use of Artificial Intelligence tools

The conception, pedagogical design, conceptual structure, and core content of this book are of the author’s exclusive authorship.

In the editing and development-support process, free-tier versions of Artificial Intelligence (AI) tools such as ChatGPT, Claude, DeepSeek, and Gemini were used, strictly as auxiliary resources. Their use was limited to supporting the review and improvement of textual style, optimizing code syntax, and assisting in generating conceptual illustrations and examples.

All responses and content suggested by these tools were subject to critical analysis, verification, technical validation, adaptation, and integration by the author, who takes responsibility for the text, the code, and the instructional resources presented. AI tools are not considered authors or co-authors of the work, nor responsible for the intellectual, technical, or pedagogical decisions underlying its content.

It should also be noted that the simulators and interactive resources in the book — available in the HTML and Jupyter Notebook (IPYNB) versions — were designed and implemented as part of the work’s pedagogical approach, aiming to provide direct experimentation with the concepts presented and to foster readers’ learning autonomy.

Distinct from the editorial use described above, the multi-language generation pipeline (see “How this book is produced”) employs a language model as a system engineering component: automatic translation of content between Portuguese and other languages, with an incremental cache that avoids retranslating unchanged passages. This step uses the paid DeepSeek API (deepseek-v4-flash model); the complete book has already been translated from Portuguese into English, French, Spanish, and Italian, and Chapters 1 to 5 additionally have a C++ track that truly compiles and runs — at a cumulative cost on the order of a few dollars, thanks to the incremental cache.

The morph.py library

The morph.py library (Zampirolli et al., 2025) accompanies the whole work as a teaching-support tool. Its goal is not to replace established libraries such as OpenCV, scikit-image, scikit-learn, NumPy, or Matplotlib, nor to compete with them in performance or scope. Instead, it seeks to make the fundamental algorithms of Digital Image Processing and Computer Vision (DIP-CV) transparent, allowing students to understand their implementation, modify the code, and develop new functionality.

Whenever possible, the library offers two versions of the same algorithm: a didactic implementation, written step by step to directly reflect the mathematical definitions presented in the book, and an optimized implementation, based on specialized libraries for practical applications.

NoteTechnical Heritage

The structure of morph.py is based on Mathematical Morphology tools developed in Brazil, such as MMachLib (Lotufo et al., 1997) and MMach (Barrera et al., 1998), as well as mmorph, used in the work of Dougherty; Lotufo (2003). These libraries served as references for teaching in the field for decades.

This philosophy can be observed, for example, in the morphological dilation operators:

  • mm.dil: optimized implementation, suited for practical applications;
  • mm.dil0: didactic implementation of dilation for planar structuring elements, following directly the classic definition of Mathematical Morphology;
  • mm.dil1: didactic implementation of dilation for structuring functions (non-planar kernels), rigorously following its mathematical formulation.

The library also provides functions for reading, displaying, color conversion, filtering, and mathematical morphology through a simple interface:

from morph import mm

img = mm.gray(mm.read("lena.jpg"))  # read and convert to grayscale
grad = mm.gradm(img)                # morphological gradient
mm.show(grad)                       # display

Throughout the book, new methods are introduced into the library to simplify solving the Programming Exercises (EPs). Among them are mm.readTrain() and mm.readTest(), which automate reading the training and test datasets used in the pattern recognition chapters.

In addition, all Gemini Notebook projects include the morph.py file, allowing direct consultation and discussion of the implementation of the algorithms presented in the book. This way, students can use Gemini Notebook itself as a study assistant, asking questions such as:

Explain how the mm.knn0 algorithm from morph.py was implemented, showing the code and commenting on each step in a didactic way. Also explain the differences between mm.knn0() and mm.knn().

ImportantDidactic implementations and optimized implementations

In several chapters, the same algorithm is presented in two versions. Functions with a suffix 0, 1, etc. (for example, mm.knn0(), mm.dil0(), and mm.dil1()) are didactic implementations, developed to facilitate understanding of the algorithms. Functions without a suffix (such as mm.knn() and mm.dil()) use optimized implementations, often based on specialized libraries such as OpenCV, scikit-image, and scikit-learn, and are better suited for practical applications.

In activities graded by Moodle’s VPL, libraries such as scikit-learn and, in some cases, scikit-image, cannot be used due to memory limitations in the execution environment. For this reason, the Programming Exercises (EPs) preferably use the didactic implementations from morph.py, which produce the same results, albeit with lower computational performance. This restriction does not apply when programs are run locally, for example in VS Code, Jupyter Notebook, or Google Colab.

The library’s source code is available at:

https://github.com/fzampirolli/pdi-vc/tree/master/morph

Programming Exercises (EPs) and Automatic Grading

Each unit of the book includes practical Programming Exercises (EPs) of increasing complexity, designed to consolidate the concepts presented throughout the chapter. Each EP is accompanied by an interactive simulator, available in both HTML and IPYNB versions, which lets students manipulate parameters, visualize the algorithms’ behavior, and develop an intuitive understanding of the problem before starting implementation. This way, the learning process combines experimentation, programming, and automatic grading.

Solutions are validated locally by the TestSuite class (testsuite.py), which compares the program’s output against the test case files (.cases):

TestSuite("EP01_01.py").run()

The system supports multiple languages (Python, Java, C++, C, JavaScript, and R) and can be integrated directly with Moodle. Instructors interested in the complete step-by-step process for publishing EPs as VPL activities should consult the Instructor’s Guide at the end of this preface, and Appendix B.

Open source

The project is governed by open-source principles. The public repository gathers the text, code, images, and scripts: github.com/fzampirolli/pdi-vc

Each version of the book is permanently archived on Zenodo with a citable DOI. To cite this material in academic work:

ZAMPIROLLI, Francisco de Assis. PDI+VC — Digital Image Processing and Computer Vision. UFABC, 2026. DOI: 10.5281/zenodo.20784605

It should be noted, for the record, that the content presented in this work reflects the critical outlook, pedagogical approach, and teaching experience of its author. Accordingly, the analyses, approaches, and opinions expressed throughout this book represent solely the understanding of its creator, and do not constitute or reflect an official or institutional position of the Federal University of ABC (UFABC).

Before you begin: Python Notebooks

The concept of Literate Programming, proposed by Donald Knuth (Knuth, 1984), underlies the structure of this material. The logic reverses the traditional paradigm: the program is written for human reading, resembling an essay, while the code is extracted separately for computational execution.

The content is structured into notebooks — documents that interleave text cells (in Markdown) and code cells (in Python).

  • Execution: code cells are identified by [ ]. They can be run with Shift + Enter or the ▶️ button in the interface.
  • Environments: the notebooks can be run locally, through Jupyter or Visual Studio Code (VS Code), as well as in cloud environments such as Google Colab.
TipNote on the format

In interactive environments, the code can be modified and executed. In the static versions (HTML or PDF), the code blocks are for reading and reference purposes, without any loss to the completeness of the explanations.


Instructor’s Guide: Publishing EPs in Moodle

This section is intended for instructors who wish to integrate the Programming Exercises (EPs) with Moodle’s VPL (Virtual Programming Lab) activities, complementing Appendix B.

Integration with Moodle (VPL)

The EPs from the notebooks can be converted into VPL activities in Moodle. The ep_tools.py script (run via make build) automates exporting the EPs from the end of each chapter in two steps:

  1. Extraction (make eps): generates a standalone interactive HTML per EP, with the statement, examples, and simulator, in gen/book/eps/<version>/. See the full list at: https://fzampirolli.github.io/pdi-vc/eps/py.pt/index.html
  2. Conversion (make moodle): transforms the HTML into a self-contained fragment, with no external CSS dependency, ready to be pasted into the Moodle editor, in gen/book/eps/<version>_moodle/. See an example at: https://fzampirolli.github.io/pdi-vc/eps/py.pt_moodle/EP01_01.html

Additionally, all the interactive simulators developed throughout the book can be accessed directly at https://fzampirolli.github.io/pdi-vc/simuladores/py.pt/.

NoteOther tracks and languages

The links above use py.pt as an example. To access EPs or simulators for another language/locale combination, just swap that segment in the URL — for example, cpp.it for the C++ track in Italian: https://fzampirolli.github.io/pdi-vc/eps/cpp.it/index.html. The structure is the same for every available combination, under /eps/<version>/, /eps/<version>_moodle/, and /simuladores/<version>/.

When publishing with make publish, both versions of each EP become available at the links indicated. Instructors can combine both strategies: paste the Moodle version into the VPL editor (with a working simulator) and include a link in the statement to the full version, where formulas are rendered correctly by MathJax.

WarningMandatory review before publishing to Moodle

Although automated, the conversion requires instructor review due to limitations of Moodle’s TinyMCE/HTML Purifier editor:

  • Mathematical formulas — TinyMCE discards backslashes (\), corrupting LaTeX equations. For this reason, the Moodle version converts simple formulas to plain HTML (entities such as &ge;, &times;). Complex formulas (\begin{cases}, matrices, integrals) may come out incomplete — review them and, if necessary, rewrite them as text or point to the full version via link.
  • External figures — Supplementary images must be inserted manually into the VPL activity.
  • Simulators — Work perfectly as long as they use standard JavaScript with inline styles and direct DOM manipulation (getElementById). Warning: if you include LaTeX formulas containing the \ character in Moodle, the simulators may stop working.

How to Publish to Moodle

  1. Access the Moodle version of the desired EP:

    https://fzampirolli.github.io/pdi-vc/eps/py.pt_moodle/EPXX_YY.html
  2. Copy the full source code of the page (Ctrl+U → Ctrl+A → Ctrl+C).

  3. In Moodle, create the VPL activity, open the HTML editor, paste the content (Ctrl+V), and save.

  4. Import the .cases files from the all/capXX/casos/ folder into the VPL test settings.

TipReusing Test Cases

The .cases files are compatible with VPL, allowing the same test set to be used both in local development and in automated grading in Moodle.