Hi all, here comes just a little remark. I am aware that I am not actually answering the original question, but I am just assuming that "cleaning" such an image is the ultimate goal here (thank you for this interesting and challenging task!). So this is what I tried:
A sample of the original image:
I end up with:
I started by partitioning the image, working on the parts. One of the resulting advantages is that the successive processes can then be parallelized. Basically I found NonlocalMeansFilter
most helpful (but it takes hours to run!). My code:
ClearAll["Global`*"]
img0 = ColorConvert["<your image>", "Grayscale"];
partImgs0 = ImagePartition[img0, {200}];
partImgs1 = ParallelMap[ColorToneMapping@*ImageAdjust, partImgs0, {2}];
partImgs2 = ParallelMap[NonlocalMeansFilter[#, 6] &, partImgs1, {2}];
partImgs3 = ParallelMap[ImageAdjust[#, {2, -.2, 1.5}] &, partImgs2, {2}];
img1 = ImageAssemble[partImgs3]
(* dirty trick: drawing black vertical lines next to left/right borders
to prevent 'DeleteBorderComponents' from swallowing whole words *)
img1data = ImageData[img1];
Table[(img1data[[n, 10]] = 0; img1data[[n, -10]] = 0), {n, 1, Length[img1data]}];
img1a = Image[img1data]
img2 = DeleteBorderComponents[img1a]
img3 = ColorNegate@DeleteSmallComponents[img2, 100]
I am sure there still is room for lots of improvement!
Regards -- Henrik