Python 在opencv中从数独中提取框
我已经使用opencv将数独图像转换为数独网格 现在我想从图像中提取每个框,最好的方法是什么 据我所知,我正试图找到直线的交点,以找到每个方框的角Python 在opencv中从数独中提取框,python,opencv,image-processing,computer-vision,opencv-python,Python,Opencv,Image Processing,Computer Vision,Opencv Python,我已经使用opencv将数独图像转换为数独网格 现在我想从图像中提取每个框,最好的方法是什么 据我所知,我正试图找到直线的交点,以找到每个方框的角 class SudokuSolverPlay: def __init__(self, image): def __preProcess(self, img): """return grayscale image""" d
class SudokuSolverPlay:
def __init__(self, image):
def __preProcess(self, img):
"""return grayscale image"""
def __maskSudoku(self, img):
"""return masked image"""
def __dectactEdge(self, img):
"""return sudoku grid"""
def drawLines(src, dest, iteration=1):
minLineLength = 100
src = cv2.convertScaleAbs(src)
for _ in range(iteration):
lines = cv2.HoughLinesP(image=src, rho=1, theta=np.pi / 180,
threshold=100, lines=np.array([]),
minLineLength=minLineLength, maxLineGap=100)
a, b, c = lines.shape
for i in range(a):
x1, y1, x2, y2 = lines[i][0][0], lines[i][0][1], lines[i][0][2], lines[i][0][3]
cv2.line(dest, (x1, y1), (x2, y2),255, 1, cv2.LINE_AA)
src = cv2.convertScaleAbs(dest)
def findVerticalLines(img):
imgX = cv2.GaussianBlur(img, (5, 5), 0)
kernelx = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 10))
imgY = cv2.Sobel(img, cv2.CV_64F, 1, 0)
imgY = cv2.convertScaleAbs(imgY)
cv2.normalize(imgY, imgY, 0, 255, cv2.NORM_MINMAX)
imgY = cv2.morphologyEx(imgY, cv2.MORPH_CLOSE, kernelx, iterations=1)
return imgY
def findHorizontalLines(img):
"""same as above only args different"""
img1 = np.zeros(img.shape)
edges = cv2.Canny(img, 50, 150, apertureSize=3)
laplacian = cv2.Laplacian(edges, cv2.CV_64F)
drawLines(laplacian, img1, iteration=1)
sby = findVerticalLines(img1)
sbx = findHorizontalLines(img1)
return img1
def solveSudoku(self):
gray = self.__preProcess(self.__originalImg)
masked = self.__maskSudoku(gray)
grid = self.__dectactGrid(masked)
if __name__ == '__main__':
colorImg = cv2.imread('sudoku1.jpg')
solver = SudokuSolverPlay(colorImg)
solver.solveSudoku()
此处的findVerticalLines()
和findHorizontalLines()
无法正确听写水平线和垂直线
img\u bin=cv2.Canny(灰度,50110)
dil_kernel=np.ones((3,3),np.uint8)
img_-bin=cv2.deplate(img_-bin,dil_内核,迭代次数=1)
现在,放大的二值图像是这样的。
假设最小盒子尺寸为20*20
line\u min\u width=20
寻找水平线
kernal\u h=np.one((1,行最小宽度),np.uint8)
img_bin_h=cv2.morphologyEx(img_bin,cv2.MORPH_OPEN,kernal_h)
寻找垂直线
kernal\u v=np.one((行最小宽度,1),np.uint8)
img_bin_v=cv2.morphologyEx(img_bin,cv2.MORPH_OPEN,kernal_v)
合并并添加膨胀层以闭合小间隙
img_bin_final=img_bin_h | img_bin_v
最终核=np.ones((3,3),np.uint8)
img_bin_final=cv2.deplate(img_bin_final,final_内核,迭代次数=1)
应用连通分量分析
ret,标签,统计信息,质心=cv2.connectedComponentsWithStats(~img_bin_final,connectivity=8,ltype=cv2.CV_32S)
可视化连接组件图像
正如您所见,我们检测到一些文本也作为框,我们可以使用简单的过滤条件轻松删除它们,这里我使用的过滤区域应为最小1000像素的条件
在检测到的框上绘制矩形。
####1和0以及我们不需要的背景和剩余连接组件
对于统计数据中的x、y、w、h区域[2:]:
#cv2.putText(图像,'box',(x-10,y-10),cv2.FONT\u HERSHEY\u SIMPLEX,1.0,(0255,0),2)
如果面积>1000:
cv2.矩形(图像,(x,y),(x+w,y+h),(0255,0),2)
最终输出图像
这个答案基于我使用OpenCV在图像中查找复选框/表格的解决方案。你可以在我的《走向数据科学》中找到详细的解释。
希望这将使您更接近解决方案
快乐编码:)
--编辑1
进行连接组件可视化的代码
def imshow_组件(标签):
###创建hsv图像,每个标签具有唯一的色调值
标签颜色=np.uint8(179*标签/np.max(标签))
###使饱和度和体积为255
空通道=255*np.类通道(标签色调)
label\u img=cv2.merge([label\u色调、空通道、空通道])
###将hsv图像转换为BGR图像
标记的颜色=cv2.CVT颜色(标记的颜色、cv2.COLOR\U HSV2BGR)
标签颜色[标签颜色==0]=0
###返回彩色图像以可视化连接的组件
返回标记为\u img
感谢您的简短回答,它正在工作,我想问你,我们能否做出明智的决定,比如什么时候根据图像应用腐蚀、膨胀或不同类型的模糊?如何像你在<代码>可视化连接组件图像中绘制的那样绘制图像@JanakVaghasiya添加了可视化连接组件的代码。您可以从学习所有图像处理概念开始。然后,在使用这些技术解决一些问题之后,你将能够自己做出这些明智的决定。它伴随着练习而来。继续学习。很高兴能帮上忙。请也接受答案。:)这回答了你的问题吗?是的,它有同样的目的,很抱歉回答“否”,您可以结束问题