如何使用 OpenCV 平滑和缩小这些非常粗糙的图像?
How to smooth and make thinner these very rough images using OpenCV?
我有一些单个数字的黑白图像。我正在使用在 MNIST 上训练的 NN 模型对它们进行分类。然而,与 MNIST 数据集相比,这些数字太粗糙和粗了。例如:
TLDR:我需要使用 OpenCV 平滑图像并可能使整体形状变薄。
您很可能会受益于 morphological operations。具体来说,听起来你想要侵蚀。
虽然你确实有一些噪音。你应该试试 OpenCV 的 smoothing operations。根据我的经验,我认为您需要使用内核区域可能约为 9 的中值模糊(尽管这取决于您想要什么)。然后你需要使用腐蚀。
您可以在 Python/OpenCV 中结合使用形态学闭合、打开和腐蚀(以及可选的骨架化和扩张),如下所示:
输入:
import cv2
import numpy as np
from skimage.morphology import skeletonize
# load image
img = cv2.imread("5.png")
# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold image
thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)[1]
# apply morphology close
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# apply morphology open
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# apply morphology erode
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (21,21))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_ERODE, kernel)
# write result to disk
cv2.imwrite("5_thinned.png", thresh)
# skeletonize image and dilate
skeleton = cv2.threshold(thresh,0,1,cv2.THRESH_BINARY)[1]
skeleton = (255*skeletonize(skeleton)).astype(np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15,15))
skeleton_dilated = cv2.morphologyEx(skeleton, cv2.MORPH_DILATE, kernel)
# write result to disk
cv2.imwrite("5_skeleton_dilated.png", skeleton_dilated)
cv2.imshow("IMAGE", img)
cv2.imshow("RESULT1", thresh)
cv2.imshow("RESULT2", skeleton_dilated)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果 1(关闭、打开、腐蚀):
结果 2(关闭、打开、腐蚀、骨架化、膨胀):
我有一些单个数字的黑白图像。我正在使用在 MNIST 上训练的 NN 模型对它们进行分类。然而,与 MNIST 数据集相比,这些数字太粗糙和粗了。例如:
TLDR:我需要使用 OpenCV 平滑图像并可能使整体形状变薄。
您很可能会受益于 morphological operations。具体来说,听起来你想要侵蚀。
虽然你确实有一些噪音。你应该试试 OpenCV 的 smoothing operations。根据我的经验,我认为您需要使用内核区域可能约为 9 的中值模糊(尽管这取决于您想要什么)。然后你需要使用腐蚀。
您可以在 Python/OpenCV 中结合使用形态学闭合、打开和腐蚀(以及可选的骨架化和扩张),如下所示:
输入:
import cv2
import numpy as np
from skimage.morphology import skeletonize
# load image
img = cv2.imread("5.png")
# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold image
thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)[1]
# apply morphology close
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# apply morphology open
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# apply morphology erode
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (21,21))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_ERODE, kernel)
# write result to disk
cv2.imwrite("5_thinned.png", thresh)
# skeletonize image and dilate
skeleton = cv2.threshold(thresh,0,1,cv2.THRESH_BINARY)[1]
skeleton = (255*skeletonize(skeleton)).astype(np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15,15))
skeleton_dilated = cv2.morphologyEx(skeleton, cv2.MORPH_DILATE, kernel)
# write result to disk
cv2.imwrite("5_skeleton_dilated.png", skeleton_dilated)
cv2.imshow("IMAGE", img)
cv2.imshow("RESULT1", thresh)
cv2.imshow("RESULT2", skeleton_dilated)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果 1(关闭、打开、腐蚀):
结果 2(关闭、打开、腐蚀、骨架化、膨胀):