how to remove noise artifacts from an image for ocr with python opencv?

  • Last Update :
  • Techknowledgy :

# Read in image, convert to 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]

# Create special horizontal kernel and dilate
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (70, 1))
dilate = cv2.dilate(thresh, horizontal_kernel, iterations = 1)

# Detect horizontal lines, sort
for largest contour, and draw on mask
mask = np.zeros(image.shape, dtype = np.uint8)
detected_lines = cv2.morphologyEx(dilate, cv2.MORPH_OPEN, horizontal_kernel, iterations = 1)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0]
if len(cnts) == 2
else cnts[1]
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)
for c in cnts:
   cv2.drawContours(mask, [c], -1, (255, 255, 255), -1)
break

Full code for completeness

import cv2
import numpy as np

# Read in image, convert to 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]

# Create special horizontal kernel and dilate
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (70, 1))
dilate = cv2.dilate(thresh, horizontal_kernel, iterations = 1)

# Detect horizontal lines, sort
for largest contour, and draw on mask
mask = np.zeros(image.shape, dtype = np.uint8)
detected_lines = cv2.morphologyEx(dilate, cv2.MORPH_OPEN, horizontal_kernel, iterations = 1)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0]
if len(cnts) == 2
else cnts[1]
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)
for c in cnts:
   cv2.drawContours(mask, [c], -1, (255, 255, 255), -1)
break

# Bitwise - and to get result and color background white
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
result = cv2.bitwise_and(image, image, mask = mask)
result[mask == 0] = (255, 255, 255)

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

Suggestion : 2

After converting to grayscale, we Otsu's anycodings_ocr threshold to get a binary image,Cerate special horizontal kernel and dilate,Otsu's threshold to obtain binary image,Next we create a long horizontal kernel anycodings_ocr and dilate to connect the numbers anycodings_ocr together

First I considered a simple approach: I set anycodings_ocr the first row of pixels as the reference: if anycodings_ocr an artifact was found along the x-axis anycodings_ocr (i.e., a white pixel if the image is anycodings_ocr binarized), I removed it along the y-axis anycodings_ocr until the next black pixel. Code for this anycodings_ocr approach is the one below:

import cv2
inp = cv2.imread("testing_file.tif")
inp = cv2.cvtColor(inp, cv2.COLOR_BGR2GRAY)
_, inp = cv2.threshold(inp, 150, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

ax = inp.shape[1]
ay = inp.shape[0]

out = inp.copy()
for i in range(ax):
   j = 0
while j in range(ay):
   if out[j, i] == 255:
   out[j, i] = 0
else:
   break
j += 1

out = cv2.bitwise_not(out)
cv2.imwrite('output.png', out)

# Read in image, convert to 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]

Full code for completeness

import cv2
import numpy as np

# Read in image, convert to 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]

# Create special horizontal kernel and dilate
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (70, 1))
dilate = cv2.dilate(thresh, horizontal_kernel, iterations = 1)

# Detect horizontal lines, sort
for largest contour, and draw on mask
mask = np.zeros(image.shape, dtype = np.uint8)
detected_lines = cv2.morphologyEx(dilate, cv2.MORPH_OPEN, horizontal_kernel, iterations = 1)
cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0]
if len(cnts) == 2
else cnts[1]
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)
for c in cnts:
   cv2.drawContours(mask, [c], -1, (255, 255, 255), -1)
break

# Bitwise - and to get result and color background white
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
result = cv2.bitwise_and(image, image, mask = mask)
result[mask == 0] = (255, 255, 255)

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

Suggestion : 3

Here is the code to remove the Gaussian noise from a color image using the Non-local Means Denoising algorithm:,h : Parameter regulating filter strength for luminance component. Bigger h value perfectly removes noise but also removes image details, smaller h value preserves details but also preserves some noise.,It's not quite there yet. So, when we apply gray scale function, cv2.fastNlMeansDenoising(img,None,10,7,21), it seems to be working better denoising black and white picture with Gaussian noise:,salt and pepper noise : It has sparse light and dark disturbances. "Pixels in the image are very different in color or intensity from their surrounding pixels; the defining characteristic is that the value of a noisy pixel bears no relation to the color of surrounding pixels. Generally this type of noise will only affect a small number of image pixels. When viewed, the image contains dark and white dots, hence the term salt and pepper noise." - wiki - Noise reduction.

In this section, we'll use cv2.fastNlMeansDenoisingColored() function which is the implementation of Non-local Means Denoising algorithm. It is defined like this:

cv2.fastNlMeansDenoisingColored(src[, dst[, h[, hColor[, templateWindowSize[, searchWindowSize]]]]])

Here is the code to remove the Gaussian noise from a color image using the Non-local Means Denoising algorithm:

import numpy as np
import cv2
from matplotlib
import pyplot as plt

img = cv2.imread('DiscoveryMuseum_NoiseAdded.jpg')
b, g, r = cv2.split(img) # get b, g, r
rgb_img = cv2.merge([r, g, b]) #
switch it to rgb

# Denoising
dst = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21)

b, g, r = cv2.split(dst) # get b, g, r
rgb_dst = cv2.merge([r, g, b]) #
switch it to rgb

plt.subplot(211), plt.imshow(rgb_img)
plt.subplot(212), plt.imshow(rgb_dst)
plt.show()

Suggestion : 4

1 week ago Nov 15, 2020  · Hello Friends, In this episode we are going to remove the noise from masked image so we can focus on our Region Of Interest(ROI) and ignore the all noise in ... , 1 week ago Jan 08, 2013  · OpenCV-Python Tutorials; Computational Photography; Image Denoising . Goal . In this chapter, ... As mentioned above it is used to remove noise from color images. (Noise … , 4 days ago Also read: Visualizing Colors In Images Using Histograms – Python OpenCV. Introduction to Image Denoising. ... Image denoising refers to the process of removing noise from a noisy … , 1 week ago Jun 27, 2022  · Here’s a simple approach: Convert image to grayscale. Otsu’s threshold to obtain binary image. Cerate special horizontal kernel and dilate. Detect horizontal lines, sort for …


import cv2
import numpy as np frame = cv2.imread('hockey4.jpg') width = 900 height = 600 frame = cv2.resize(frame, (width, height)) # Convert BGR to HLS hls = cv2.cvtColor(frame, cv2.COLOR_BGR2HLS) #HLS ranges
for blue #lower array defines the lower limit and upper array defines the upper limit of the range #The mask is a binary image where the output is white
if the corresponding pixel in the input image is between the range specified by upper and lower limits #blue lower = np.array([90, 90, 19]) #90,90,19 upper = np.array([130, 190, 100]) #130,190,100 mask = cv2.inRange(hls, lower, upper) # Bitwise - AND mask and original image res = cv2.bitwise_and(frame, frame, mask = mask)
im_gray = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE) image = cv2.GaussianBlur(im_gray, (5, 5), 1) th = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 3, 2)
import cv2 image = cv2.imread('9qBsB.jpg') image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) se = cv2.getStructuringElement(cv2.MORPH_RECT, (8, 8)) bg = cv2.morphologyEx(image, cv2.MORPH_DILATE, se) out_gray = cv2.divide(image, bg, scale = 255) out_binary = cv2.threshold(out_gray, 0, 255, cv2.THRESH_OTSU)[1] cv2.imshow('binary', out_binary) cv2.imwrite('binary.png', out_binary) cv2.imshow('gray', out_gray) cv2.imwrite('gray.png', out_gray)
import cv2
import numpy as np # load image img = cv2.imread("license_plate.jpg") # convert to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # blur blur = cv2.GaussianBlur(gray, (0, 0), sigmaX = 33, sigmaY = 33) # divide divide = cv2.divide(gray, blur, scale = 255) # otsu threshold thresh = cv2.threshold(divide, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1] # apply morphology kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) # write result to disk cv2.imwrite("hebrew_text_division.jpg", divide) cv2.imwrite("hebrew_text_division_threshold.jpg", thresh) cv2.imwrite("hebrew_text_division_morph.jpg", morph) # display it cv2.imshow("gray", gray) cv2.imshow("divide", divide) cv2.imshow("thresh", thresh) cv2.imshow("morph", morph) cv2.waitKey(0) cv2.destroyAllWindows()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 2)) morphology_img = cv2.morphologyEx(img_grey, cv2.MORPH_OPEN, kernel, iterations = 1) plt.imshow(morphology_img, 'Greys_r')