我应该如何从 OpenCV 中的阈值图像中去除噪声?
How should I remove noise from this thresholded image in OpenCV?
我想删除不属于图像中字母和数字的任何内容。输入图像是这样的:
我试过用canny边缘检测,但是容易受噪声影响,噪声轮廓很大。由于这个原因,形态学操作也没有成功。我试过 cv2.MORPH_CLOSE
但噪音区域变大了。
我的代码在这里,但它目前在消除噪音方面完全没用:
import imutils
input=cv2.imread("n4.jpg")
resized = imutils.resize(input, width=700)
cv2.imshow("resized",resized)
blur = cv2.GaussianBlur(resized,(7,7),0)
cv2.imshow("blur",blur)
gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
threshINV = cv2.threshold(gray, 140, 255, cv2.THRESH_BINARY_INV)[1]
cv2.imshow("thresh",threshINV)
e = cv2.Canny(threshINV,20,50)
cv2.imshow("e",e)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4,4))
close = cv2.morphologyEx(threshINV, cv2.MORPH_CLOSE, kernel)
cv2.imshow("close",close)
edged = cv2.Canny(gray, 20, 50)
dilat = cv2.dilate(edged, None, iterations=1)
cv2.imshow("test",dilat)
cv2.waitKey(0)
cv2.destroyAllWindows()
我看过这个 example and this other example,但是由于噪声的大小以及我想保留的轮廓没有可定义的形状,它们无法工作。
我也看过这个 method,但我还是认为它行不通,因为没有要平滑的整体轮廓。
您发布的图片很有挑战性。
我发布的解决方案对于您发布的图片来说太具体了。
我尽量保持它的通用性,但我不希望它在其他图像上效果很好。
您可以使用它来获取有关消除噪音的更多选项的想法。
解决方案主要基于找到连接的组件并移除较小的组件 - 被认为是噪声。
我使用 pytesseract
OCR 检查结果对于 OCR 是否足够清晰。
代码如下(请阅读评论):
import numpy as np
import scipy.signal
import cv2
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe" # For Windows OS
# Read input image
input = cv2.imread("n4.jpg")
# Convert to Grayscale.
gray = cv2.cvtColor(input, cv2.COLOR_BGR2GRAY)
# Convert to binary and invert polarity
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# Find connected components (clusters)
nlabel, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity=8)
# Remove small clusters: With both width<=10 and height<=10 (clean small size noise).
for i in range(nlabel):
if (stats[i, cv2.CC_STAT_WIDTH] <= 10) and (stats[i, cv2.CC_STAT_HEIGHT] <= 10):
thresh[labels == i] = 0
#Use closing with very large horizontal kernel
mask = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((1, 150)))
# Find connected components (clusters) on mask
nlabel, labels, stats, centroids = cv2.connectedComponentsWithStats(mask, connectivity=8)
# Find label with maximum area
#
largest_label = 1 + np.argmax(stats[1:, cv2.CC_STAT_AREA])
# Set to zero all clusters that are not the largest cluster.
thresh[labels != largest_label] = 0
# Use closing with horizontal kernel of 15 (connecting components of digits)
mask = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((1, 15)))
# Find connected components (clusters) on mask again
nlabel, labels, stats, centroids = cv2.connectedComponentsWithStats(mask, connectivity=8)
# Remove small clusters: With both width<=30 and height<=30
for i in range(nlabel):
if (stats[i, cv2.CC_STAT_WIDTH] <= 30) and (stats[i, cv2.CC_STAT_HEIGHT] <= 30):
thresh[labels == i] = 0
# Use closing with horizontal kernel of 15, this time on thresh
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((1, 15)))
# Use median filter with 3x5 mask (using OpenCV medianBlur with k=5 is removes important details).
thresh = scipy.signal.medfilt(thresh, (3,5))
# Inverse polarity
thresh = 255 - thresh
# Apply OCR
data = pytesseract.image_to_string(thresh, config="-c tessedit"
"_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-/"
" --psm 6"
" ")
print(data)
# Show image for testing
cv2.imshow('thresh', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
thresh
(干净的图像):
OCR 结果:EXPO22016/01-2019
我想删除不属于图像中字母和数字的任何内容。输入图像是这样的:
我试过用canny边缘检测,但是容易受噪声影响,噪声轮廓很大。由于这个原因,形态学操作也没有成功。我试过 cv2.MORPH_CLOSE
但噪音区域变大了。
我的代码在这里,但它目前在消除噪音方面完全没用:
import imutils
input=cv2.imread("n4.jpg")
resized = imutils.resize(input, width=700)
cv2.imshow("resized",resized)
blur = cv2.GaussianBlur(resized,(7,7),0)
cv2.imshow("blur",blur)
gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
threshINV = cv2.threshold(gray, 140, 255, cv2.THRESH_BINARY_INV)[1]
cv2.imshow("thresh",threshINV)
e = cv2.Canny(threshINV,20,50)
cv2.imshow("e",e)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4,4))
close = cv2.morphologyEx(threshINV, cv2.MORPH_CLOSE, kernel)
cv2.imshow("close",close)
edged = cv2.Canny(gray, 20, 50)
dilat = cv2.dilate(edged, None, iterations=1)
cv2.imshow("test",dilat)
cv2.waitKey(0)
cv2.destroyAllWindows()
我看过这个 example and this other example,但是由于噪声的大小以及我想保留的轮廓没有可定义的形状,它们无法工作。
我也看过这个 method,但我还是认为它行不通,因为没有要平滑的整体轮廓。
您发布的图片很有挑战性。
我发布的解决方案对于您发布的图片来说太具体了。
我尽量保持它的通用性,但我不希望它在其他图像上效果很好。
您可以使用它来获取有关消除噪音的更多选项的想法。
解决方案主要基于找到连接的组件并移除较小的组件 - 被认为是噪声。
我使用 pytesseract
OCR 检查结果对于 OCR 是否足够清晰。
代码如下(请阅读评论):
import numpy as np
import scipy.signal
import cv2
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r"C:\Program Files\Tesseract-OCR\tesseract.exe" # For Windows OS
# Read input image
input = cv2.imread("n4.jpg")
# Convert to Grayscale.
gray = cv2.cvtColor(input, cv2.COLOR_BGR2GRAY)
# Convert to binary and invert polarity
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# Find connected components (clusters)
nlabel, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity=8)
# Remove small clusters: With both width<=10 and height<=10 (clean small size noise).
for i in range(nlabel):
if (stats[i, cv2.CC_STAT_WIDTH] <= 10) and (stats[i, cv2.CC_STAT_HEIGHT] <= 10):
thresh[labels == i] = 0
#Use closing with very large horizontal kernel
mask = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((1, 150)))
# Find connected components (clusters) on mask
nlabel, labels, stats, centroids = cv2.connectedComponentsWithStats(mask, connectivity=8)
# Find label with maximum area
#
largest_label = 1 + np.argmax(stats[1:, cv2.CC_STAT_AREA])
# Set to zero all clusters that are not the largest cluster.
thresh[labels != largest_label] = 0
# Use closing with horizontal kernel of 15 (connecting components of digits)
mask = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((1, 15)))
# Find connected components (clusters) on mask again
nlabel, labels, stats, centroids = cv2.connectedComponentsWithStats(mask, connectivity=8)
# Remove small clusters: With both width<=30 and height<=30
for i in range(nlabel):
if (stats[i, cv2.CC_STAT_WIDTH] <= 30) and (stats[i, cv2.CC_STAT_HEIGHT] <= 30):
thresh[labels == i] = 0
# Use closing with horizontal kernel of 15, this time on thresh
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((1, 15)))
# Use median filter with 3x5 mask (using OpenCV medianBlur with k=5 is removes important details).
thresh = scipy.signal.medfilt(thresh, (3,5))
# Inverse polarity
thresh = 255 - thresh
# Apply OCR
data = pytesseract.image_to_string(thresh, config="-c tessedit"
"_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-/"
" --psm 6"
" ")
print(data)
# Show image for testing
cv2.imshow('thresh', thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
thresh
(干净的图像):
OCR 结果:EXPO22016/01-2019