Hi Simon, yes, I think the instructions you can give to the segmentation step are quite limited, mostly the PSM parameter and I suppose a few minor ones. There is something about tables but I've never used it and yours might be too small for this to work. Yes, you should be able to see what is happening looking at the HOCR file.
You could also try the attached script, it was made for the 4.x version but might work with 5.x too. It draws boxes around letters according to the tesseract output. I'm attaching the output on a simple text and on several crops from your image: only in the clean one you can see the text boxes. You can do the same from the HOCR file. Yes, you still need to fine tune for the new character. I was able to train up to 57k iterations still improving the results on a test dataset. You need to fine tune including the new symbols AND all the other symbols you expect to recognize in the training dataset. I'm not sure if you are using something like this: merge_unicharsets $(TESSDATA)/$(CONTINUE_FROM).lstm-unicharset $(TRAIN)/my.unicharset "$@" if so, you can replace it with: cp "$(TRAIN)/my.unicharset" "data/unicharset" and the new model will output only the characters that are present in your new dataset (for example to discard lower case letters, the < character, %, !, #, etc.) Also, if you do not need to recognize the < symbol, you could reuse this rather than adding a new one completely. I mean that when you generate the images with the "angle" symbol you put < in the transcription. Maybe it helps, maybe it won't. Bye Lorenzo Il giorno sab 25 nov 2023 alle ore 12:25 Simon <smong5...@gmail.com> ha scritto: > Yes in general I want to recognice this part "< 0,05 A" except that the > < ist actually ∠ the character for angularity. > > The segmentation process of tesseract can't be edited right? So you mean I > would need to make an Tesseract independent program that localizes the > boxes crops them out and feeds them to Tesseract? In that case I still > would need to train Tesseract for recognizing ∠ . So I am still > wondering how to train this sign properly. > > Because you asked if the isolation step is able to isolate it, I can check > this by looking at the hocr information right? > > > > Lorenzo Blz schrieb am Freitag, 24. November 2023 um 10:45:14 UTC+1: > >> Hi Simon, >> if I understand correctly how tesseract works, it follows this steps: >> >> - it segments the image into lines of text >> - it then takes each individual line and slides a small window, 1px wide >> I think, over it, from one end to the other. For each step the model >> outputs a prediction. The model, being an bidirectional LSTM has some >> memory of the previous and following pixel columns. >> - all these predictions are converted into characters using beam search >> >> Please correct me if I got it wrong. So the first thing I think looking >> at your picture is the segmentation step. Do you want to read the "< 0,05 >> A" block only? Is the segmentation step able to isolate it? This is the >> first thing I would try to understand. >> Also your sample image for "<" has a very different angle to the one >> before 0,05. >> >> In this case a would try to do a custom segmentation, looking for >> rectangular boxes of a certain height, aspect ratio, etc. Then cropping >> these out (maybe dropping the rectangular box and the black vertical lines) >> and feed them to tesseract. This of course requires custom programming. >> >> This might give good results even without fine tuning. I would try this >> manually with GIMP first. >> >> >> Also I suppose you are not going to encounter a lot of wild fonts into >> these kind of diagrams. The more fonts you use, the harder the training. I >> would focus on very few fonts, even one. I would start with exactly one >> font and train on these to see quickly if my training setup/pipeline is >> working. And if the training results reflect onto the diagrams later. If >> the model error rate is good on the individual text lines and it is bad on >> the real images it might be a segmentation problem that training cannot >> fix. Or the problem might be the external box, that I suppose you do not >> have in your generated data. >> >> Ideally, I would use real crops from these diagrams rather than images >> from text2image. >> >> Also distinguishing 0 from O with many fonts is very hard. Often you have >> domain knowledge that can help you to fix these errors in post, for example >> 0,O5 can be easily spotted and fixed. You can, for example, assume that >> each box contains only one kind of data and guess the most likely one from >> this or from the box sequence, etc. >> >> I got good results with 20k samples (real world scanned docs, multi >> fonts). 10k seems reasonable, I also assume your output "characters set" is >> very small, like the numbers and a few capital letters and a couple of >> symbols (no %, ^, &, {, etc.). >> >> >> >> Lorenzo >> >> Il giorno gio 23 nov 2023 alle ore 10:16 Simon <smon...@gmail.com> ha >> scritto: >> >>> If I need to train new characters that are not recognized by a default >>> model, is fine tuning in this case the right approach? >>> One of these characters ist the one for angularity: ∠ >>> >>> This symbols appear in technical drawings and should be recognised in >>> those. E.g. for the scenario in the following picture tesseract should >>> reconize this symbol. >>> >>> >>> >>> [image: angularity.png] >>> >>> Also here is one of the pngs I tried to train with: >>> [image: angularity_0_r0.jpg] >>> They all look pretty similar to this one. Things that change are the >>> angle, the propotion and the thickness of the lines. All examples have this >>> 64x64 pixel box around it. >>> >>> >>> Is Fine Tuning for this scenario the right approach as I only find >>> information for fine tuning for specific fonts. For fine tune also the >>> "tesstrain" repository would not be needed as it is used for training from >>> scratch, correct? >>> desal...@gmail.com schrieb am Mittwoch, 22. November 2023 um 15:27:02 >>> UTC+1: >>> >>>> From my limited experience, you need a lot more data than that to train >>>> from scratch. If you can't make more than that data, you might first try to >>>> fine tune:and then train by removing the top layer of the best model. >>>> >>>> On Wednesday, November 22, 2023 at 4:46:53 PM UTC+3 smon...@gmail.com >>>> wrote: >>>> >>>>> As it is not properly possible to combine my traineddata from scratch >>>>> with an existing one, I have decided to also train my traineddata model >>>>> numbers. Therefore I wrote a script which synthetically generates >>>>> groundtruth data with text2image. >>>>> This script uses dozens of different fonts and creates numbers for the >>>>> following formats. >>>>> X.XXX >>>>> X.XX >>>>> X,XX >>>>> X,XXX >>>>> I generated 10,000 files to train the numbers. But unfortunately >>>>> numbers get recognized pretty poorly with the best model. (most of times >>>>> only "0."; "0" or "0," gets recognized) >>>>> So I wanted to ask if It is not enough training (ground truth data) >>>>> for proper recognition when I train several fonts. >>>>> Thanks in advance for you help. >>>>> >>>> -- >>> >> You received this message because you are subscribed to the Google Groups >>> "tesseract-ocr" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to tesseract-oc...@googlegroups.com. >>> >> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/tesseract-ocr/6a904604-f0b7-48ef-a4b2-cf1e97123041n%40googlegroups.com >>> <https://groups.google.com/d/msgid/tesseract-ocr/6a904604-f0b7-48ef-a4b2-cf1e97123041n%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- > You received this message because you are subscribed to the Google Groups > "tesseract-ocr" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to tesseract-ocr+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/tesseract-ocr/31d6a1f5-d114-485b-b6b3-897c57616783n%40googlegroups.com > <https://groups.google.com/d/msgid/tesseract-ocr/31d6a1f5-d114-485b-b6b3-897c57616783n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "tesseract-ocr" group. To unsubscribe from this group and stop receiving emails from it, send an email to tesseract-ocr+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/tesseract-ocr/CAMgOLLw5NG4Tr5NB%3DvWG_AG75_oM_J1odD_%3DogCv04LKtd5eBA%40mail.gmail.com.
''' Created on May 16, 2018 @author: trz ''' import logging import sys import time import tesserocr from collections import deque from multiprocessing import Lock from tesserocr import PyTessBaseAPI, RIL, iterate_level from operator import itemgetter import cv2 import numpy as np # DEFAULT_LANG="ita15kf" # DEFAULT_LANG="elett_16000" DEFAULT_LANG = "eng" colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] yellow = (255, 255, 0) magenta = (255, 0, 255) gray = (100, 100, 100) DEBUG = False def recognize_text(raw_img): lang = DEFAULT_LANG psm_mode = tesserocr.PSM.SINGLE_BLOCK api = PyTessBaseAPI(lang=lang) logging.info("Tesseract version %s", api.Version()) api.Init(lang=lang) #api.SetPageSegMode(psm_mode) # single line api.SetImageBytes(raw_img.tobytes(), raw_img.shape[1], raw_img.shape[0], 1, raw_img.shape[1]) api.Recognize() ri = api.GetIterator() prev_symbol_end = -1 prev_symbol = None draw_img = cv2.cvtColor(raw_img, cv2.COLOR_GRAY2BGR) res = "" for i, r in enumerate(iterate_level(ri, RIL.SYMBOL)): symbolBounds = r.BoundingBox(RIL.SYMBOL) conf = r.Confidence(RIL.SYMBOL) new_word = r.IsAtBeginningOf(RIL.WORD) new_line = r.IsAtBeginningOf(RIL.TEXTLINE) #print("NW/NL", new_word, new_line) if new_word: res += " " if new_line: res += "\n" if symbolBounds is None: print("symbolBounds is None", conf) continue symbol = r.GetUTF8Text(RIL.SYMBOL) res += symbol cv2.rectangle(draw_img, (symbolBounds[0], symbolBounds[1]), (symbolBounds[2], symbolBounds[3]), colors[i % 3]) if i % 2 == 0: cv2.rectangle(draw_img, (symbolBounds[0], 0), (symbolBounds[2], 1), yellow, 2) else: cv2.rectangle(draw_img, (symbolBounds[0], draw_img.shape[0] - 2), (symbolBounds[2], draw_img.shape[0] - 2), magenta, 2) # space between symbols curr_symbol_start = symbolBounds[0] if prev_symbol_end == -1: space_between_symbols = 0 else: space_between_symbols = curr_symbol_start - prev_symbol_end print("From", prev_symbol, "to", symbol, space_between_symbols) symbol_h = symbolBounds[3] - symbolBounds[1] half_h = symbol_h // 2 + symbolBounds[1] th = 12 color = (200,200,200) if space_between_symbols < th else (0, 200, 0) #cv2.rectangle(draw_img, (prev_symbol_end, half_h-2), (curr_symbol_start, half_h+2), # color, -1) prev_symbol_end = symbolBounds[2] prev_symbol = symbol print(res) #cv2.imwrite("boxes.jpg", draw_img) cv2.imshow("ocr boxes", draw_img) cv2.waitKey(0) if __name__ == '__main__': logger = logging.getLogger() logger.setLevel(logging.DEBUG) filename = sys.argv[1] img = cv2.imread(filename, 0) res = recognize_text(img)