تحويل النص غير المنظم بتقنية التعرف الضوئي على الحروف (OCRed) إلى نص مناسب

StackOverflow https://stackoverflow.com//questions/22039207

سؤال

أنا أستخدم مايكروسوفت MODI في VB6 للتعرف الضوئي على الحروف (OCR) على الصورة.(أعرف أدوات التعرف الضوئي على الحروف الأخرى مثل tesseract وما إلى ذلك ولكني أجد MODI أكثر دقة من غيرها)

الصورة المراد التعرف عليها ضوئيًا هي هكذا

enter image description here

والنص الذي أحصل عليه بعد التعرف الضوئي على الحروف هو كما يلي

Text1
Text2
Text3
Number1
Number2
Number3

المشكلة هنا هي أنه لا يتم الاحتفاظ بالنص المقابل من العمود المقابل.كيف يمكنني تعيين Number1 مع Text1؟

لا أستطيع إلا أن أفكر في حل مثل هذا.

يوفر MODI إحداثيات جميع كلمات التعرف الضوئي على الحروف مثل هذه

LeftPos = Img.Layout.Words(0).Rects(0).Left
TopPos = Img.Layout.Words(0).Rects(0).Top

لذا، لمحاذاة الكلمات في نفس السطر، يمكننا مطابقة TopPos لكل كلمة ثم فرزها حسب LeftPos.سوف نحصل على الخط الكامل.لذلك قمت بتكرار كل الكلمات وقمت بتخزين نصها وكذلك اليسار والأعلى في جدول MySQL.ثم قام بتشغيل هذا الاستعلام

SELECT group_concat(word ORDER BY `left` SEPARATOR ' ')
FROM test_copy
GROUP BY `top`

مشكلتي هي أن المواضع العليا ليست متماثلة تمامًا لكل كلمة، ومن الواضح أنه سيكون هناك بعض الاختلافات في البكسل.

حاولت الإضافة DIV 5, ، لدمج الكلمات الموجودة في نطاق 5 بكسل ولكن هذا لا يعمل في بعض الحالات.لقد حاولت أيضًا القيام بذلك في Node.js عن طريق حساب التسامح لكل كلمة ثم الفرز حسب LeftPos ولكني ما زلت أشعر أن هذه ليست أفضل طريقة للقيام بذلك.

تحديث: يقوم كود js بالمهمة ولكن باستثناء الحالة التي يكون فيها اختلاف Number1 بمقدار 5 بكسل ولا يوجد لدى Text2 أي مقابل في هذا السطر.

هل هناك أي فكرة أفضل للقيام بذلك؟

هل كانت مفيدة؟

المحلول

لست متأكدًا بنسبة 100% من كيفية تحديد تلك الكلمات الموجودة في العمود "الأيسر"، ولكن بمجرد تحديد هذه الكلمة، يمكنك العثور على كلمات أخرى في السطر من خلال عرض ليس فقط الإحداثي العلوي ولكن المستطيل بأكمله عبر ( العلوي والسفلي).تحديد التداخل (التقاطع) مع الكلمات الأخرى.لاحظ المنطقة المميزة باللون الأحمر أدناه.

Horizontal projection

هذا هو التسامح الذي يمكنك استخدامه لاكتشاف ما إذا كان هناك شيء ما في نفس السطر.إذا تداخل شيء ما ببكسل واحد فقط، فمن المحتمل أن يكون من خط أقل أو أعلى.ولكن إذا تداخل، على سبيل المثال، بنسبة 50% أو أكثر من ارتفاع النص 1، فمن المحتمل أن يكون على نفس السطر.


مثال SQL للعثور على جميع الكلمات في "السطر" استنادًا إلى التنسيق العلوي والسفلي

select 
    word.id, word.Top, word.Left, word.Right, word.Bottom 
from 
    word
where 
    (word.Top >= @leftColWordTop and word.Top <= @leftColWordBottom)
    or (word.Bottom >= @leftColWordTop  and word.Bottom <= @leftColWordBottom)

مثال على كود psuedo VB6 لحساب الخطوط أيضًا.

'assume words is a collection of WordInfo objects with an Id, Top, 
'   Left, Bottom, Right properties filled in, and a LineAnchorWordId 
'   property that has not been set yet.

'get the words in left-to-right order
wordsLeftToRight = SortLeftToRight(words) 

'also get the words in top-to-bottom order
wordsTopToBottom = SortTopToBottom(words) 

'pass through identifying a line "anchor", that being the left-most 
'   word that starts (and defines) a line
for each anchorWord in wordsLeftToRight

    'check if the word has been mapped to aline yet by checking if 
    '   its anchor property has been set yet.  This assumes 0 is not 
    '   a valid id, use -1 instead if needed
    if anchorWord.LineAnchorWordId = 0 then 

        'not locate every word on this line, as bounded by the 
        '   anchorWord.  every word determined to be on this line 
        '   gets its LineAnchorWordId property set to the Id of the 
        '   anchorWord
        for each lineWord in wordsTopToBottom

            if lineWord.Bottom < anchorWord.Top Then

                'skip it,it is above the line (but keep searching down
                '   because we haven't reached the anchorWord location yet)

            else if lineWord.Top > anchorWord.Bottom Then

                'skip it,it is below the line, and exit the search 
                '   early since all the rest will also be below the line
                exit for

            else if OverlapsWithinTolerance(anchorWord, lineWord) then

                lineWord.LineAnchorWordId = anchorWord.Id

            endif

        next

    end if

next anchorWord

'at this point, every word has been assigned a LineAnchorWordId, 
'   and every word on the same line will have a matching LineAnchorWordId
'   value.  If stored in a DB you can now group them by LineAnchorWordId 
' and sort them by their Left coord to get your output.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top