ओसीआर के लिए सफाई छवि


9

मैं ओसीआर के लिए छवियों को साफ करने की कोशिश कर रहा हूं: (लाइनें)

यहां छवि विवरण दर्ज करें

मुझे कभी-कभी छवि को आगे बढ़ाने के लिए इन पंक्तियों को हटाने की आवश्यकता होती है और मैं बहुत करीब हो रहा हूं, लेकिन बहुत बार थ्रेसहोल्ड पाठ से बहुत दूर ले जाता है:

    copy = img.copy()
    blur = cv2.GaussianBlur(copy, (9,9), 0)
    thresh = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,11,30)

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
    dilate = cv2.dilate(thresh, kernel, iterations=2)

    cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]

    for c in cnts:
        area = cv2.contourArea(c)
        if area > 300:
            x,y,w,h = cv2.boundingRect(c)
            cv2.rectangle(copy, (x, y), (x + w, y + h), (36,255,12), 3)

संपादित करें: इसके अतिरिक्त, निरंतर संख्याओं का उपयोग करने से फ़ॉन्ट में बदलाव नहीं होगा। क्या ऐसा करने का कोई सामान्य तरीका है?


2
इनमें से कुछ पंक्तियाँ, या उनके टुकड़े, कानूनी पाठ जैसी ही विशेषताएँ हैं, और मान्य पाठ को बिगाड़े बिना उनसे छुटकारा पाना मुश्किल होगा। यदि यह लागू होता है, तो आप उन तथ्यों पर ध्यान केंद्रित कर सकते हैं जो वे पात्रों की तुलना में लंबे हैं, और कुछ अलग-थलग हैं। तो एक पहला कदम वर्णों के आकार और निकटता का अनुमान लगा सकता है।
यवेस डेव

@YvesDaoust पात्रों की निकटता का पता लगाने के बारे में कैसे जाना जाएगा? (चूंकि आकार पर विशुद्ध रूप से छानने से पात्रों के साथ बहुत समय तक
घुल

1
आप पा सकते हैं, हर बूँद के लिए, अपने निकटतम पड़ोसी से दूरी के लिए। फिर दूरी के हिस्टोग्राम विश्लेषण से, आपको "करीब" और "अलग" (वितरण के मोड की तरह कुछ), या "घिरे" और "पृथक" के बीच एक सीमा मिलेगी।
यवेस डाएक्ट

एक दूसरे के पास कई छोटी रेखाओं के मामले में उनके निकटतम पड़ोसी अन्य छोटी रेखा नहीं होंगे? क्या अन्य सभी ब्लब्स की औसत दूरी की गणना करना बहुत महंगा होगा?
K41F4r

"उनके निकटतम पड़ोसी अन्य छोटी रेखा नहीं होंगे?": अच्छी आपत्ति, आपका सम्मान। वास्तव में करीब छोटे खंडों का एक गुच्छा कानूनी पाठ से भिन्न नहीं होता है, हालांकि पूरी तरह से अप्रत्याशित व्यवस्था में। आपको टूटी लाइनों के टुकड़ों को फिर से इकट्ठा करना पड़ सकता है। मुझे यकीन नहीं है कि सभी के लिए औसत दूरी आपको बचाएगी।
Yves Daoust

जवाबों:


14

यहाँ एक विचार है। हम इस समस्या को कई चरणों में तोड़ते हैं:

  1. औसत आयताकार समोच्च क्षेत्र निर्धारित करें। हम फिर समोच्च का पता लगाते हैं और समोच्च के आयत क्षेत्र का उपयोग करके फ़िल्टर करते हैं । हम ऐसा करते हैं इसका कारण यह है कि कोई भी विशिष्ट चरित्र केवल इतना बड़ा होगा जबकि बड़ा शोर बड़े आयताकार क्षेत्र को फैलाएगा। हम तब औसत क्षेत्र निर्धारित करते हैं।

  2. बड़े बाहरी रूपरेखा निकालें। हम फिर से आकृति के माध्यम से पुनरावृत्ति करते हैं और बड़े समोच्चों को हटा देते हैं यदि वे 5xसमोच्च में भरकर औसत समोच्च क्षेत्र से बड़े होते हैं । एक निश्चित सीमा क्षेत्र का उपयोग करने के बजाय, हम इस गतिशील सीमा का उपयोग अधिक मजबूती के लिए करते हैं।

  3. वर्णों को जोड़ने के लिए एक ऊर्ध्वाधर कर्नेल के साथ पतला । विचार अवलोकन का लाभ उठाता है कि कॉलम में अक्षर संरेखित किए जाते हैं। एक ऊर्ध्वाधर कर्नेल के साथ पतला करके हम पाठ को एक साथ जोड़ते हैं ताकि शोर इस संयुक्त समोच्च में शामिल नहीं होगा।

  4. छोटा शोर निकालें । अब जबकि रखने के लिए पाठ जुड़ा हुआ है, हम आकृति पाते हैं और 4xऔसत समोच्च क्षेत्र की तुलना में किसी भी आकृति को हटाते हैं।

  5. बिटवाइज़-और छवि का पुनर्निर्माण करने के लिए । चूंकि हमारे पास अपने मुखौटे को रखने के लिए केवल वांछित आकृति हैं, हम बिटवाइज़-और पाठ को संरक्षित करने और अपना परिणाम प्राप्त करने के लिए।


यहाँ प्रक्रिया का एक दृश्य है:

हम ओत्सु की दहलीज एक द्विआधारी छवि प्राप्त करते हैं फिर औसत आयताकार समोच्च क्षेत्र निर्धारित करने के लिए आकृति पाते हैं। यहाँ से हम से हरे रंग में हाइलाइट बड़े बाहरी आकृति को दूर आकृति भरने

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें

हम एक निर्माण अगला खड़ी गिरी और फैलने पात्रों कनेक्ट करने के लिए। यह कदम शोर को अलग-अलग बूँद में रखने और अलग करने के लिए सभी वांछित पाठ को जोड़ता है।

यहां छवि विवरण दर्ज करें

अब हम छोटे शोर को दूर करने के लिए समोच्च क्षेत्र का उपयोग करके समोच्च और फ़िल्टर पाते हैं

यहां छवि विवरण दर्ज करें

यहां सभी हटाए गए शोर कणों को हरे रंग में हाइलाइट किया गया है

यहां छवि विवरण दर्ज करें

परिणाम

यहां छवि विवरण दर्ज करें

कोड

import cv2

# Load image, grayscale, and Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Determine average contour area
average_area = [] 
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    area = w * h
    average_area.append(area)

average = sum(average_area) / len(average_area)

# Remove large lines if contour area is 5x bigger then average contour area
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    x,y,w,h = cv2.boundingRect(c)
    area = w * h
    if area > average * 5:  
        cv2.drawContours(thresh, [c], -1, (0,0,0), -1)

# Dilate with vertical kernel to connect characters
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,5))
dilate = cv2.dilate(thresh, kernel, iterations=3)

# Remove small noise if contour area is smaller than 4x average
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    area = cv2.contourArea(c)
    if area < average * 4:
        cv2.drawContours(dilate, [c], -1, (0,0,0), -1)

# Bitwise mask with input image
result = cv2.bitwise_and(image, image, mask=dilate)
result[dilate==0] = (255,255,255)

cv2.imshow('result', result)
cv2.imshow('dilate', dilate)
cv2.imshow('thresh', thresh)
cv2.waitKey()

नोट: पारंपरिक छवि प्रसंस्करण थ्रेसहोल्ड, रूपात्मक संचालन और समोच्च फ़िल्टरिंग (समोच्च सन्निकटन, क्षेत्र, पहलू अनुपात या बूँद का पता लगाने) तक सीमित है। चूंकि इनपुट चित्र वर्ण पाठ आकार के आधार पर भिन्न हो सकते हैं, एक विलक्षण समाधान खोजना काफी कठिन है। आप एक गतिशील समाधान के लिए मशीन / गहन सीखने के साथ अपने स्वयं के क्लासिफायरियर प्रशिक्षण में देखना चाहते हैं।


1
एक बड़े फ़ॉन्ट के मामले में यह पाठ को नष्ट नहीं करेगा?
K41F4r

हां, यह हो सकता है, इसलिए आपको दहलीज क्षेत्र मान को समायोजित करना होगा। अधिक गतिशील दृष्टिकोण के लिए एक विचार औसत चरित्र क्षेत्र को निर्धारित करने के लिए है, तो इसका उपयोग उस सीमा के रूप में करें
nathancy

उदाहरण के लिए बहुत विशिष्ट लगता है, औसत क्षेत्र का उपयोग करके अभी भी पाठ को बहुत समय नष्ट कर दिया जाएगा जो ओसीआर के लिए परिणाम को खराब करता है
K41F4r

क्या आपके पास एक और उदाहरण इनपुट छवि है जिसे आप पोस्ट में जोड़ सकते हैं?
नौ

1
एक समाधान खोजना जो पारंपरिक छवि प्रसंस्करण तकनीकों का उपयोग करके सभी स्थितियों में काम करता है, काफी मुश्किल है। आप गहरी शिक्षा का उपयोग करके अपने स्वयं के क्लासिफायरशिप प्रशिक्षण में देखना चाहते हैं। सौभाग्य!
नथनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.