

{"id":102264,"date":"2021-10-26T09:00:52","date_gmt":"2021-10-26T03:30:52","guid":{"rendered":"https:\/\/data-flair.training\/blogs\/?p=102264"},"modified":"2026-06-01T12:33:43","modified_gmt":"2026-06-01T07:03:43","slug":"opencv-sudoku-solver","status":"publish","type":"post","link":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/","title":{"rendered":"Sudoku Solver using OpenCV &amp; Python"},"content":{"rendered":"<p>We all played sudoku at least once in our childhood. It is a very interesting puzzle game. In this project, we\u2019re going to build a sudoku solver program using OpenCV. It detects a sudoku board from an image and then solves it.<\/p>\n<p>First, the program will detect a sudoku board in an image then extract only the board. Then it detects each given number from that board and then it solves the board. After solving the board it puts the solved numbers in that original image at the same position where the board was empty. All these operations will be built with OpenCV python and Deep learning OCR detection.<\/p>\n<h3>What is OpenCV?<\/h3>\n<p>OpenCV is an Image processing library for python and it is written in C\/C++. We can also perform some real-time operations with OpenCV because it is very fast and lightweight.<\/p>\n<h3>What is Deep Learning?<\/h3>\n<p>Deep learning is a subset of machine learning that is built with neural networks. Neural networks try to mimic human brains to solve a problem. Deep learning is used to solve complex problems that cannot be solved with typical machine learning algorithms.<\/p>\n<p>To detect numbers from the sudoku board we\u2019ll use a pre-trained <strong>OCR<\/strong> model. <strong>OCR <\/strong>or<strong> Optical Character Recognition<\/strong> is a technology that recognizes text within a digital image. The model that we\u2019ll be using is specially trained for sudoku. It only detects a single digit in an image.<\/p>\n<h3>Prerequisites:<\/h3>\n<p>1. Python 3.x (we used 3.7.10)<br \/>\n2. OpenCV &#8211; 4.4.0<br \/>\n3. Numpy &#8211; 1.19.3<br \/>\n4. Tensorflow &#8211; 2.5.0<br \/>\n5. Imutils &#8211; 0.5.4<\/p>\n<h3>Download Sudoku Solver OpenCV Project<\/h3>\n<p>Download source code of python sudoku solver: <a href=\"https:\/\/drive.google.com\/file\/d\/1r3xRywHmcvkSF61Wm9SFvkVmx50RcMJN\/view?usp=drive_link\"><strong>Sudoku Solver Project Source Code<\/strong><\/a><\/p>\n<h3>What is Sudoku?<\/h3>\n<p>Sudoku is a combinational number-placement puzzle. The objective of sudoku is to fill a 9&#215;9 grid with some digits in such a way so that each column, row, and nine 3&#215;3 subgrids contain all of the digits from 0-9.<\/p>\n<p>We\u2019ll use an algorithm called backtracking. Backtracking is an algorithm for finding solutions to some computational problem. It tries to find a solution until it validates all criteria.<\/p>\n<p>In sudoku, the algorithm will put a number in an empty space and then move on to the next empty space, if anywhere some criteria fail then it will turn back to some previous solutions and changes it according to the criteria. It continues until it finds a final solution that matches all the criteria.<\/p>\n<p><strong>solver.py<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># DataFlair OpenCV Sudoku solver\r\n\r\ndef find_empty(board):\r\n\"\"\"checks where is an empty or unsolved block\"\"\"\r\nfor i in range(len(board)):\r\nfor j in range(len(board[0])):\r\nif board[i][j] == 0:\r\nreturn (i, j) # row, col\r\n\r\nreturn None<\/pre>\n<ul>\n<li>The function takes a 9&#215;9 2D matrix board and finds all the empty positions within the board. Here 0 means an empty space.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">def valid(board, num, pos):\r\n# Check row\r\nfor i in range(len(board[0])):\r\nif board[pos[0]][i] == num and pos[1] != i:\r\nreturn False\r\n\r\n# Check column\r\nfor i in range(len(board)):\r\nif board[i][pos[1]] == num and pos[0] != i:\r\nreturn False\r\n\r\n# Check box\r\nbox_x = pos[1] \/\/ 3\r\nbox_y = pos[0] \/\/ 3\r\n\r\nfor i in range(box_y*3, box_y*3 + 3):\r\nfor j in range(box_x * 3, box_x*3 + 3):\r\nif board[i][j] == num and (i,j) != pos:\r\nreturn False\r\n\r\nreturn True<\/pre>\n<ul>\n<li>The <strong>valid<\/strong> function also takes the same board as input and validates if the board can be solved or not.<\/li>\n<li>It takes a number from the board and checks if the same number is existing in the row or column or the same subgrid.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">def solve(board):\r\nfind = find_empty(board)\r\nif not find:\r\nreturn True\r\nelse:\r\nrow, col = find\r\n\r\nfor i in range(1,10):\r\nif valid(board, i, (row, col)):\r\nboard[row][col] = i\r\n\r\nif solve(board):\r\nreturn True\r\nboard[row][col] = 0\r\nreturn False<\/pre>\n<ul>\n<li>The solve function loop through each empty and nonempty element.<\/li>\n<li>It validates the number and wherever it finds an empty space it puts a validated number between 1-9.<\/li>\n<li>The loop continues until it fills up all the empty spaces and validates each digit of the board.<\/li>\n<li>If the board is solved then it returns True, otherwise, it returns False.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">def get_board(bo):\r\nif solve(bo):\r\nreturn bo\r\nelse:\r\nraise ValueError<\/pre>\n<ul>\n<li>And finally, the get_board function calls the solve function. If the board is solved then it returns the solved board, otherwise, it raises a ValueError.<\/li>\n<\/ul>\n<p>Now the main program where we actually solve and preview the solved sudoku.<\/p>\n<h3><strong>Steps :<\/strong><\/h3>\n<p>1. Import necessary packages.<br \/>\n2. Find sudoku board in an image.<br \/>\n3. Split the board.<br \/>\n4. Predict digits of each box.<br \/>\n5. Solve the board.<\/p>\n<p><strong>Sudoku-Solver.py<\/strong><\/p>\n<h4>1. Import necessary packages:<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># DataFlair Sudoku solver\r\n\r\nimport cv2\r\nimport numpy as np\r\nfrom tensorflow.keras.models import load_model\r\nimport imutils\r\nfrom solver import *<\/pre>\n<ul>\n<li>Import all the required packages for the project.<\/li>\n<\/ul>\n<h4>2. Find sudoku board in an image:<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># Read image\r\nimg = cv2.imread('sudoku1.jpg')\r\ncv2.imshow(\"Input image\", img)<\/pre>\n<ul>\n<li>First read an image using cv2.imread() function.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">def find_board(img):\r\n\"\"\"Takes an image as input and finds a sudoku board inside of the image\"\"\"\r\ngray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\r\nbfilter = cv2.bilateralFilter(gray, 13, 20, 20)\r\nedged = cv2.Canny(bfilter, 30, 180)\r\nkeypoints = cv2.findContours(edged.copy(), cv2.RETR_TREE,\r\ncv2.CHAIN_APPROX_SIMPLE)\r\ncontours = imutils.grab_contours(keypoints)\r\nnewimg = cv2.drawContours(img.copy(), contours, -1, (0, 255, 0), 3)\r\ncv2.imshow(\"Contour\", newimg)<\/pre>\n<ul>\n<li>We\u2019ll try to find the board using contour detection.<\/li>\n<li>To detect contours we need to convert the image into the grayscale mode, so using cv2.cvtColor() we convert the image into grayscale mode.<\/li>\n<li>cv2.bilateralFilter() removes some noises from the image.<\/li>\n<li>Using cv2.Canny() we detect edges in the image.<\/li>\n<li>And then we detect all the continuous points within the edges using cv2.findContours. These continuous points are called contours.<\/li>\n<\/ul>\n<p>Output:<\/p>\n<p><a href=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/contour.webp\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-103875\" src=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/contour.webp\" alt=\"contour\" width=\"1920\" height=\"1028\" srcset=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/contour.webp 1920w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/contour-768x411.webp 768w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/contour-1536x822.webp 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">contour.png\r\n\r\ncontours = sorted(contours, key=cv2.contourArea, reverse=True)[:15]\r\nlocation = None\r\n# Finds rectangular contour\r\nfor contour in contours:\r\napprox = cv2.approxPolyDP(contour, 15, True)\r\nif len(approx) == 4:\r\nlocation = approx\r\nbreak\r\nresult = get_perspective(img, location)\r\nreturn result, location<\/pre>\n<ul>\n<li>Now we sort the contours by their area size using the sorted function and take the first 10 detected contours.<\/li>\n<li>We know that sudoku boards are rectangular. So we loop through all the contours and check if the contour is rectangular or not. We do it using cv2.approxPolyDP() function.<\/li>\n<li>If the length of the contour is 4 then it is considered a rectangle.<\/li>\n<li>After that, we get a perspective transformation of that board and extract it from the main image.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">def get_perspective(img, location, height = 900, width = 900):\r\n\"\"\"Takes an image and location of an interesting region.\r\nAnd return the only selected region with a perspective transformation\"\"\"\r\npts1 = np.float32([location[0], location[3], location[1], location[2]])\r\npts2 = np.float32([[0, 0], [width, 0], [0, height], [width, height]])\r\n\r\n# Apply Perspective Transform Algorithm\r\nmatrix = cv2.getPerspectiveTransform(pts1, pts2)\r\nresult = cv2.warpPerspective(img, matrix, (width, height))\r\nreturn result<\/pre>\n<ul>\n<li>Perspective transformation is also known as a birds-eye view. Perspective transformation is used to get a better insight into a given image or video. In perspective transformation, a selected region from an image is projected into another plane.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-perspective-transformation.webp\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-103876\" src=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-perspective-transformation.webp\" alt=\"perspective transformation\" width=\"960\" height=\"452\" srcset=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-perspective-transformation.webp 960w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-perspective-transformation-768x362.webp 768w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/><\/a><\/p>\n<ul>\n<li>Pts1 points will be selected from the given image and pts2 is the point of another plane where the selected region will be projected.<\/li>\n<li>cv2.getPerspectiveTransformation() returns the matrix of the transformation and the cv2.warpPerspective() gives the actual transformed image.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">board, location = find_board(img)\r\ncv2.imshow(\"Board\", board)<\/pre>\n<p><strong>Output<\/strong>:<\/p>\n<p><a href=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/board.webp\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-103877\" src=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/board.webp\" alt=\"board\" width=\"1920\" height=\"1028\" srcset=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/board.webp 1920w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/board-768x411.webp 768w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/board-1536x822.webp 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<h4>3. Split the board:<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># split the board into 81 individual images\r\ndef split_boxes(board):\r\n\"\"\"Takes a sudoku board and split it into 81 cells.\r\neach cell contains an element of that board either given or an empty cell.\"\"\"\r\nrows = np.vsplit(board,9)\r\nboxes = []\r\nfor r in rows:\r\ncols = np.hsplit(r,9)\r\nfor box in cols:\r\nbox = cv2.resize(box, (input_size, input_size))\/255.0\r\ncv2.imshow(\"Splitted block\", box)\r\ncv2.waitKey(50)\r\nboxes.append(box)\r\nreturn boxes<\/pre>\n<ul>\n<li>Sudoku contains a total of 81 numbers. And we want to classify each number individually.<\/li>\n<li>The split_boxes() function takes a board and splits it into 81 images or blocks.<\/li>\n<li>np.vsplit() splits an image vertically and np.hsplit() splits an image horizontally.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">gray = cv2.cvtColor(board, cv2.COLOR_BGR2GRAY)\r\nrois = split_boxes(gray)\r\nrois = np.array(rois).reshape(-1, input_size, input_size, 1)<\/pre>\n<h4>4. Predict digits of each box:<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">classes = np.arange(0, 10)\r\n\r\nmodel = load_model('model-OCR.h5')\r\n\r\n# get prediction\r\nprediction = model.predict(rois)\r\n# print(prediction)\r\n\r\npredicted_numbers = []\r\n# get classes from prediction\r\nfor i in prediction:\r\nindex = (np.argmax(i))\r\npredicted_number = classes[index]\r\npredicted_numbers.append(predicted_number)\r\n\r\nprint(predicted_numbers)<\/pre>\n<ul>\n<li>We have a total of 9 classes to predict. np.arange(0,10) creates an array containing 0 to 9.<\/li>\n<li>Using the load_model function we load the pre-trained model.<br \/>\nmodel.predict(rois) predicts all total 81 digits at once. It returns an array containing 81 predictions. Each prediction array contains 9 elements.<\/li>\n<li>Then we iterate through each prediction and get the index of the max element using np.argmax().<\/li>\n<li>After that, we get the final predicted number from the classes list.<\/li>\n<\/ul>\n<h4>5. Solve the board:<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># reshape the list\r\nboard_num = np.array(predicted_numbers).astype('uint8').reshape(9, 9)<\/pre>\n<ul>\n<li>The solver program takes a 9&#215;9 2D matrix. But our predicted list is a 1D flat list. So we reshaped the list first.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># solve the board\r\ntry:\r\nsolved_board_nums = get_board(board_num)<\/pre>\n<ul>\n<li>After that we fed the matrix to the get_board() function from the solver program. It returns a 9*9 solved matrix.<\/li>\n<\/ul>\n<p>But we want to preview the solved board in the main input image. So let&#8217;s do that.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">def displayNumbers(img, numbers, color=(0, 255, 0)):\r\nW = int(img.shape[1]\/9)\r\nH = int(img.shape[0]\/9)\r\nfor i in range (9):\r\nfor j in range (9):\r\nif numbers[(j*9)+i] !=0:\r\ncv2.putText(img, str(numbers[(j*9)+i]),\r\n(i*W+int(W\/2)-int((W\/4)),int((j+0.7)*H)),\r\ncv2.FONT_HERSHEY_COMPLEX, 2, color,\r\n2, cv2.LINE_AA)\r\nreturn img<\/pre>\n<ul>\n<li>The displayNumbers() function displays numbers to an image.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">def get_InvPerspective(img, masked_num, location, height = 900, width = 900):\r\n\"\"\"Takes original image as input\"\"\"\r\npts1 = np.float32([[0, 0], [width, 0], [0, height], [width, height]])\r\npts2 = np.float32([location[0], location[3], location[1], location[2]])\r\n\r\n# Apply Perspective Transform Algorithm\r\nmatrix = cv2.getPerspectiveTransform(pts1, pts2)\r\nresult = cv2.warpPerspective(masked_num, matrix, (img.shape[1],\r\nimg.shape[0]))\r\nreturn result<\/pre>\n<ul>\n<li>get_InvPerspective is exact the opposite of the get_perspective() function. It takes an image and projects it into another planes selected region.<\/li>\n<\/ul>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">binArr = np.where(np.array(predicted_numbers)&gt;0, 0, 1)\r\nprint(binArr)\r\n# get only solved numbers for the solved board\r\nflat_solved_board_nums = solved_board_nums.flatten()*binArr\r\n# create a mask\r\nmask = np.zeros_like(board)\r\nsolved_board_mask = displayNumbers(mask, flat_solved_board_nums)\r\ncv2.imshow(\"Solved Mask\", solved_board_mask)<\/pre>\n<ul>\n<li>First, we create a binary array of 0 and 1 from the predicted unsolved array. If an element is greater than 0, that will be added to the binary array as 1 and the rest of the element as 0.<\/li>\n<li>Then we create a blank mask of the same size as the board using np.zeros_like().<\/li>\n<li>The displayNumbers() function displays only solved digits in the mask.<\/li>\n<\/ul>\n<p><strong>Output:<\/strong><\/p>\n<p><a href=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/solved-mask.webp\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-103878\" src=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/solved-mask.webp\" alt=\"solved mask\" width=\"1920\" height=\"1028\" srcset=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/solved-mask.webp 1920w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/solved-mask-768x411.webp 768w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/solved-mask-1536x822.webp 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\"># Get inverse perspective\r\ninv = get_InvPerspective(img, solved_board_mask, location)<\/pre>\n<p><strong>Output:<\/strong><\/p>\n<p><a href=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/inverse.webp\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-103879\" src=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/inverse.webp\" alt=\"inverse\" width=\"1920\" height=\"1028\" srcset=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/inverse.webp 1920w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/inverse-768x411.webp 768w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/inverse-1536x822.webp 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">combined = cv2.addWeighted(img, 0.7, inv, 1, 0)\r\ncv2.imshow(\"Final result\", combined)\r\ncv2.waitKey(0)\r\n\r\nexcept:\r\nprint(\"Solution doesn't exist. Model misread digits.\")<\/pre>\n<ul>\n<li>Finally, we combined the inverse mask and the original image.<\/li>\n<\/ul>\n<h3>OpenCV Sudoku Solver Output:<\/h3>\n<p><a href=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/opencv-sudoku-solver-output.webp\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-103880\" src=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/opencv-sudoku-solver-output.webp\" alt=\"opencv sudoku solver output\" width=\"1920\" height=\"1028\" srcset=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/opencv-sudoku-solver-output.webp 1920w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/opencv-sudoku-solver-output-768x411.webp 768w, https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/opencv-sudoku-solver-output-1536x822.webp 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<h3>Summary<\/h3>\n<p>Sudoku is a popular number puzzle game. Solving it by hand takes time, but using Python and OpenCV, we can build a smart Sudoku solver. This project uses computer vision to read a Sudoku puzzle from an image and machine learning or backtracking algorithms to solve it. It\u2019s a fun way to combine image recognition with logic-based problem solving.<\/p>\n<p>In this project, we built OpenCV sudoku solver algorithm that detects sudoku board from an image and then solves it. Through this project, we\u2019ve learned about deep learning, image transformation, and some other image processing operations.<span hidden class=\"__iawmlf-post-loop-links\" data-iawmlf-links=\"[{&quot;id&quot;:2545,&quot;href&quot;:&quot;https:\\\/\\\/drive.google.com\\\/file\\\/d\\\/1r3xRywHmcvkSF61Wm9SFvkVmx50RcMJN\\\/view?usp=drive_link&quot;,&quot;archived_href&quot;:&quot;http:\\\/\\\/web-wp.archive.org\\\/web\\\/20260601071934\\\/https:\\\/\\\/drive.google.com\\\/file\\\/d\\\/1r3xRywHmcvkSF61Wm9SFvkVmx50RcMJN\\\/view?usp=drive_link&quot;,&quot;redirect_href&quot;:&quot;&quot;,&quot;checks&quot;:[{&quot;date&quot;:&quot;2026-06-01 12:08:15&quot;,&quot;http_code&quot;:200},{&quot;date&quot;:&quot;2026-06-05 20:12:05&quot;,&quot;http_code&quot;:200}],&quot;broken&quot;:false,&quot;last_checked&quot;:{&quot;date&quot;:&quot;2026-06-05 20:12:05&quot;,&quot;http_code&quot;:200},&quot;process&quot;:&quot;done&quot;}]\"><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We all played sudoku at least once in our childhood. It is a very interesting puzzle game. In this project, we\u2019re going to build a sudoku solver program using OpenCV. It detects a sudoku&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":103874,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[36],"tags":[25549,25729,21082,25730,25731,25550],"class_list":["post-102264","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-machine-learning","tag-opencv-sudoku-solver","tag-python-opencv-project","tag-python-project","tag-python-sudoku-solver","tag-sudoku-solver","tag-sudoku-solver-machine-learning"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Sudoku Solver using OpenCV &amp; Python - DataFlair<\/title>\n<meta name=\"description\" content=\"Build a sudoku solver algorithm using Machine Learning with OpenCV in Python. It detects sudoku board from an image and then solves it.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sudoku Solver using OpenCV &amp; Python - DataFlair\" \/>\n<meta property=\"og:description\" content=\"Build a sudoku solver algorithm using Machine Learning with OpenCV in Python. It detects sudoku board from an image and then solves it.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/\" \/>\n<meta property=\"og:site_name\" content=\"DataFlair\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/DataFlairWS\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-10-26T03:30:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-06-01T07:03:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-solver-opencv-python.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"DataFlair Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@DataFlairWS\" \/>\n<meta name=\"twitter:site\" content=\"@DataFlairWS\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"DataFlair Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Sudoku Solver using OpenCV &amp; Python - DataFlair","description":"Build a sudoku solver algorithm using Machine Learning with OpenCV in Python. It detects sudoku board from an image and then solves it.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/","og_locale":"en_US","og_type":"article","og_title":"Sudoku Solver using OpenCV &amp; Python - DataFlair","og_description":"Build a sudoku solver algorithm using Machine Learning with OpenCV in Python. It detects sudoku board from an image and then solves it.","og_url":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/","og_site_name":"DataFlair","article_publisher":"https:\/\/www.facebook.com\/DataFlairWS\/","article_published_time":"2021-10-26T03:30:52+00:00","article_modified_time":"2026-06-01T07:03:43+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-solver-opencv-python.webp","type":"image\/webp"}],"author":"DataFlair Team","twitter_card":"summary_large_image","twitter_creator":"@DataFlairWS","twitter_site":"@DataFlairWS","twitter_misc":{"Written by":"DataFlair Team","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/#article","isPartOf":{"@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/"},"author":{"name":"DataFlair Team","@id":"https:\/\/data-flair.training\/blogs\/#\/schema\/person\/b49855299264df5e27e3ec6c2cd9fde9"},"headline":"Sudoku Solver using OpenCV &amp; Python","datePublished":"2021-10-26T03:30:52+00:00","dateModified":"2026-06-01T07:03:43+00:00","mainEntityOfPage":{"@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/"},"wordCount":1241,"commentCount":3,"publisher":{"@id":"https:\/\/data-flair.training\/blogs\/#organization"},"image":{"@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/#primaryimage"},"thumbnailUrl":"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-solver-opencv-python.webp","keywords":["OpenCV Sudoku Solver","python opencv project","Python project","python sudoku solver","sudoku solver","Sudoku Solver Machine learning"],"articleSection":["Machine Learning Tutorials"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/","url":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/","name":"Sudoku Solver using OpenCV &amp; Python - DataFlair","isPartOf":{"@id":"https:\/\/data-flair.training\/blogs\/#website"},"primaryImageOfPage":{"@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/#primaryimage"},"image":{"@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/#primaryimage"},"thumbnailUrl":"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-solver-opencv-python.webp","datePublished":"2021-10-26T03:30:52+00:00","dateModified":"2026-06-01T07:03:43+00:00","description":"Build a sudoku solver algorithm using Machine Learning with OpenCV in Python. It detects sudoku board from an image and then solves it.","breadcrumb":{"@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/#primaryimage","url":"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-solver-opencv-python.webp","contentUrl":"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2021\/10\/sudoku-solver-opencv-python.webp","width":1200,"height":628,"caption":"sudoku solver opencv python"},{"@type":"BreadcrumbList","@id":"https:\/\/data-flair.training\/blogs\/opencv-sudoku-solver\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Blog Home","item":"https:\/\/data-flair.training\/blogs\/"},{"@type":"ListItem","position":2,"name":"Machine Learning Tutorials","item":"https:\/\/data-flair.training\/blogs\/category\/machine-learning\/"},{"@type":"ListItem","position":3,"name":"Sudoku Solver using OpenCV &amp; Python"}]},{"@type":"WebSite","@id":"https:\/\/data-flair.training\/blogs\/#website","url":"https:\/\/data-flair.training\/blogs\/","name":"DataFlair","description":"Learn Today. Lead Tomorrow.","publisher":{"@id":"https:\/\/data-flair.training\/blogs\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/data-flair.training\/blogs\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/data-flair.training\/blogs\/#organization","name":"DataFlair","url":"https:\/\/data-flair.training\/blogs\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/data-flair.training\/blogs\/#\/schema\/logo\/image\/","url":"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2016\/07\/Data-Flair.png","contentUrl":"https:\/\/data-flair.training\/blogs\/wp-content\/uploads\/sites\/2\/2016\/07\/Data-Flair.png","width":106,"height":48,"caption":"DataFlair"},"image":{"@id":"https:\/\/data-flair.training\/blogs\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/DataFlairWS\/","https:\/\/x.com\/DataFlairWS","https:\/\/www.linkedin.com\/company\/dataflair-web-services-pvt-ltd\/","https:\/\/www.youtube.com\/user\/DataFlairWS"]},{"@type":"Person","@id":"https:\/\/data-flair.training\/blogs\/#\/schema\/person\/b49855299264df5e27e3ec6c2cd9fde9","name":"DataFlair Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/ef46b745ddad2fad690af626c6ef29b91809ad0a9f5ef398d07817d8cad042f5?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/ef46b745ddad2fad690af626c6ef29b91809ad0a9f5ef398d07817d8cad042f5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ef46b745ddad2fad690af626c6ef29b91809ad0a9f5ef398d07817d8cad042f5?s=96&d=mm&r=g","caption":"DataFlair Team"},"description":"DataFlair Team is a group of passionate educators and industry experts dedicated to providing high-quality online learning resources on programming, Java, Python, C++, DSA, AI, ML, data Science, Android, Flutter, MERN, Web Development, and technology. With years of experience in the field, the team aims to simplify complex topics and help learners advance their careers. At DataFlair, we believe in empowering students and professionals with the knowledge and skills needed to thrive in today\u2019s fast-paced tech industry. Follow us for Free courses, expert insights, tutorials, and practical tips to boost your learning journey.","url":"https:\/\/data-flair.training\/blogs\/author\/datafbdad\/"}]}},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/posts\/102264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/comments?post=102264"}],"version-history":[{"count":7,"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/posts\/102264\/revisions"}],"predecessor-version":[{"id":148619,"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/posts\/102264\/revisions\/148619"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/media\/103874"}],"wp:attachment":[{"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/media?parent=102264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/categories?post=102264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/data-flair.training\/blogs\/wp-json\/wp\/v2\/tags?post=102264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}