Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Dor-sketch committed Jun 26, 2024
1 parent 06e11b8 commit 8ce63b8
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 31 deletions.
31 changes: 17 additions & 14 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -262,31 +262,23 @@

const img = new Image();
img.onload = function () {
const MAX_WIDTH = 300;
const MAX_WIDTH = 500;
let targetWidth = img.width;
let targetHeight = img.height;

// Scale only if the image width is larger than MAX_WIDTH
if (img.width > MAX_WIDTH) {

const scale = MAX_WIDTH / img.width;
targetWidth = MAX_WIDTH; // Scale width to MAX_WIDTH
targetHeight = img.height * scale; // Scale height to maintain aspect ratio
}


canvas.width = targetWidth;
canvas.height = targetHeight;
ctx.drawImage(img, 0, 0, targetWidth, targetHeight);

// Binarize and enhance the image
let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

for (let i = 0; i < imageData.length; i += 4) {
const avg = data[i]; // Since the image is greyscale, we can just use the red channel
imageData[i] = avg < 128 ? 0 : 255;
imageData[i + 1] = imageData[i];
imageData[i + 2] = imageData[i];
}
ctx.putImageData(imageData, 0, 0);
imageData = binarizeImage(imageData);
ctx.putImageData(imageData, 0, 0);

const processedImageSrc = canvas.toDataURL();
Expand All @@ -299,6 +291,18 @@
});
}

function binarizeImage(imageData) {
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const avg = data[i] * 0.3 + data[i + 1] * 0.59 + data[i + 2] * 0.11; // Grayscale
const binarized = avg < 90 ? 0 : 255;
data[i] = binarized;
data[i + 1] = binarized;
data[i + 2] = binarized;
}
return imageData;
}


function setupWebWorkers(numWorkers) {
const workers = [];
Expand All @@ -325,7 +329,7 @@
const centerRegionSize = 0.5; // Sample the central 50% of the cell
for (let row = 0; row < 9; row++) {
for (let col = 0; col < 9; col++) {
// Calculate the coordinates for the central region of the cell
// Calculate the coordinates for the central region of the cell
const offsetX = (cellWidth * (1 - centerRegionSize)) / 2;
const offsetY = (cellHeight * (1 - centerRegionSize)) / 2;
const centerWidth = cellWidth * centerRegionSize;
Expand All @@ -347,7 +351,6 @@
const cellImageData = ctx.getImageData(col * cellWidth, row * cellHeight, cellWidth, cellHeight).data;
tasks.push({ width: cellWidth, height: cellHeight, imageData: cellImageData, row, col });
}

}
}
const numWorkers = Math.min(tasks.length, navigator.hardwareConcurrency) || 1;
Expand Down
55 changes: 38 additions & 17 deletions docs/worker.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
// Global storage for debug images
const debugImages = [];

importScripts('https://cdn.jsdelivr.net/npm/tesseract.js@4/dist/tesseract.min.js');

self.onmessage = async function(e) {
const { width, height, imageData, row, col } = e.data;
const result = await extractSudokuNumber(width, height, imageData);
const result = await extractSudokuNumber(width, height, imageData, row, col);
self.postMessage({ result });
};
async function extractSudokuNumber(cellWidth, cellHeight, imageData) {

async function extractSudokuNumber(cellWidth, cellHeight, imageData, row, col) {
const cellImageData = new ImageData(new Uint8ClampedArray(imageData), cellWidth, cellHeight);

// Check for black pixels in the center of the cell
if (!hasBlackPixelsInCenter(cellImageData)) {
if (!hasBlackPixelsInSampledLines(cellImageData)) {
console.log('No black pixels found in cell at row:', row, 'col:', col);
return '.'; // Return '.' immediately if no black pixels are found
}

// Save the cell image data for debugging
debugImages.push({ row, col, imageData: cellImageData });

// Convert ImageData to Blob as Tesseract.js can work with Blob for recognition
const blob = await new Promise(resolve => {
const canvas = new OffscreenCanvas(cellWidth, cellHeight);
Expand All @@ -32,24 +40,37 @@ async function extractSudokuNumber(cellWidth, cellHeight, imageData) {

const digit = text.trim();
const validDigit = digit.length === 1 && '123456789'.includes(digit) ? digit : '.';
console.log('Extracted Digit:', validDigit);
console.log('Extracted Digit: ', validDigit, 'at row:', row, 'col:', col);
return validDigit;
}

function hasBlackPixelsInCenter(imageData) {
// Existing functions remain unchanged...
function hasBlackPixelsInSampledLines(imageData) {
const { width, height, data } = imageData;
const centerX = Math.floor(width / 2);
const centerY = Math.floor(height / 2);
const radius = Math.floor(Math.min(width, height) / 4); // Check a central square of the cell

for (let y = centerY - radius; y <= centerY + radius; y++) {
for (let x = centerX - radius; x <= centerX + radius; x++) {
const index = (y * width + x) * 4;
if (data[index] === 0 && data[index + 1] === 0 && data[index + 2] === 0 && data[index + 3] === 255) {
// Found a black pixel (RGBA)
return true;
}

// Define lines to sample: 25% and 75% for both horizontal and vertical
const rowsToCheck = [Math.floor(height * 0.25), Math.floor(height * 0.75)];
const colsToCheck = [Math.floor(width * 0.25), Math.floor(width * 0.75)];

// Check horizontal lines
for (let y of rowsToCheck) {
for (let x = 0; x < width; x++) {
if (isBlackPixel(data, y, x, width)) return true;
}
}
return false; // No black pixels found

// Check vertical lines
for (let x of colsToCheck) {
for (let y = 0; y < height; y++) {
if (isBlackPixel(data, y, x, width)) return true;
}
}

return false; // No black pixels found in sampled lines
}

// Helper function to check if a pixel is black
function isBlackPixel(data, y, x, width) {
const index = (y * width + x) * 4;
return data[index] === 0 && data[index + 1] === 0 && data[index + 2] === 0 && data[index + 3] === 255;
}

0 comments on commit 8ce63b8

Please sign in to comment.