From 8ce63b86116d69b112c2288395e6764b5546ecf3 Mon Sep 17 00:00:00 2001 From: Dor-sketch Date: Thu, 27 Jun 2024 00:18:07 +0300 Subject: [PATCH] WIP --- docs/index.html | 31 +++++++++++++++------------- docs/worker.js | 55 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/docs/index.html b/docs/index.html index c4cd417..b29eb0b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -262,16 +262,15 @@ 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; @@ -279,14 +278,7 @@ // 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(); @@ -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 = []; @@ -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; @@ -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; diff --git a/docs/worker.js b/docs/worker.js index 575248a..17481f7 100644 --- a/docs/worker.js +++ b/docs/worker.js @@ -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); @@ -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; } \ No newline at end of file