Python 如何使用OpenCV获取数独网格的单元格?
在过去的几天里,我一直在尝试从图片中获取数独网格,我一直在努力获取网格中较小的正方形。 我正在画下面的图片。我原以为用canny过滤器处理图像会很好,但事实并非如此,我无法得到每个正方形的每个轮廓。然后我把自适应阈值,大津,和一个经典的阈值测试,但每次,它似乎不能捕捉到每一个小正方形 最终的目标是获取包含数字的单元格,并使用pytorch识别数字,因此我非常希望获得一些数字的清晰图像,这样识别就不会出错:) 有人知道如何实现这一点吗? 提前多谢!:DPython 如何使用OpenCV获取数独网格的单元格?,python,image,opencv,image-processing,sudoku,Python,Image,Opencv,Image Processing,Sudoku,在过去的几天里,我一直在尝试从图片中获取数独网格,我一直在努力获取网格中较小的正方形。 我正在画下面的图片。我原以为用canny过滤器处理图像会很好,但事实并非如此,我无法得到每个正方形的每个轮廓。然后我把自适应阈值,大津,和一个经典的阈值测试,但每次,它似乎不能捕捉到每一个小正方形 最终的目标是获取包含数字的单元格,并使用pytorch识别数字,因此我非常希望获得一些数字的清晰图像,这样识别就不会出错:) 有人知道如何实现这一点吗? 提前多谢!:D 如果图像只包含紧密贴合的数独网格,实现它的一
如果图像只包含紧密贴合的数独网格,实现它的一个粗略方法是将图像分成相等的9X9网格,然后尝试提取每个网格中的数字。以下是一个潜在的解决方案:
从上到下和从左到右
参数将每个单元格按顺序组织起来
这是初始二值图像(左)和过滤掉的数字+修复的网格线+反转图像(右) 这里是每个单元迭代的可视化 每个单元格中检测到的数字 代码
导入cv2
从imutils导入等高线
将numpy作为np导入
#加载图像、灰度和自适应阈值
image=cv2.imread('1.png')
灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
阈值=cv2。自适应阈值(灰色,255,cv2。自适应阈值高斯C,cv2。阈值二进制INV,57,5)
#过滤掉所有数字和噪音,仅隔离方框
cnts=cv2.查找对象(阈值、cv2.RETR\u树、cv2.链近似值、简单值)
如果len(cnts)==2个其他cnts[1],则cnts=cnts[0]
对于碳纳米管中的碳:
面积=cv2。轮廓面积(c)
如果面积小于1000:
cv2.拉深轮廓(阈值[c],-1,(0,0,0),-1)
#固定水平线和垂直线
垂直内核=cv2.getStructuringElement(cv2.MORPH_RECT,(1,5))
thresh=cv2.morphologyEx(thresh,cv2.MORPH\u CLOSE,垂直内核,迭代次数=9)
水平内核=cv2.getStructuringElement(cv2.MORPH_RECT,(5,1))
thresh=cv2.morphologyEx(thresh,cv2.MORPH\u CLOSE,水平核,迭代次数=4)
#按从上到下排序,每行按从左到右排序
反转=255-阈值
cnts=cv2.findContours(反转、cv2.RETR\u树、cv2.CHAIN\u近似、简单)
如果len(cnts)==2个其他cnts[1],则cnts=cnts[0]
(CNT,u)=等高线。等高线排序(CNT,方法=“从上到下”)
数独行=[]
行=[]
对于枚举(碳纳米管,1)中的(i,c):
面积=cv2。轮廓面积(c)
如果面积小于50000:
行。追加(c)
如果i%9==0:
(CNT,u)=等高线。等高线排序(行,方法=“从左到右”)
数独行追加(cnts)
行=[]
#遍历每个框
对于数独行中的行:
对于第行中的c:
掩码=np.zero(image.shape,dtype=np.uint8)
cv2.绘制轮廓(掩模,[c],-1,(255255),-1)
结果=cv2.按位_和(图像、掩码)
结果[掩码==0]=255
cv2.imshow(“结果”,结果)
cv2.等待键(175)
cv2.imshow('thresh',thresh)
cv2.imshow(“反转”,反转)
cv2.waitKey()
注意:排序思想是根据中以前的答案改编而成的 步骤:
########## To view all the extracted digits ###############
_, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
axs = axs.flatten()
for img, ax in zip(list_images, axs):
ax.imshow(cv2.resize(img,(64,64)))
plt.show()
翘曲:
########## To view all the extracted digits ###############
_, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
axs = axs.flatten()
for img, ax in zip(list_images, axs):
ax.imshow(cv2.resize(img,(64,64)))
plt.show()
th3:
########## To view all the extracted digits ###############
_, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
axs = axs.flatten()
for img, ax in zip(list_images, axs):
ax.imshow(cv2.resize(img,(64,64)))
plt.show()
扭曲2:
########## To view all the extracted digits ###############
_, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
axs = axs.flatten()
for img, ax in zip(list_images, axs):
ax.imshow(cv2.resize(img,(64,64)))
plt.show()
数独结果:
所有提取的数字:
########## To view all the extracted digits ###############
_, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
axs = axs.flatten()
for img, ax in zip(list_images, axs):
ax.imshow(cv2.resize(img,(64,64)))
plt.show()
参考文献:
########## To view all the extracted digits ###############
_, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
axs = axs.flatten()
for img, ax in zip(list_images, axs):
ax.imshow(cv2.resize(img,(64,64)))
plt.show()