#include #include #include #include #include using namespace cv; int main() { char* file = "sample-sudoku-input.jpg"; Mat colorImg = imread(file, IMREAD_COLOR); if (!colorImg.data) { std::cout << "Could not open/find image." << std::endl; return -1; } Mat grayImg, bwImg, processedImg; cvtColor(colorImg, grayImg, COLOR_BGR2GRAY); threshold(grayImg, bwImg, 100, 255, 1); Mat element = getStructuringElement(MORPH_CROSS, Size(3,3), Point(1,1)); dilate(bwImg, processedImg, element); erode(processedImg, processedImg, element); Size sizeImg = processedImg.size(); int iRow, iCol, pixels; int horizontalLines[100]; int iHorizontal = 0; int verticalLines[100]; int iVertical = 0; // Find Horizontal Rows for (iRow = 0; iRow < (int) sizeImg.height; iRow++) { pixels = 0; for (iCol = 0; iCol < (int) sizeImg.width; iCol++) { if (processedImg.at(iRow, iCol) == -1) { pixels++; } } if (pixels > (.5 * sizeImg.width)) { horizontalLines[iHorizontal++] = iRow; } } // Find Vertical Rows for (iCol = 0; iCol < (int) sizeImg.width; iCol++) { pixels = 0; for (iRow = 0; iRow < (int) sizeImg.height; iRow++) { if (processedImg.at(iRow, iCol) == -1) { pixels++; } } if (pixels > (.5 * sizeImg.height)) { verticalLines[iVertical++] = iCol; } } Mat linesImg, numberImg; linesImg = Mat::zeros(sizeImg, processedImg.type()); numberImg = Mat::zeros(sizeImg, processedImg.type()); // Copy Horizontal Rows for (iRow = 0; iRow < iHorizontal; iRow++) { int row = horizontalLines[iRow]; for (iCol = 0; iCol < (int) sizeImg.width; iCol++) { linesImg.at(row, iCol) = processedImg.at(row, iCol); } } // Copy Vertical Lines for (iCol = 0; iCol < iVertical; iCol++) { int col = verticalLines[iCol]; for (iRow = 0; iRow < (int) sizeImg.height; iRow++) { linesImg.at(iRow, col) = processedImg.at(iRow, col); } } // Get Number Image numberImg = processedImg - linesImg; namedWindow("Gray", WINDOW_AUTOSIZE); imshow("Gray", grayImg); waitKey(0); namedWindow("BW", WINDOW_AUTOSIZE); imshow("BW", bwImg); waitKey(0); namedWindow("Processed", WINDOW_AUTOSIZE); imshow("Processed", processedImg); waitKey(0); namedWindow("Lines", WINDOW_AUTOSIZE); imshow("Lines", linesImg); waitKey(0); namedWindow("Numbers", WINDOW_AUTOSIZE); imshow("Numbers", numberImg); waitKey(0); // Remove Noise erode(numberImg, numberImg, element); dilate(numberImg, numberImg, element); namedWindow("Processed Numbers", WINDOW_AUTOSIZE); imshow("Processd Numbers", numberImg); waitKey(0); destroyWindow("Gray"); destroyWindow("BW"); destroyWindow("Processed"); destroyWindow("Lines"); destroyWindow("Numbers"); destroyWindow("Processed Numbers"); }