
बस दूसरे दिन मुझे चित्र में सरल पाठ को पहचानने की आवश्यकता थी और मेरे एल्गोरिथ्म को लागू करने की बिल्कुल इच्छा नहीं थी, क्योंकि मैं सिद्धांत से परिचित हूं और मुझे पता है कि यह इतना आसान मामला नहीं है, इसलिए मैंने तुरंत तैयार पुस्तकालय के लिए बाजार का अध्ययन करने का फैसला किया। Google को बस कुछ अनुरोध और मुझे एहसास हुआ कि tessnet2 पुस्तकालय के रूप में मेरे लिए अधिक उपयुक्त कुछ भी नहीं मिल सकता है। मैंने लगातार हबर को पढ़ा और मुझे पता है कि ओसीआर के सिद्धांत पर बहुत सारे लेख हैं और मुझे बहुत आश्चर्य हुआ कि tessnet2 पुस्तकालय के बारे में कुछ भी नहीं है।
tessnet2 Tesseract OCR पर आधारित है
टेसरेक्ट ओसीआर इंजन यूएनएलवी एक्यूरेसी टेस्ट में 1995 में शुरू किए गए 3 सर्वश्रेष्ठ इंजनों में से एक था। 1995 से 2006 के बीच, इसे थोड़ा संशोधित किया गया था, लेकिन यह संभवतः खुले स्रोत पर उपलब्ध सबसे सटीक ओसीआर इंजनों में से एक है। जो कोड उपलब्ध है, वह बाइनरी, ग्रे या कलर इमेज और डिस्प्ले टेक्स्ट को पढ़ेगा। TIFF रीडिंग डिज़ाइन की गई है ताकि असम्पीडित TIFF छवियां पढ़ी जा सकें, या Libtiff को संपीड़ित चित्र पढ़ने के लिए जोड़ा जा सके।
Tessnet2 का उपयोग कैसे करें:
1. डाउनलोड करें
पुस्तकालय , .NET प्रोजेक्ट में
Tessnet2.dll के लिए लिंक (संदर्भ) जोड़ें।
2. हमें जिस भाषा की आवश्यकता है उसे डाउनलोड करें (मुझे व्यक्तिगत रूप से अंग्रेजी की आवश्यकता है) (
tesseract-2.00.eng.tar.gz ) और इसे tessdata फ़ोल्डर में डालें। टेसडेटा फ़ोल्डर हमारे एप्लिकेशन की निष्पादन योग्य फ़ाइल के बगल में होना चाहिए।
चित्र से पाठ पढ़ने के लिए, ऐसा पाठ पर्याप्त है:
Bitmap image = new Bitmap ( "eurotext.tif" );
tessnet2.Tesseract ocr = new tessnet2.Tesseract();
ocr.SetVariable( "tessedit_char_whitelist" , "0123456789" ); // If digit only
ocr.Init( @"c:\temp" , " eng " , false ); // To use correct tessdata
List <tessnet2.Word> result = ocr.DoOCR(image, Rectangle.Empty);
foreach (tessnet2.Word word in result)
Console .WriteLine( "{0} : {1}" , word.Confidence, word.Text);
* This source code was highlighted with Source Code Highlighter .
मैं परिणाम से बहुत खुश था, इसलिए मुझे तुरंत याद आया कि मैंने एक परियोजना के लिए कैप्चा को हल करने के लिए कई महीने पहले एक सेवा शुरू की है, मैं तुरंत कहूंगा कि इससे अच्छा कुछ नहीं आया, मुझे वहां गति की आवश्यकता थी, लेकिन मैं इसे वहां नहीं कर सकता था, टी। एक। ऐसी सेवाएं इसे प्रदान करने में सक्षम नहीं हैं, और परिणाम आमतौर पर बहुत ही निराशाजनक है, यह समझ में आता है, क्योंकि उन्होंने $ 1 के लिए $ 1 से सही ढंग से कैप्चा में प्रवेश किया, जो कम से कम कहने के लिए भयानक है। इसलिए, प्रयोग के लिए, मैंने उस उदाहरण का उपयोग करके इस लाइब्रेरी के साथ खेलने का फैसला किया।
हमारे लिए प्रारंभिक डेटा एक कैप्चा होगा, जिस पर हमें दो नंबरों पर सरल क्रियाएं करने और उत्तर प्राप्त करने की आवश्यकता है। यह बहुत सरल लगता है, लेकिन समस्या यह है कि सभी प्रतीक अलग-अलग रंगों के हैं और एक गतिशील पृष्ठभूमि है, कभी-कभी मेरे लिए (व्यक्ति) को समझना मुश्किल है कि वहां क्या लिखा गया है।
तुरंत मैं कार्यक्रम के परिणाम लाता हूं, जिसके बाद मैं आपको बताऊंगा कि यह कैसे काम करता है:





स्क्रीनशॉट में स्पष्ट रूप से दिखाया गया है कि लाइनों के एक समूह की वजह से पुस्तकालय कुछ भी हल नहीं कर सकता है, कभी-कभी पृष्ठभूमि, जिसे पूरी तरह से हटाया नहीं गया था, भी स्थगित हो जाता है। इसलिए, मैंने चित्र को साफ करने के लिए अपना छोटा एल्गोरिथ्म विकसित किया है, इसमें कुछ भी भव्य नहीं है, मैं किनारे से कुछ पिक्सेल पीछे हटता हूं और आयत के माध्यम से चलता हूं और वहां रंग जमा करता हूं, पहले अंक के बाद रंग भी जमा करता हूं और संकेत से पहले (बाद वाला हैक के अधिक है, लेकिन टी। .k। लेख दूसरे के लिए समर्पित है, फिर इसे उसी तरह छोड़ दिया)। मुझे केवल इतना करना है कि मेरे संग्रह में आए सभी रंगों पर पेंट करें और सफेद न हों।
सभी एल्गोरिदम में, केवल बिटमैप पर एल्गोरिथ्म भरने वाला क्षेत्र सबसे उपयोगी हो सकता है:
void FloodFill( Bitmap bitmap, int x, int y, Color color)
{
BitmapData data = bitmap.LockBits(
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
int [] bits = new int [data.Stride / 4 * data.Height];
Marshal.Copy(data.Scan0, bits, 0, bits.Length);
LinkedList<Point> check = new LinkedList<Point>();
int floodTo = color.ToArgb();
int floodFrom = bits[x + y * data.Stride / 4];
bits[x + y * data.Stride / 4] = floodTo;
if (floodFrom != floodTo)
{
check.AddLast( new Point(x, y));
while (check.Count > 0)
{
Point cur = check.First.Value;
check.RemoveFirst();
foreach (Point off in new Point[] {
new Point(0, -1), new Point(0, 1),
new Point(-1, 0), new Point(1, 0)})
{
Point next = new Point(cur.X + off.X, cur.Y + off.Y);
if (next.X >= 0 && next.Y >= 0 &&
next.X < data.Width &&
next.Y < data.Height)
{
if (bits[next.X + next.Y * data.Stride / 4] == floodFrom)
{
check.AddLast(next);
bits[next.X + next.Y * data.Stride / 4] = floodTo;
}
}
}
}
}
Marshal.Copy(bits, 0, data.Scan0, bits.Length);
bitmap.UnlockBits(data);
}
}
* This source code was highlighted with Source Code Highlighter .
उन लोगों के लिए जो प्रयोग करने में रुचि रखते हैं, मैं
स्रोत कोड संलग्न करता हूं।
परिणाम
हम एक दिलचस्प tessnet2 पुस्तकालय से परिचित हो गए, वास्तविक परिस्थितियों में इसके संचालन की जांच की, जटिल चित्रों (कैप्चा) के लिए बहुत अच्छे समाधान परिणाम प्राप्त किए, बेशक इसमें त्रुटियां हैं, लेकिन उनकी संख्या नगण्य है, खासकर इस प्रकार के कैप्चा के लिए आप नियमित अभिव्यक्ति का उपयोग करके एक चेक जोड़ सकते हैं और आप यह सुनिश्चित करने के लिए जान जाएंगे कि अप्रकाशित पाठ वांछित प्रारूप से मेल खाता है।