#! /usr/bin/python3 import sys, re import html_gen as h from process_funcs import bash import html_report_funcs as hr # Created on 2025-10-29 19:56:39.002606+00:00 make_clip_src_py.py last_edit = "Last edited on 2025-10-29 19:38:32 by stolfi"
As a more challenging test of the idea, we use the following clip of page f22v, from the "Herbal" section, cropped 800x420+824+1158. It covers the leaf closest to the reader in the west half of the second tier of leaves. The leaf is painted with the yellowish kind of green tempera-like paint. The paint is semi-transparent and there are some dark streaks in it, that could be faint inked details that were blithely painted over. (Click on thumbnails for the full-size images.)
One possible problem with this test is that there is some bleedthrough from the dark ink and red paint used in opposite side of the vellum, page f22r. Here is that page and the area corresponding to the clip above, both flipped left-right for convenience:
The approximate correspondence between the two images, determined visually from mutual bleedthroughs, is f22v[x,y] ~ f22r[2796-x,y-53]. This formula disregards possible differences of scale, orientation, and folio bending, but seems to be accurate enough over that clip. The following image shows the f22r clip above, with inverted colors and 50% opacity, overlaid on the f22v clip of interest. Unfortunately it seems that most of those dark streaks in the green area of the latter are indeed bleedthrough:
Anyway, we proceeded with the Bayesian classification described on Report 1. We considered six candidate provinces:
parch: blank parchment.
r1ink: medium brown Rt1 ink.
r2ink: dark brown Rt2 ink.
dkgrn: dark green paint over blank vellum.
ltgrn: light green paint over blank vellum.
liug0: light ink under green paint.
For each of these provinces, we created a mask image (manually, with an image editor) specifying a sample of pixels believed to be representative of it. For each mask shown below, we also show the image consisting of the selected pixels from the clip of interest.
For the parch province, we picked a sample of blank vellum pixels scattered all over the clip:
| parch sample |
![]() |
![]() |
| r1ink sample |
![]() |
![]() |
| r2ink sample |
![]() |
![]() |
There are a few character tails and other bits of text and outlines that seem to be the (now very faint) traces by the original Scribe. We did not see it necessary to introduce a separate province for them.
The dkgrn province is meant to be the parts inside the first leaf where the dark green paint was applied over blank vellum. The separate light green province ltgrn is justified because the third leaf in that leaf bundle, partly visible near the right edge of the clip, is painted with a shade of green that is significantly lighter than that of the front leaf. When choosing the dkgrn samples, we tried to avoid pixels where there could be bleedthrough from the dark ink of f22r as well as brown ink detail that were painted over.
| dkgrn sample |
![]() |
![]() |
| ltgrn sample |
![]() |
![]() |
The province liug0 is the one we hope to identify, namely the pixels were original faint ink drawings were painter over with the green paint inside the front leaf. When selecting the liug0 samples we tried to avoid pixels where there could be bleedthrough from the dark ink of f22r.
| liug0 sample |
![]() |
![]() |
Each color taken from the input image can be visualized as a point of Cartesian space R^3 inside the RGB color cube, whose corners are the eight "basic" RGB colors: (0,0,0) for black, (1,1,1) for white, (1,0,0) for red, (1,1,0) for yellow, etc.. A sample of colors is a cloud of points in this cube.
The images below are three different views of the three clouds corresponding to the three samples above. For clarity, each cloud was painted with a distinctive random color, unrelated to the colors themselves. Also, the plot only shows a subset of at most ~1000 points from each cloud.
In these images and in the analysis, the R,G,B color coordinates are transformed by a non-linear projective map of R^3 into three new coordinates ZUV, that are somewhat similar to the YUV coordinates. The thin lines in these images are the edges the RGB color cube, plus the diagonal from black to white, distorted by this map. This transformation of the color coordinates improves the separation of dark colors.
![]() |
![]() |
![]() |
It can be seen in these snapshots that the sample clouds of the two ink colors r1ink and r2ink overlap and are distinguished almost entirely by luminance (brightness). The same hold for the dark green and the light-ink-under-green samples, dkgrn and liug0. Apart from these two pairs, the clouds are well-separated.
The following images show the result of this analysis. For each of the six provinces plus OTHER, we get a grayscale image whose value at some pixel p is the probability of p belonging tho that province, based on its color. To make the images more intuitive, the image for parch is shown as computed (probability 1 = white) while the others are inverted (probability 1 = black).
The images for parch and ltgrn> are as expected, except that there is a halo of ltgrn>
allaround the dkgrn province. Along that edge the dark green paint layer becoems thinner and
looks like ltgrn>. or maybe
| parch out |
![]() |
| ltgrn out |
![]() |
The two brown inks were separated as expected:
| r1ink out |
![]() |
| r2ink out |
![]() |
The thin fuzzy outlines that surround some glyphs in the r1ink map are pixels that straddle the boundary between the dark r2ink glyphs and the blank vellum get a mix of the two colors, and therefore get classified as the lighter ink r1ink.
Unfortunately, since the classification was mostly determined by darkness, it is not evidence that the two provinces are really two distinct rounds of retracing, as opposde to the Scribe back-tracing his own traces with a more loaded pen.< Other methods will be needed to resolve this question.
The result for the conjectured ink-under-green-paint liug0 however was disappointing. The conjectured province liug0 couldnot be cleanly separated from the dark green province dkgrn, and the detected pixels were mostly bleedthrough of the brown and reddish inks from f22r:
| dkgrn out |
![]() |
|
| liug0 out |
![]() |
![]() |
The outliers (pixels that did not seem to belong to any of the given provinces) were mainly a halo around the dkgrn area, apparently where the bluish component of the paint spread out on the same side of the vellum, just as some of it bled through to the other side:
| OTHER out |
![]() |
In addition to that lighter green fringe, this map has a small patch at the lower right corner. It is a bit of light yellow-ocher paint applied to the stem of the 4th leaf (only) in this leaf bundle.
There are also many isolated outliers in the text half of the clip. These appear to be places where the blank vellum is discolored by bleedthrough from the drawings of f22r.
Two other attemps were made to separate a meaningful light-ink-under-green-paint province. We prepared a mask liug1 that has more samples than liug0, still avoiding the pixels where there is potential bleedthrough:
| liug1 sample |
![]() |
![]() |
| liug1 out |
![]() |
![]() |
Another attempt was made, using a mast liug2 that covered all the darker areas of the leaf, without regard for potential bleedthroughs:
| liug2 sample |
![]() |
![]() |
Again, the color cloud and the results were not very diferent:
| liug2 out |
![]() |
![]() |
But maybe the human eyebrain can succeed where the computer has failed. Here is what my Superior Pareidolia sees on the liug1 map above:
| liug1 out |
![]() |
![]() |
Clearly, a famous alchemical sorcerer apprentice about to prepare the Herba Pareidolica elixir on his original invention, the animated blender with an integral spout for easy pouring.
Last edited on 2025-10-24 05:02:53 by stolfi
def main(): global last_edit title = "[086] f79v-pond-S" title = h.protect_html(title) st = h.new_doc(title, "#eeffdd") h.section(st, 2, "Details") caption = """???""" hr.basic_figure(st, "annotated.png", caption) h.section(st, 2, "Discussion") discussion = """""" h.parags(st, discussion) h.output_doc(st, sys.stdout, 99, last_edit) return 0 # ---------------------------------------------------------------------- main()