การประมวลผลภาพเพื่อปรับปรุงความถูกต้องของ tesseract OCR


145

ฉันใช้ tesseract เพื่อแปลงเอกสารเป็นข้อความ คุณภาพของเอกสารอยู่ในช่วงที่ดุเดือดและฉันกำลังมองหาเคล็ดลับเกี่ยวกับการประมวลผลภาพประเภทใดที่อาจปรับปรุงผลลัพธ์ ฉันสังเกตเห็นว่าข้อความที่มีการจัดเรียงสูง - ตัวอย่างเช่นที่สร้างขึ้นโดยเครื่องแฟกซ์ - เป็นเรื่องยากโดยเฉพาะอย่างยิ่งสำหรับ tesseract ในการประมวลผล - สันนิษฐานว่าขอบหยักเหล่านี้กับตัวอักษรทำให้เกิดความสับสนในอัลกอริทึมการจดจำรูปร่าง

เทคนิคการประมวลผลภาพแบบใดที่จะปรับปรุงความแม่นยำ ฉันใช้การเบลอแบบเกาส์เพื่อปรับภาพที่มีตัวอักษรให้เรียบและเห็นการปรับปรุงเล็กน้อย แต่ฉันหวังว่าจะมีเทคนิคเฉพาะที่จะให้ผลลัพธ์ที่ดีกว่า พูดฟิลเตอร์ที่ปรับให้เป็นภาพขาวดำซึ่งจะทำให้ขอบที่ไม่สม่ำเสมอนั้นราบเรียบตามด้วยฟิลเตอร์ที่จะเพิ่มความคมชัดเพื่อทำให้ตัวละครมีความชัดเจนยิ่งขึ้น

มีคำแนะนำทั่วไปสำหรับคนที่เป็นมือใหม่ในการประมวลผลภาพหรือไม่?

คำตอบ:


103
  1. แก้ไข DPI (ถ้าจำเป็น) 300 DPI ขั้นต่ำ
  2. ขนาดตัวอักษรแก้ไข (เช่น 12 pt ควรเป็น ok)
  3. พยายามแก้ไขบรรทัดข้อความ (เท็กซ์เดสก์และดิวarp)
  4. พยายามแก้ไขความสว่างของภาพ (เช่นไม่มีส่วนที่มืดของภาพ)
  5. ภาพสองทางและเสียงรบกวน

ไม่มีบรรทัดคำสั่งสากลที่เหมาะกับทุกกรณี (บางครั้งคุณจำเป็นต้องทำให้ภาพเบลอและคมชัดขึ้น) แต่คุณสามารถให้ลองไปTEXTCLEANER จากเฟร็ดคริป

หากคุณไม่ได้เป็นแฟนของบรรทัดคำสั่งบางทีคุณอาจจะพยายามที่จะใช้ opensource scantailor.sourceforge.netหรือการค้าbookrestorer


6
และมีคู่มือภาพประกอบเกี่ยวกับวิธีการทำเช่นนี้: code.google.com/p/tesseract-ocr/wiki/ImproveQuality
iljau

2
หมายเหตุสคริปต์ที่เชื่อมโยงนั้นดูเหมือนว่าจะเป็นลินุกซ์เท่านั้น
Zoran Pavlovic

1
นี่ไม่ใช่ความจริง - นี่คือสคริปต์ทุบตี หากคุณได้ติดตั้ง bash และ ImageMagick มันจะทำงานบน windows เช่นกัน Bash สามารถติดตั้งเป็นส่วนหนึ่งของซอฟต์แวร์ที่มีประโยชน์อื่น ๆ เช่นgitหรือmsys2 ...
user898678

6
@iljau ตั้งแต่ย้ายมาที่ github หน้า wiki อยู่ที่: github.com/tesseract-ocr/tesseract/wiki/ImproveQuality
hometoast

2
เอกสาร Tesseract ย้ายอีกครั้งไปยังtesseract-ocr.github.io/tessdoc/ImproveQuality
ไม่มีใคร

73

ฉันไม่เคยเป็นผู้เชี่ยวชาญ OCR แต่ฉันในสัปดาห์นี้จำเป็นต้องแปลงข้อความเป็น jpg

ฉันเริ่มด้วยสี jpg RGB 445x747 พิกเซล ฉันลองใช้ tesseract ทันทีและโปรแกรมก็แทบไม่แปลงเลย จากนั้นฉันไปที่ GIMP และทำสิ่งต่อไปนี้ ภาพ> โหมด> ภาพระดับสีเทา> ภาพสเกล> ตัวกรอง 1191x2000 พิกเซล> ปรับปรุง> มาสก์ที่ไม่ชัดด้วยค่ารัศมี = 6.8, จำนวน = 2.69, ขีด จำกัด = 0 ฉันบันทึกเป็น jpg ใหม่ที่คุณภาพ 100%

จากนั้น Tesseract ก็สามารถที่จะแยกข้อความทั้งหมดเป็นไฟล์. txt

Gimp เป็นเพื่อนของคุณ


11
+1 ฉันทำตามขั้นตอนของคุณและฉันได้รับการปรับปรุงอย่างมาก ขอบคุณ
onof

1
ฉันยังรู้สึกว่า Tesseract ทำงานได้ดีขึ้นหากคุณแปลงอินพุตเป็นไฟล์ TIFF และให้ Tesseract เป็น TIFF (แทนที่จะขอให้ Tesseract ทำการแปลงให้คุณ) ImageMagick สามารถทำการแปลงให้คุณ นี่คือความประทับใจเล็กน้อยของฉัน แต่ฉันไม่ได้ทดสอบอย่างรอบคอบดังนั้นอาจผิด
DW

+1 ตัวกรอง "หน้ากากที่ไม่ชัด" ทำให้วันของฉันเป็นจริงได้ อีกขั้นตอนที่ช่วยฉัน: การใช้เครื่องมือ "เลือกฟัซซี" เลือกพื้นหลังแล้วกด Del เพื่อเพิ่มมันออกมา
Davide

ฉันติดอยู่กับปัญหาการประมวลผลภาพนี้ก่อนที่ tesseract recognition stackoverflow.com/questions/32473095/…คุณสามารถช่วยฉันออกจากที่นี่ได้หรือไม่?
ฮุสเซน

Nope ฉันพยายามทำให้มันมีขนาดใหญ่ขึ้นและกำหนดให้เป็นเฉดสีเทาดูเหมือนว่าไม่มีอะไรจะให้ผลลัพธ์ที่ดี ถอนหายใจ :( ตรวจสอบเป้าหมายนี้: freesms4us.com/…
gumuruh

30

สามจุดเพื่อปรับปรุงความสามารถในการอ่านของภาพ: 1) ปรับขนาดภาพด้วยความสูงและความกว้างของตัวแปร (คูณ 0.5 และ 1 และ 2 ด้วยความสูงและความกว้างของภาพ) 2) แปลงภาพเป็นรูปแบบสเกลสีเทา (ขาวดำ) 3) ลบพิกเซลรบกวนและทำให้ชัดเจนยิ่งขึ้น (กรองภาพ)

ดูรหัสด้านล่าง:

//Resize
  public Bitmap Resize(Bitmap bmp, int newWidth, int newHeight)
        {

                Bitmap temp = (Bitmap)bmp;

                Bitmap bmap = new Bitmap(newWidth, newHeight, temp.PixelFormat);

                double nWidthFactor = (double)temp.Width / (double)newWidth;
                double nHeightFactor = (double)temp.Height / (double)newHeight;

                double fx, fy, nx, ny;
                int cx, cy, fr_x, fr_y;
                Color color1 = new Color();
                Color color2 = new Color();
                Color color3 = new Color();
                Color color4 = new Color();
                byte nRed, nGreen, nBlue;

                byte bp1, bp2;

                for (int x = 0; x < bmap.Width; ++x)
                {
                    for (int y = 0; y < bmap.Height; ++y)
                    {

                        fr_x = (int)Math.Floor(x * nWidthFactor);
                        fr_y = (int)Math.Floor(y * nHeightFactor);
                        cx = fr_x + 1;
                        if (cx >= temp.Width) cx = fr_x;
                        cy = fr_y + 1;
                        if (cy >= temp.Height) cy = fr_y;
                        fx = x * nWidthFactor - fr_x;
                        fy = y * nHeightFactor - fr_y;
                        nx = 1.0 - fx;
                        ny = 1.0 - fy;

                        color1 = temp.GetPixel(fr_x, fr_y);
                        color2 = temp.GetPixel(cx, fr_y);
                        color3 = temp.GetPixel(fr_x, cy);
                        color4 = temp.GetPixel(cx, cy);

                        // Blue
                        bp1 = (byte)(nx * color1.B + fx * color2.B);

                        bp2 = (byte)(nx * color3.B + fx * color4.B);

                        nBlue = (byte)(ny * (double)(bp1) + fy * (double)(bp2));

                        // Green
                        bp1 = (byte)(nx * color1.G + fx * color2.G);

                        bp2 = (byte)(nx * color3.G + fx * color4.G);

                        nGreen = (byte)(ny * (double)(bp1) + fy * (double)(bp2));

                        // Red
                        bp1 = (byte)(nx * color1.R + fx * color2.R);

                        bp2 = (byte)(nx * color3.R + fx * color4.R);

                        nRed = (byte)(ny * (double)(bp1) + fy * (double)(bp2));

                        bmap.SetPixel(x, y, System.Drawing.Color.FromArgb
                (255, nRed, nGreen, nBlue));
                    }
                }



                bmap = SetGrayscale(bmap);
                bmap = RemoveNoise(bmap);

                return bmap;

        }


//SetGrayscale
  public Bitmap SetGrayscale(Bitmap img)
        {

            Bitmap temp = (Bitmap)img;
            Bitmap bmap = (Bitmap)temp.Clone();
            Color c;
            for (int i = 0; i < bmap.Width; i++)
            {
                for (int j = 0; j < bmap.Height; j++)
                {
                    c = bmap.GetPixel(i, j);
                    byte gray = (byte)(.299 * c.R + .587 * c.G + .114 * c.B);

                    bmap.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
                }
            }
            return (Bitmap)bmap.Clone();

        }
//RemoveNoise
   public Bitmap RemoveNoise(Bitmap bmap)
        {

            for (var x = 0; x < bmap.Width; x++)
            {
                for (var y = 0; y < bmap.Height; y++)
                {
                    var pixel = bmap.GetPixel(x, y);
                    if (pixel.R < 162 && pixel.G < 162 && pixel.B < 162)
                        bmap.SetPixel(x, y, Color.Black);
                    else if (pixel.R > 162 && pixel.G > 162 && pixel.B > 162)
                        bmap.SetPixel(x, y, Color.White);
                }
            }

            return bmap;
        }

ภาพเข้า
ภาพเข้า

ภาพส่งออก ภาพส่งออก


Yes.we ต้องผ่านพารามิเตอร์ที่จำเป็นในการปรับขนาดวิธีมันจะ preocess ปรับขนาด SetGrayscale และ RemoveNoise การดำเนินงานแล้วส่งกลับภาพที่มีการอ่านที่ดีขึ้น
Sathyaraj Palanisamy

พยายามใช้วิธีนี้กับชุดของไฟล์และเปรียบเทียบกับผลลัพธ์เริ่มต้น ในบางกรณีที่ จำกัด จะให้ผลลัพธ์ที่ดีกว่าส่วนใหญ่มีคุณภาพข้อความที่ส่งออกลดลงเล็กน้อย ดังนั้นมันจึงดูเหมือนโซลูชั่นสากล
Bryn

มันใช้งานได้ดีสำหรับฉัน แน่นอนว่ามันเป็นจุดเริ่มต้นสำหรับการประมวลผลภาพล่วงหน้าซึ่งจะลบจำนวนความซึ่งพูดพล่อยๆที่คุณได้รับกลับมาจาก Tesseract
ses

22

โดยทั่วไปฉันมักใช้เทคนิคการประมวลผลภาพล่วงหน้าดังต่อไปนี้โดยใช้ไลบรารี OpenCV:

  1. Rescaling ภาพ (ขอแนะนำถ้าคุณกำลังทำงานกับภาพที่มี DPI น้อยกว่า 300 dpi):

    img = cv2.resize(img, None, fx=1.2, fy=1.2, interpolation=cv2.INTER_CUBIC)
    
  2. การแปลงภาพเป็นโทนสีเทา:

    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
  3. การใช้การขยายและการพังทลายเพื่อลบเสียงรบกวน (คุณอาจเล่นกับขนาดเคอร์เนลขึ้นอยู่กับชุดข้อมูลของคุณ):

    kernel = np.ones((1, 1), np.uint8)
    img = cv2.dilate(img, kernel, iterations=1)
    img = cv2.erode(img, kernel, iterations=1)
    
  4. การใช้การเบลอซึ่งสามารถทำได้โดยใช้หนึ่งในบรรทัดต่อไปนี้ (ซึ่งแต่ละอันมีข้อดีและข้อเสียอย่างไรก็ตามตัวกรองเบลอเฉลี่ยและตัวกรองทวิภาคีมักจะทำงานได้ดีกว่าเบลอเกาส์):

    cv2.threshold(cv2.GaussianBlur(img, (5, 5), 0), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    
    cv2.threshold(cv2.bilateralFilter(img, 5, 75, 75), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    
    cv2.threshold(cv2.medianBlur(img, 3), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    
    cv2.adaptiveThreshold(cv2.GaussianBlur(img, (5, 5), 0), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)
    
    cv2.adaptiveThreshold(cv2.bilateralFilter(img, 9, 75, 75), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)
    
    cv2.adaptiveThreshold(cv2.medianBlur(img, 3), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)
    

เมื่อเร็ว ๆ นี้ฉันได้เขียนคำแนะนำง่ายๆเกี่ยวกับ Tesseract แต่ควรให้คุณเขียนสคริปต์ OCR แรกของคุณและกำจัดอุปสรรคที่ฉันพบเมื่อสิ่งต่าง ๆ ชัดเจนน้อยกว่าที่ฉันชอบในเอกสารประกอบ

ในกรณีที่คุณต้องการตรวจสอบพวกเขาที่นี่ฉันกำลังแบ่งปันลิงก์กับคุณ:


เหตุใดเราจึงแปลงภาพเป็นระดับสีเทา เพื่อให้มีความเฉพาะเจาะจงมากขึ้นฉันได้เห็นในกระบวนการตรวจจับภาพภาพจะถูกแปลงเป็นสเกลสีเทาก่อนจากนั้นจึง sobel-> MSER -> SWT คุณช่วยอธิบายได้ไหม ฉันใหม่ในฟิลด์ IP
OnePunchMan

สำหรับความเข้าใจของฉันมันขึ้นอยู่กับอัลกอริทึมซึ่งบางคนอาจไม่จำเป็นต้องแปลงเลย คิดว่าพิกเซลเป็นค่าสีที่จัดเก็บแบบดิจิทัลในกรณีของ RGB, แดง, เขียวและน้ำเงิน เมื่อพิกเซลถูกแปลงเป็นสเกล B / W แล้วอัลกอริทึมของคุณต้องทำงานใน 2 มิติเท่านั้นแทนที่จะเป็น 3 ซึ่งมาพร้อมกับข้อดีที่เห็นได้ชัดในความเร็วเมื่อใช้อัลกอริทึมของคุณกับพิกเซลทีละคน นอกจากนี้บางคนอาจบอกว่ามันง่ายกว่าที่จะลบจุดรบกวนและตรวจจับขอบบนภาพเมื่อมันถูกแปลงเป็นสีเทา
bkaankuguoglu

ขอบคุณสำหรับคำตอบ และเกี่ยวกับบล็อกของคุณคุณช่วยเขียนหนึ่งวิธีในการสร้าง OCR จากรอยขีดข่วนโดยใช้ TESSERACT สำหรับสคริปต์ที่ไม่ใช่ภาษาโรมัน ฉันมีการค้นหาทุกที่สิ่งที่ถูกต้องไม่ชัดเจน
OnePunchMan

16

นี้ค่อนข้างที่ผ่านมา แต่ก็ยังอาจมีประโยชน์

ประสบการณ์ของฉันแสดงให้เห็นว่าการปรับขนาดภาพในหน่วยความจำก่อนที่จะส่งผ่านไปยัง tesseract บางครั้งช่วยได้

ลองใช้โหมดการแก้ไขที่แตกต่างกัน โพสต์https://stackoverflow.com/a/4756906/146003ช่วยฉันได้มาก


15

สิ่งที่เป็นประโยชน์มากสำหรับฉันในวิธีนี้คือซอร์สโค้ดสำหรับโครงการ Capture2Text http://sourceforge.net/projects/capture2text/files/Capture2Text/

BTW: ความรุ่งโรจน์ของผู้สร้างสำหรับการแบ่งปันอัลกอริทึมที่เจ็บปวดเช่นนี้

ให้ความสนใจเป็นพิเศษกับไฟล์ Capture2Text \ SourceCode \ leptonica_util \ leptonica_util.c - นั่นคือสาระสำคัญของการประมวลผลภาพล่วงหน้าสำหรับยูทิลิตี้นี้

หากคุณจะรันไบนารีคุณสามารถตรวจสอบการแปลงภาพก่อน / หลังกระบวนการในโฟลเดอร์ Capture2Text \ Output \ Output

วิธีแก้ปัญหาที่กล่าวถึง PS ใช้ Tesseract สำหรับ OCR และ Leptonica สำหรับการประมวลผลล่วงหน้า


1
ขอบคุณสำหรับเครื่องมือ Capture2Text มันสมบูรณ์แบบแก้ปัญหา OCR ทั้งหมดในโครงการของฉัน!
Lê Quang Duy

12

Java version สำหรับโค้ด Sathyaraj ด้านบน:

// Resize
public Bitmap resize(Bitmap img, int newWidth, int newHeight) {
    Bitmap bmap = img.copy(img.getConfig(), true);

    double nWidthFactor = (double) img.getWidth() / (double) newWidth;
    double nHeightFactor = (double) img.getHeight() / (double) newHeight;

    double fx, fy, nx, ny;
    int cx, cy, fr_x, fr_y;
    int color1;
    int color2;
    int color3;
    int color4;
    byte nRed, nGreen, nBlue;

    byte bp1, bp2;

    for (int x = 0; x < bmap.getWidth(); ++x) {
        for (int y = 0; y < bmap.getHeight(); ++y) {

            fr_x = (int) Math.floor(x * nWidthFactor);
            fr_y = (int) Math.floor(y * nHeightFactor);
            cx = fr_x + 1;
            if (cx >= img.getWidth())
                cx = fr_x;
            cy = fr_y + 1;
            if (cy >= img.getHeight())
                cy = fr_y;
            fx = x * nWidthFactor - fr_x;
            fy = y * nHeightFactor - fr_y;
            nx = 1.0 - fx;
            ny = 1.0 - fy;

            color1 = img.getPixel(fr_x, fr_y);
            color2 = img.getPixel(cx, fr_y);
            color3 = img.getPixel(fr_x, cy);
            color4 = img.getPixel(cx, cy);

            // Blue
            bp1 = (byte) (nx * Color.blue(color1) + fx * Color.blue(color2));
            bp2 = (byte) (nx * Color.blue(color3) + fx * Color.blue(color4));
            nBlue = (byte) (ny * (double) (bp1) + fy * (double) (bp2));

            // Green
            bp1 = (byte) (nx * Color.green(color1) + fx * Color.green(color2));
            bp2 = (byte) (nx * Color.green(color3) + fx * Color.green(color4));
            nGreen = (byte) (ny * (double) (bp1) + fy * (double) (bp2));

            // Red
            bp1 = (byte) (nx * Color.red(color1) + fx * Color.red(color2));
            bp2 = (byte) (nx * Color.red(color3) + fx * Color.red(color4));
            nRed = (byte) (ny * (double) (bp1) + fy * (double) (bp2));

            bmap.setPixel(x, y, Color.argb(255, nRed, nGreen, nBlue));
        }
    }

    bmap = setGrayscale(bmap);
    bmap = removeNoise(bmap);

    return bmap;
}

// SetGrayscale
private Bitmap setGrayscale(Bitmap img) {
    Bitmap bmap = img.copy(img.getConfig(), true);
    int c;
    for (int i = 0; i < bmap.getWidth(); i++) {
        for (int j = 0; j < bmap.getHeight(); j++) {
            c = bmap.getPixel(i, j);
            byte gray = (byte) (.299 * Color.red(c) + .587 * Color.green(c)
                    + .114 * Color.blue(c));

            bmap.setPixel(i, j, Color.argb(255, gray, gray, gray));
        }
    }
    return bmap;
}

// RemoveNoise
private Bitmap removeNoise(Bitmap bmap) {
    for (int x = 0; x < bmap.getWidth(); x++) {
        for (int y = 0; y < bmap.getHeight(); y++) {
            int pixel = bmap.getPixel(x, y);
            if (Color.red(pixel) < 162 && Color.green(pixel) < 162 && Color.blue(pixel) < 162) {
                bmap.setPixel(x, y, Color.BLACK);
            }
        }
    }
    for (int x = 0; x < bmap.getWidth(); x++) {
        for (int y = 0; y < bmap.getHeight(); y++) {
            int pixel = bmap.getPixel(x, y);
            if (Color.red(pixel) > 162 && Color.green(pixel) > 162 && Color.blue(pixel) > 162) {
                bmap.setPixel(x, y, Color.WHITE);
            }
        }
    }
    return bmap;
}

คลาสของคุณสำหรับบิตแมปคืออะไร? ไม่พบบิตแมปใน Java (เป็นบน Android)
เราคือ Borg

วิธีนี้ผ่านข้อยกเว้น: เกิดจาก: java.lang.IllegalArgumentException: y ต้องเป็น <bitmap.height ()
Nativ

9

เอกสารประกอบของ Tesseract มีรายละเอียดที่ดีเกี่ยวกับการปรับปรุงคุณภาพ OCRผ่านขั้นตอนการประมวลผลภาพ

ในระดับหนึ่ง Tesseract จะนำไปใช้โดยอัตโนมัติ นอกจากนี้ยังเป็นไปได้ที่จะบอกให้ Tesseract เขียนภาพขั้นกลางสำหรับการตรวจสอบเช่นเพื่อตรวจสอบว่าการประมวลผลภาพภายในนั้นดีเพียงใด (ค้นหาtessedit_write_imagesในการอ้างอิงข้างต้น)

ที่สำคัญกว่านั้นระบบเครือข่ายนิวรัลแบบใหม่ใน Tesseract 4 ให้ผลลัพธ์ OCR ที่ดีกว่ามากโดยทั่วไปและโดยเฉพาะอย่างยิ่งสำหรับภาพที่มีจุดรบกวน มันเปิดใช้งานด้วย--oem 1เช่นใน:

$ tesseract --oem 1 -l deu page.png result pdf

(ตัวอย่างนี้เลือกภาษาเยอรมัน)

ดังนั้นจึงเป็นการสมควรที่จะทดสอบว่าคุณได้รับโหมด Tesseract LSTM มากน้อยเพียงใดก่อนที่จะใช้ขั้นตอนการประมวลผลภาพล่วงหน้าที่กำหนดเอง


6

การปรับเปลี่ยนสัญญาณไฟอัตโนมัติเป็นสิ่งสำคัญหากแสงไม่สม่ำเสมอในภาพ การประมวลผลล่วงหน้าของฉันโดยใช้ GraphicsMagic ถูกกล่าวถึงในโพสต์นี้: https://groups.google.com/forum/#!topic/tesseract-ocr/jONGSChLRv4

GraphicsMagic ยังมีคุณสมบัติ -lat สำหรับ Linear Time Adaptive Threshold ที่ฉันจะลองเร็ว ๆ นี้

วิธีอื่นของการกำหนดเกณฑ์ใหม่โดยใช้ OpenCV มีการอธิบายไว้ที่นี่: http://docs.opencv.org/trunk/doc/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html


2
ลิงก์ OpenCV มีการเปลี่ยนแปลง ในเอกสารประกอบ OpenCV เป็น บทช่วยสอน OpenCV-Python> การประมวลผลภาพใน OpenCV> Image Thresholding
richk

2

ฉันทำสิ่งเหล่านี้เพื่อให้ได้ผลลัพธ์ที่ดีจากภาพที่มีข้อความไม่เล็กมาก

  1. ใช้การเบลอกับภาพดั้งเดิม
  2. ใช้เกณฑ์ที่ปรับได้
  3. ใช้ผลการเหลา

และหากยังไม่ได้ผลลัพธ์ที่ดีให้ปรับภาพเป็น 150% หรือ 200%


2

การอ่านข้อความจากเอกสารภาพโดยใช้โปรแกรม OCR มีปัญหามากมายเพื่อให้ได้ความแม่นยำที่ดี ไม่มีวิธีแก้ไขที่แน่นอนสำหรับทุกกรณี แต่นี่คือบางสิ่งที่ควรพิจารณาเพื่อปรับปรุงผลลัพธ์ OCR

1) การมีสัญญาณรบกวนเนื่องจากคุณภาพของภาพที่ไม่ดี / องค์ประกอบที่ไม่พึงประสงค์ / blobs ในพื้นที่พื้นหลัง สิ่งนี้ต้องการการดำเนินการก่อนการประมวลผลบางอย่างเช่นการกำจัดเสียงรบกวนซึ่งสามารถทำได้อย่างง่ายดายโดยใช้ตัวกรอง Gaussian หรือวิธีการกรองแบบมัธยฐานปกติ เหล่านี้ยังมีอยู่ใน OpenCV

2) การวางแนวของภาพที่ไม่ถูกต้อง: เนื่องจากโปรแกรม OCR ผิดแนวไม่สามารถแบ่งส่วนของเส้นและคำในภาพได้อย่างถูกต้องซึ่งให้ความแม่นยำที่แย่ที่สุด

3) การแสดงตนของบรรทัด: ในขณะที่ทำเครื่องมือ OCR คำหรือการแบ่งบรรทัดบางครั้งก็พยายามที่จะรวมคำและบรรทัดเข้าด้วยกันและทำให้การประมวลผลเนื้อหาที่ไม่ถูกต้องและด้วยเหตุนี้ให้ผลที่ไม่ถูกต้อง ยังมีปัญหาอื่น ๆ อีกด้วย แต่สิ่งเหล่านี้เป็นประเด็นพื้นฐาน

แอปพลิเคชันโพสต์OCRนี้เป็นกรณีตัวอย่างที่สามารถประมวลผลล่วงหน้าภาพล่วงหน้าและประมวลผลภาพ OCR บางส่วนเพื่อให้ได้ความแม่นยำของ OCR ที่ดีขึ้น


1

การรับรู้ข้อความขึ้นอยู่กับปัจจัยหลายประการเพื่อให้ได้ผลลัพธ์ที่มีคุณภาพดี เอาต์พุต OCR ขึ้นอยู่กับคุณภาพของภาพอินพุต นี่คือเหตุผลที่ OCR เอ็นจิ้นทุกตัวให้แนวทางเกี่ยวกับคุณภาพของภาพอินพุตและขนาดของมัน แนวทางเหล่านี้ช่วยให้เครื่องยนต์ OCR ให้ผลลัพธ์ที่แม่นยำ

ฉันได้เขียนบทความโดยละเอียดเกี่ยวกับการประมวลผลภาพในหลาม กรุณาไปที่ลิงค์ด้านล่างสำหรับคำอธิบายเพิ่มเติม เพิ่มรหัสต้นฉบับของไพ ธ อนเพื่อใช้กระบวนการเหล่านั้น

กรุณาเขียนความคิดเห็นหากคุณมีข้อเสนอแนะหรือความคิดที่ดีขึ้นในหัวข้อนี้เพื่อปรับปรุง

https://medium.com/cashify-engineering/improve-accuracy-of-ocr-using-image-preprocessing-8df29ec3a033


2
โปรดเพิ่มคำตอบที่นี่เป็นบทสรุปของบล็อกของคุณ ดังนั้นแม้ว่าการเชื่อมโยงจะตายคำตอบก็จะไม่ได้ผล
Nithin

0

คุณสามารถลดเสียงรบกวนจากนั้นจึงใช้การกำหนดเกณฑ์ขั้นต่ำ แต่คุณสามารถเล่นกับการกำหนดค่า OCR ได้โดยเปลี่ยนค่า --psm และ --oem

ลอง: --psm 5 --oem 2

คุณสามารถดูลิงค์ต่อไปนี้เพื่อดูรายละเอียดเพิ่มเติมได้ ที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.