# Sudoku Solver (Part 1)

Mar 23 · 7 min read

# Step1: Read the image using opencv. Here original.jpg refers to my camera photo.

`frame = cv2.imread('original.jpg')`

# Step2: Convert this image into grayscale image.

`gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)cv2.imwrite('gray' , gray)`

`def AdaptiveThresholding(gray): gray=cv2.adaptiveThreshold(gray,200,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,11,3) return gray`

# Step4 : Opening Operation

`kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))gray = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)cv2.imwrite('morph.jpg',gray)`

# Step5 : Getting Sudoku

`contours,h=cv2.findContours(gray,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)`
`contour = max(contours, key=cv2.contourArea)`
`x, y, w, h = cv2.boundingRect(contour)sudoku = gray[y:y + h, x:x + w]side_length = min(sudoku.shape)sudoku = cv2.resize(sudoku, (side_length, side_length))cv2.imwrite('sudoku.jpg' , sudoku)`

# Step6: Making Sudoku Straight

`contours, h = cv2.findContours(sudoku, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)`
`contours = sorted(contours, key=cv2.contourArea, reverse=True)`
`largest = Nonefor cnt in contours[:min(5,len(contours))]:  print ("Length of approx(cnt) : " + str(len(approx(cnt))) )  if (len(approx(cnt)) == 4)    print ("Condition becomes True")    largest = cnt`
`def approx(cnt): peri = cv2.arcLength(cnt, True) app = cv2.approxPolyDP(cnt, 0.01 * peri, True) return app`
`def order_points(pts): pts = pts.reshape(4, 2) rect = np.zeros((4, 2), dtype = "float32") s = pts.sum(axis = 1) rect[0] = pts[np.argmin(s)] rect[2] = pts[np.argmax(s)] diff = np.diff(pts, axis = 1) rect[1] = pts[np.argmin(diff)] rect[3] = pts[np.argmax(diff)] return rect`
`def four_points_transform(image,rect):  (tl,tr,br,bl) = rect  widthBottom = np.sqrt(((br[0] - bl[0])**2) + ((br[1] - bl[1]) **    2))  widthTop = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1])**2))  maxWidth = max(widthBottom , widthTop)  heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))  heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))  maxHeight = max(int(heightA), int(heightB))  dst = np.array([                 [0,0],                 [maxWidth - 1,0],                 [maxWidth-1 , maxHeight-1],                 [0,maxHeight-1]] , dtype = 'float32')  M = cv2.getPerspectiveTransform(rect,dst)  warped=cv2.warpPerspective(image,M,(int(maxWidth),int(maxHeight)))  return warped`
`if (largest is not None): app = approx(largest)  print ("App: " + str(len(app))) corners = order_points(app) sudoku = four_points_transform(sudoku,corners) print ("Done Straighten !!") cv2.imwrite("FinalSudoku.jpg" ,sudoku)`

Written by

## Anmol Dua

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just \$5/month. Upgrade