Here is a way of extracting the positions of the various characters in your image by using ImageCorrelate
.
Define the image to be worked on.
image = <your image goes here>
Define a set of kernel images to correlate with the image. I use {0,1,2,3,4,5,6,7,8,9,+,-,E,.}
scaled to an appropriate size and then rasterised.
kernels =
Map[
(Style[#, FontSize -> 28, FontWeight -> Bold] // Rasterize //
ColorNegate // Binarize) &,
Join[Range[0, 9], {"+", "-", "E", "."}]
]
Prepare the image for use in ImageCorrelate
. Adding 0.01 to the 0 background avoids problems with it being “detected” - try omitting this step to see what happens.
imageneg = image // ColorNegate // ImageAdd[#, 0.01] &
Compute the CosineDistance
image correlation for each kernel image. Threshold the results to detect instances of each kernel image, and Dilate the resulting small bright detections so you can easily see them.
imagecorrels =
Map[
(ImageCorrelate[imageneg, #, CosineDistance] // ColorNegate //
Binarize[#, 0.85] &) &,
kernels
];
MapThread[Column[{#1, #2}] &, {Dilation[#, 3] & /@ imagecorrels, kernels}]
The results are very good for this set of kernel images. However, some of the “+” and “-“ are missed, which is probably because their kernel images differ too much from what appears in the image to be processed, and the “.” at the bottom of the image are missed, but this looks like an “edge effect” that would go away if you didn’t crop the image so tightly. Also, the “I” of “SI” is mistaken for a “1”.
The image processing could be tweaked to improve this performance. For instance, you could make the correlation results "compete" with each other to determine the "detection" at each image location - i.e. identify before detect - rather than simply threshold the correlations independently.
The locations of the detected image kernels could then be post-processed to create a representation of your image in terms of kernel images.
TextRecognize
doesn't do it letter by letter, but tries to identify words from a dictionary. This is a known limitation... See this answer by Arnoud $\endgroup$TextRecognize
is based on Tesseract, which is free and open source and will give you a lot more flexibility than usingTextRecognize
. For example it lets you constrain the set of characters you are interested in. That said, some time ago I tried to use it to read a huge matrix of 0s and 1s (again from an old paper), and ended up needing to do many manual corrections in each row ... It's probably not worth the time. $\endgroup$