logo
down
shadow

Remove background noise from image to make text more clear for OCR


Remove background noise from image to make text more clear for OCR

Content Index :

Remove background noise from image to make text more clear for OCR
Tag : java , By : Adil
Date : November 25 2020, 09:00 AM

Does that help My answer is based on following assumptions. It's possible that none of them holds in your case.
It's possible for you to impose a threshold for bounding box heights in the segmented region. Then you should be able to filter out other components. You know the average stroke widths of the digits. Use this information to minimize the chance that the digits are connected to other regions. You can use distance transform and morphological operations for this.
Mat im = imread("aRh8C.png", 0);
// apply Otsu threshold
Mat bw;
threshold(im, bw, 0, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);
// take the distance transform
Mat dist;
distanceTransform(bw, dist, CV_DIST_L2, CV_DIST_MASK_PRECISE);
Mat dibw;
// threshold the distance transformed image
double SWTHRESH = 8;    // stroke width threshold
threshold(dist, dibw, SWTHRESH/2, 255, CV_THRESH_BINARY);
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
// perform opening, in case digits are still connected
Mat morph;
morphologyEx(dibw, morph, CV_MOP_OPEN, kernel);
dibw.convertTo(dibw, CV_8U);
// find contours and filter
Mat cont;
morph.convertTo(cont, CV_8U);

Mat binary;
cvtColor(dibw, binary, CV_GRAY2BGR);

const double HTHRESH = im.rows * .5;    // height threshold
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
vector<Point> digits; // points corresponding to digit contours

findContours(cont, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
{
    Rect rect = boundingRect(contours[idx]);
    if (rect.height > HTHRESH)
    {
        // append the points of this contour to digit points
        digits.insert(digits.end(), contours[idx].begin(), contours[idx].end());

        rectangle(binary, 
            Point(rect.x, rect.y), Point(rect.x + rect.width - 1, rect.y + rect.height - 1),
            Scalar(0, 0, 255), 1);
    }
}

// take the convexhull of the digit contours
vector<Point> digitsHull;
convexHull(digits, digitsHull);
// prepare a mask
vector<vector<Point>> digitsRegion;
digitsRegion.push_back(digitsHull);
Mat digitsMask = Mat::zeros(im.rows, im.cols, CV_8U);
drawContours(digitsMask, digitsRegion, 0, Scalar(255, 255, 255), -1);
// expand the mask to include any information we lost in earlier morphological opening
morphologyEx(digitsMask, digitsMask, CV_MOP_DILATE, kernel);
// copy the region to get a cleaned image
Mat cleaned = Mat::zeros(im.rows, im.cols, CV_8U);
dibw.copyTo(cleaned, digitsMask);
Mat im = Highgui.imread("aRh8C.png", 0);
// apply Otsu threshold
Mat bw = new Mat(im.size(), CvType.CV_8U);
Imgproc.threshold(im, bw, 0, 255, Imgproc.THRESH_BINARY_INV | Imgproc.THRESH_OTSU);
// take the distance transform
Mat dist = new Mat(im.size(), CvType.CV_32F);
Imgproc.distanceTransform(bw, dist, Imgproc.CV_DIST_L2, Imgproc.CV_DIST_MASK_PRECISE);
// threshold the distance transform
Mat dibw32f = new Mat(im.size(), CvType.CV_32F);
final double SWTHRESH = 8.0;    // stroke width threshold
Imgproc.threshold(dist, dibw32f, SWTHRESH/2.0, 255, Imgproc.THRESH_BINARY);
Mat dibw8u = new Mat(im.size(), CvType.CV_8U);
dibw32f.convertTo(dibw8u, CvType.CV_8U);

Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
// open to remove connections to stray elements
Mat cont = new Mat(im.size(), CvType.CV_8U);
Imgproc.morphologyEx(dibw8u, cont, Imgproc.MORPH_OPEN, kernel);
// find contours and filter based on bounding-box height
final double HTHRESH = im.rows() * 0.5; // bounding-box height threshold
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
List<Point> digits = new ArrayList<Point>();    // contours of the possible digits
Imgproc.findContours(cont, contours, new Mat(), Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE);
for (int i = 0; i < contours.size(); i++)
{
    if (Imgproc.boundingRect(contours.get(i)).height > HTHRESH)
    {
        // this contour passed the bounding-box height threshold. add it to digits
        digits.addAll(contours.get(i).toList());
    }   
}
// find the convexhull of the digit contours
MatOfInt digitsHullIdx = new MatOfInt();
MatOfPoint hullPoints = new MatOfPoint();
hullPoints.fromList(digits);
Imgproc.convexHull(hullPoints, digitsHullIdx);
// convert hull index to hull points
List<Point> digitsHullPointsList = new ArrayList<Point>();
List<Point> points = hullPoints.toList();
for (Integer i: digitsHullIdx.toList())
{
    digitsHullPointsList.add(points.get(i));
}
MatOfPoint digitsHullPoints = new MatOfPoint();
digitsHullPoints.fromList(digitsHullPointsList);
// create the mask for digits
List<MatOfPoint> digitRegions = new ArrayList<MatOfPoint>();
digitRegions.add(digitsHullPoints);
Mat digitsMask = Mat.zeros(im.size(), CvType.CV_8U);
Imgproc.drawContours(digitsMask, digitRegions, 0, new Scalar(255, 255, 255), -1);
// dilate the mask to capture any info we lost in earlier opening
Imgproc.morphologyEx(digitsMask, digitsMask, Imgproc.MORPH_DILATE, kernel);
// cleaned image ready for OCR
Mat cleaned = Mat.zeros(im.size(), CvType.CV_8U);
dibw8u.copyTo(cleaned, digitsMask);
// feed cleaned to Tesseract

Comments
No Comments Right Now !

Boards Message :
You Must Login Or Sign Up to Add Your Comments .

Share : facebook icon twitter icon

How to remove background noise while performing OpenCV Image subtraction?


Tag : python , By : Bado
Date : March 29 2020, 07:55 AM
wish help you to fix your issue I have two images one is the document image and the other image is the template image. , The code is self explanatory.
import numpy as np
import cv2

if __name__ == '__main__':

    image = cv2.imread('image.png',cv2.IMREAD_GRAYSCALE)
    template = cv2.imread('template.png',cv2.IMREAD_GRAYSCALE)

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    template = cv2.morphologyEx(template, cv2.MORPH_ERODE, kernel,iterations = 2)

    image[template == 0] = 255

    cv2.imshow('image', image)
    cv2.imshow('tmpl', template)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Remove background text and noise from an image using image processing with OpenCV


Tag : python , By : Grant
Date : March 29 2020, 07:55 AM
Hope this helps Here are two potential approaches and a method to correct distorted text:
Method #1: Morphological operations + contour filtering
YabVzu
import cv2
import pytesseract
import numpy as np

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

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

# Morph open to remove noise
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,2))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1)

# Find contours and remove small noise
cnts = cv2.findContours(opening, 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 < 50:
        cv2.drawContours(opening, [c], -1, 0, -1)

# Invert and apply slight Gaussian blur
result = 255 - opening
result = cv2.GaussianBlur(result, (3,3), 0)

# Perform OCR
data = pytesseract.image_to_string(result, lang='eng', config='--psm 6')
print(data)

cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('result', result)
cv2.waitKey()     
import cv2
import pytesseract
import numpy as np

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Load image, convert to HSV, color threshold to get mask
image = cv2.imread('2.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([100, 175, 110])
mask = cv2.inRange(hsv, lower, upper)

# Invert image and OCR
invert = 255 - mask
data = pytesseract.image_to_string(invert, lang='eng', config='--psm 6')
print(data)

cv2.imshow('mask', mask)
cv2.imshow('invert', invert)
cv2.waitKey()
import cv2
import pytesseract
import numpy as np
from imutils.perspective import four_point_transform

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

# Load image, convert to HSV, color threshold to get mask
image = cv2.imread('1.png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([100, 175, 110])
mask = cv2.inRange(hsv, lower, upper)

# Morph close to connect individual text into a single contour
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=3)

# Find rotated bounding box then perspective transform
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
rect = cv2.minAreaRect(cnts[0])
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image,[box],0,(36,255,12),2)
warped = four_point_transform(255 - mask, box.reshape(4, 2))

# OCR
data = pytesseract.image_to_string(warped, lang='eng', config='--psm 6')
print(data)

cv2.imshow('mask', mask)
cv2.imshow('close', close)
cv2.imshow('warped', warped)
cv2.imshow('image', image)
cv2.waitKey()
import cv2
import numpy as np

def nothing(x):
    pass

# Load image
image = cv2.imread('2.png')

# Create a window
cv2.namedWindow('image')

# Create trackbars for color change
# Hue is from 0-179 for Opencv
cv2.createTrackbar('HMin', 'image', 0, 179, nothing)
cv2.createTrackbar('SMin', 'image', 0, 255, nothing)
cv2.createTrackbar('VMin', 'image', 0, 255, nothing)
cv2.createTrackbar('HMax', 'image', 0, 179, nothing)
cv2.createTrackbar('SMax', 'image', 0, 255, nothing)
cv2.createTrackbar('VMax', 'image', 0, 255, nothing)

# Set default value for Max HSV trackbars
cv2.setTrackbarPos('HMax', 'image', 179)
cv2.setTrackbarPos('SMax', 'image', 255)
cv2.setTrackbarPos('VMax', 'image', 255)

# Initialize HSV min/max values
hMin = sMin = vMin = hMax = sMax = vMax = 0
phMin = psMin = pvMin = phMax = psMax = pvMax = 0

while(1):
    # Get current positions of all trackbars
    hMin = cv2.getTrackbarPos('HMin', 'image')
    sMin = cv2.getTrackbarPos('SMin', 'image')
    vMin = cv2.getTrackbarPos('VMin', 'image')
    hMax = cv2.getTrackbarPos('HMax', 'image')
    sMax = cv2.getTrackbarPos('SMax', 'image')
    vMax = cv2.getTrackbarPos('VMax', 'image')

    # Set minimum and maximum HSV values to display
    lower = np.array([hMin, sMin, vMin])
    upper = np.array([hMax, sMax, vMax])

    # Convert to HSV format and color threshold
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv, lower, upper)
    result = cv2.bitwise_and(image, image, mask=mask)

    # Print if there is a change in HSV value
    if((phMin != hMin) | (psMin != sMin) | (pvMin != vMin) | (phMax != hMax) | (psMax != sMax) | (pvMax != vMax) ):
        print("(hMin = %d , sMin = %d, vMin = %d), (hMax = %d , sMax = %d, vMax = %d)" % (hMin , sMin , vMin, hMax, sMax , vMax))
        phMin = hMin
        psMin = sMin
        pvMin = vMin
        phMax = hMax
        psMax = sMax
        pvMax = vMax

    # Display result image
    cv2.imshow('image', result)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

Remove wavy noise from image background using OpenCV


Tag : python , By : user123284
Date : March 29 2020, 07:55 AM
I wish did fix the issue. You can play around with contrast/brightness to remove background pixels as discussed in this post.
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

alpha = 2.5
beta = -0.0

denoised = alpha * gray + beta
denoised = np.clip(denoised, 0, 255).astype(np.uint8)

denoised = cv2.fastNlMeansDenoising(denoised, None, 31, 7, 21)

How to remove background noise in image without damaging text?


Tag : python , By : Alex S
Date : October 07 2020, 02:00 AM
will help you Since your image is only black/white, you can do simple thresholding and morphological transformations to filter the image. If your image input was not black and white, you could do blurring techniques such as cv2.medianBlur() or cv2.GaussianBlur() to smooth the image as a preprocessing step. Then you could perform morphological operations with various kernel sizes or construct custom kernels with cv2.getStructuringElement(). Generally, a larger kernel size (7x7 or 9x9) will remove more noise but also remove the desired details as opposed to a smaller kernel (3x3 or 5x5). There is a trade off depending on how much noise you want to remove while balancing the amount of details to preserve. Take a look at this answer for colored captchas.
import cv2
import pytesseract

pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe"

image = cv2.imread('1.png',0)
thresh = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY_INV)[1]

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

result = 255 - opening
cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('result', result)

print(pytesseract.image_to_string(result))
cv2.waitKey()

Remove surrounding lines and background graphic noise from handwritten text


Tag : python , By : UnKnownUser
Date : October 05 2020, 12:00 PM
Hope that helps Here's a simple approach with the assumption that the text is blue
Convert image to HSV format and color threshold with cv2.inRange() Perform morphological transformations to smooth image Isolate characters Recolor characters for OCR/Tesseract
image = cv2.imread('1.png')
result = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([21,0,0])
upper = np.array([179, 255, 209])
mask = cv2.inRange(image, lower, upper)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2,2))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=1)
result[close==0] = (255,255,255)
retouch_mask = (result <= [250.,250.,250.]).all(axis=2)
result[retouch_mask] = [0,0,0]
import numpy as np
import cv2

image = cv2.imread('1.png')
result = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([21,0,0])
upper = np.array([179, 255, 209])
mask = cv2.inRange(image, lower, upper)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2,2))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=1)

result[close==0] = (255,255,255)

cv2.imshow('cleaned', result)

retouch_mask = (result <= [250.,250.,250.]).all(axis=2)
result[retouch_mask] = [0,0,0]

cv2.imshow('mask', mask)
cv2.imshow('close', close)
cv2.imshow('result', result)
cv2.waitKey()
Related Posts Related QUESTIONS :
  • Clean Archtecture. Understanding of scheme
  • Processing 3 triangle not showing in Javafx 8 Window tab
  • How to specify a sequence-based generated value in Hibernate 5 via legacy mapping
  • Spring-boot application not getting auto-deployed on startup
  • How to only pass strings that the user select
  • Is there a way to SELECT using "GREATEST(field1, field2)" where field1 and field2 are aggregate sums in the sa
  • How to handle JSON objects wrapped into one JSON object with retrofit2?
  • Configure Hazelcast CPSubsystem Retries Timeout
  • how to use onBindViewHolder with multiple items in android RecyclerView
  • No ParameterResolver registered for parameter in BeforeAll method
  • Finding the path in a graph with the least casualties according to the lanchester square law
  • MongoWriteException when inserting into Mongodb with composite custom _id
  • Fetch Oracle procedure metadata with Java when multiple procedure signatures
  • Value modification of key-pair in HashMap and impact for a HashCode
  • Migration from solrj to spring-data-solr
  • How to check if you're still connected to the database with jpa
  • Use Date type in the graphql scheme
  • Split and add the string based on length
  • Is "main" method of spring boot application required when deploy as war
  • Getting the average within specific numbers in an array
  • how to use izpack to make my jar application to installer?
  • What is meant by src in Java Eclipse?
  • Create a mirrored linked list in Java
  • Examples of good JPA Java Desktop Application
  • Translate Java to Python -- signing strings with PEM certificate files
  • Algorithm Analysis tool for java
  • Java serial comm API - what does inputstream.read() return if a timeout occurs?
  • How do I make a background thread in Java that allows the main application to exit completely? This works in Linux, but
  • How to add an image dynamically at runtime in java
  • Java App on Mac asking for allow network connections everytime
  • Best actively maintained Java XMPP Library?
  • Multi-Threaded Application - Help with some pseudo code!
  • Scoping a StringBuilder inside a for loop
  • How to specify hash algorithm when updating LDAP via Java?
  • Class not found exception (org.apache.openjpa.enhance.PersistenceCapable) thrown in a client of WLS 10
  • In Java ,where in memory are class functions put?
  • How do I test expectedExceptionsMessageRegExp (exception message) using TestNG?
  • Help In understanding Multi Dimentional Arrays
  • No bean named '...' is defined and Spring @Resource annotation
  • Singleton design pattern vs Singleton beans in Spring container
  • flashvars object was not working in mozilla browser
  • Shell script to import mysql dump file
  • What are the best practices to separate data from users
  • May I use com.google.code prefix for my packages?
  • How to set classpath in manifest file , while creating JAR from eclipse?
  • dealing with voice in java
  • Error: java.security.AccessControlException: Access denied
  • How to verify the root trust of a ceritifcate
  • Searching for a standalone JSP compiler
  • Spring 2.5 managed servlets: howto?
  • iBatis get executed sql
  • GRAPH: find an algorithm to determine the shortest path from one point to another in a rectangular maze?
  • Efficient JSON encoding for data that may be binary, but is often text
  • How to Read Java File Structure using Java?
  • Java-Hibernate-Newbie: How do I acces the values from this list?
  • Smallest executable for Windows
  • Java: matching two different type of array
  • how to accept valid e-mail id in text box?
  • How can I know where a Null Pointer Exception originated?
  • Memory limited image processing in server
  • shadow
    Privacy Policy - Terms - Contact Us © scrbit.com