我正在尝试在此处读取扫描图像中的所有手写数字
我尝试使用 PIL 逐个像素地查看,裁剪子图像,然后通过神经网络提供它们,但是被裁剪的区域从来没有完全对齐并导致很多不准确。
我也尝试过使用 OpenCV 找到所有的灰色方 block ,然后裁剪图像并通过神经网络提供它们,但我似乎无法找到全部或什至只遗漏几个;它会错过大约 30% 的方 block 。 (我对 OpenCV 不是很有经验,所以我可能搞砸了)
所以我只是在为这个问题寻找一个潜在的想法/解决方案,所以任何建议都将不胜感激,提前致谢!
最佳答案
我假设输入图像名称是“sqaures.jpg”
首先,导入所需的库并加载 RGB 和 Gray 格式的图像:
import cv2
import numpy as np
image = cv2.imread("squares.jpg", 1)
image_gray = cv2.imread("squares.jpg", 0)
然后,我们执行一个简单的操作,使用 np.where() 函数从输入图像中清除一些噪声:
image_gray = np.where(image_gray > 240, 255, image_gray)
image_gray = np.where(image_gray <= 240, 0, image_gray)
因为我们想从图像中抓取整个正方形区域。在执行自适应阈值方法之前,我们需要稍微模糊图像:
image_gray = cv2.blur(image_gray, (5, 5))
im_th = cv2.adaptiveThreshold(image_gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 115, 1)
kernal = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
im_th = cv2.morphologyEx(im_th, cv2.MORPH_OPEN, kernal, iterations=3)
在 OpenCV 中使用轮廓检测来找到所有可能的区域:
_, contours, _ = cv2.findContours(im_th.copy(), cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)
contours.remove(contours[0]) #remove the biggest contour
最后,尝试根据高宽比找到潜在的正方形区域:
square_rects = []
square_areas = []
for i, cnt in enumerate(contours):
(x, y, w, h) = cv2.boundingRect(cnt)
ar = w / float(h)
if 0.9 < ar < 1.1:
square_rects.append(((x,y), (x+w, y+h)))
square_areas.append(w*h) #store area information
我们需要通过执行以下操作从列表中删除任何太小的内容:
import statistics
median_size_limit= statistics.median(square_areas) * 0.8
square_rects = [rect for i, rect in enumerate(square_rects)
if square_areas[i] > median_size_limit]
您可以通过在原始图像上绘制所有矩形来直观地检查输出:
for rect in square_rects:
cv2.rectangle(image, rect[0], rect[1], (0,255,0), 2)
cv2.imwrite("_output_image.png", image)
cv2.imshow("image", image)
cv2.waitKey()
您可以使用“square_rects”定位所有正方形并从原始图像中裁剪它们。
干杯。
关于python - 从扫描图像中识别手写数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51867834/