Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在opencv中从数独中提取框_Python_Opencv_Image Processing_Computer Vision_Opencv Python - Fatal编程技术网

Python 在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

我已经使用opencv将数独图像转换为数独网格

现在我想从图像中提取每个框,最好的方法是什么

据我所知,我正试图找到直线的交点,以找到每个方框的角

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()
无法正确听写水平线和垂直线


一种解决方法是进行形态学运算,从canny边缘图像中找到垂直线和水平线,然后进行连接成分分析以找到方框。 我在下面做了一个示例版本。你可以进一步调整它,使它更好。 我从蒙面图像作为输入开始

读取输入图像 灰度=cv2.imread('masked_image.jpg',0) 执行canny边缘检测并添加膨胀层
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添加了可视化连接组件的代码。您可以从学习所有图像处理概念开始。然后,在使用这些技术解决一些问题之后,你将能够自己做出这些明智的决定。它伴随着练习而来。继续学习。很高兴能帮上忙。请也接受答案。:)这回答了你的问题吗?是的,它有同样的目的,很抱歉回答“否”,您可以结束问题