Python 我应该如何在OpenCV中从这个阈值图像中去除噪声?

Python 我应该如何在OpenCV中从这个阈值图像中去除噪声?,python,opencv,image-processing,ocr,Python,Opencv,Image Processing,Ocr,我想删除任何不是图像中字母和数字的部分。输入图像如下所示: 我曾尝试应用canny边缘检测,但它容易受到噪声的影响,并且噪声轮廓相当大。由于这个原因,形态学操作也一直不成功。我尝试了cv2.MORPH_CLOSE,但是噪音区域变大了 我的代码在这里,但目前在消除噪音方面完全没有用处: import imutils input=cv2.imread("n4.jpg") resized = imutils.resize(input, width=700) cv2.imshow("resized"

我想删除任何不是图像中字母和数字的部分。输入图像如下所示:

我曾尝试应用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()
我看了这个和这个,但是它们不起作用,因为噪音的大小和我想要保留的轮廓没有可定义的形状


我也看过这个,但我再次认为它不会起作用,因为没有整体轮廓可以平滑

您发布的图像非常具有挑战性。
我发布的解决方案对于您发布的图像来说太具体了。
我尽量保持它的通用性,但我不希望它在其他图像上工作得很好。
您可以使用它来获得更多消除噪音选项的想法

解决方案主要基于找到连接的组件并移除较小的组件(被认为是噪声)

我使用了
pytesseract
OCR来检查结果是否足够干净,可以进行OCR

以下是代码(请阅读注释):

将numpy导入为np
导入scipy.signal
进口cv2
导入pytesseract
pytesseract.pytesseract.tesseract_cmd=r“C:\Program Files\tesseract OCR\tesseract.exe”,适用于Windows操作系统
#读取输入图像
输入=cv2.imread(“n4.jpg”)
#转换为灰度。
灰色=cv2.CVT颜色(输入,cv2.COLOR\u BGR2GRAY)
#转换为二进制并反转极性
ret,thresh=cv2.阈值(灰色,0,255,cv2.thresh\u二进制\u INV+cv2.thresh\u OTSU)
#查找连接的组件(群集)
nlabel,labels,stats,形心=cv2。connectedComponentsWithStats(阈值,连接性=8)
#移除小簇:具有两个宽度
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
# https://stackoverflow.com/questions/47520487/how-to-use-python-opencv-to-find-largest-connected-component-in-a-single-channel
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()