Please bookmark this page to avoid losing your image tool!

Image Food Product Counter

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
/**
 * Detects and counts food items in an image using a pre-trained AI model.
 * This function dynamically loads TensorFlow.js and the COCO-SSD model to perform object detection.
 * It then draws the original image on a canvas, highlights the detected food items with bounding boxes,
 * and displays a summary of the counts.
 *
 * @param {Image} originalImg The original input image as a JavaScript Image object.
 * @param {number} confidenceThreshold The minimum confidence score (0.0 to 1.0) for a detection to be counted. Default is 0.5.
 * @param {string} foodClasses A comma-separated string of food item names to detect. Defaults to items available in the COCO-SSD model.
 * @returns {Promise<HTMLCanvasElement>} A Promise that resolves with a canvas element containing the annotated image.
 */
async function processImage(originalImg, confidenceThreshold = 0.5, foodClasses = 'banana,apple,sandwich,orange,broccoli,carrot,hot dog,pizza,donut,cake') {

    // Helper to dynamically load a script and return a promise
    const loadScript = (url) => {
        return new Promise((resolve, reject) => {
            // Avoid re-loading the same script
            if (document.querySelector(`script[src="${url}"]`)) {
                // Wait for the global object to be available if script is already loading
                const checkInterval = setInterval(() => {
                    const globalName = url.includes('tfjs') ? 'tf' : 'cocoSsd';
                    if (window[globalName]) {
                        clearInterval(checkInterval);
                        resolve();
                    }
                }, 100);
                return;
            }
            const script = document.createElement('script');
            script.src = url;
            script.onload = resolve;
            script.onerror = () => reject(new Error(`Script load error for ${url}`));
            document.head.appendChild(script);
        });
    };

    // Helper to generate a consistent color from a string (for bounding boxes)
    const stringToColor = (str) => {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            hash = str.charCodeAt(i) + ((hash << 5) - hash);
        }
        let color = '#';
        for (let i = 0; i < 3; i++) {
            const value = (hash >> (i * 8)) & 0xFF;
            // Ensure the color is not too dark
            const clampedValue = Math.max(100, value);
            color += ('00' + clampedValue.toString(16)).substr(-2);
        }
        return color;
    };

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    canvas.width = originalImg.naturalWidth;
    canvas.height = originalImg.naturalHeight;
    ctx.drawImage(originalImg, 0, 0);

    // Display a loading message
    ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
    ctx.fillRect(0, canvas.height/2 - 25, canvas.width, 50);
    ctx.fillStyle = 'white';
    ctx.font = '24px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('Analyzing image with AI...', canvas.width / 2, canvas.height / 2 + 8);


    try {
        // Load the necessary AI model libraries from a CDN
        await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@3.11.0/dist/tf.min.js');
        await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd@2.2.2/dist/coco-ssd.min.js');

        // Load the COCO-SSD model.
        const model = await cocoSsd.load();

        // Run object detection on the image
        const predictions = await model.detect(originalImg);

        // Clear the loading message by redrawing the original image
        ctx.drawImage(originalImg, 0, 0);

        const targetClasses = foodClasses.split(',').map(item => item.trim().toLowerCase());
        const foodCounts = {};

        // Process each prediction
        predictions.forEach(prediction => {
            if (prediction.score > confidenceThreshold && targetClasses.includes(prediction.class)) {
                // Increment count for the detected class
                foodCounts[prediction.class] = (foodCounts[prediction.class] || 0) + 1;

                const [x, y, width, height] = prediction.bbox;
                const color = stringToColor(prediction.class);
                const label = `${prediction.class} (${Math.round(prediction.score * 100)}%)`;

                // Draw the bounding box
                ctx.strokeStyle = color;
                ctx.lineWidth = Math.max(2, canvas.width / 400);
                ctx.strokeRect(x, y, width, height);

                // Draw the label background
                ctx.fillStyle = color;
                const fontHeight = Math.max(16, canvas.width / 50);
                ctx.font = `${fontHeight}px Arial`;
                const textWidth = ctx.measureText(label).width;
                ctx.fillRect(x, y, textWidth + 10, fontHeight + 5);

                // Draw the label text
                ctx.fillStyle = '#000000';
                ctx.fillText(label, x + 5, y + fontHeight);
            }
        });


        // Draw the summary of counts in a semi-transparent box
        const summaryKeys = Object.keys(foodCounts);
        const boxHeight = (summaryKeys.length + 1) * 25 + 20;
        ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
        ctx.fillRect(5, 5, 220, boxHeight);
        
        ctx.fillStyle = '#FFFFFF';
        ctx.font = '20px Arial';
        let summaryTextY = 30;
        ctx.textAlign = 'left';
        ctx.fillText('Detected Food:', 15, summaryTextY);
        summaryTextY += 25;

        ctx.font = '16px Arial';
        if (summaryKeys.length === 0) {
           ctx.fillText('None', 15, summaryTextY);
        } else {
            summaryKeys.forEach(foodItem => {
                ctx.fillText(`• ${foodItem}: ${foodCounts[foodItem]}`, 15, summaryTextY);
                summaryTextY += 25;
            });
        }

    } catch (error) {
        console.error("Error processing image with AI model:", error);
        // Display an error message on the canvas
        ctx.drawImage(originalImg, 0, 0); // Redraw to clear loading message
        ctx.fillStyle = 'rgba(255, 0, 0, 0.7)';
        ctx.fillRect(0, canvas.height - 50, canvas.width, 50);
        ctx.fillStyle = 'white';
        ctx.font = '20px Arial';
        ctx.textAlign = 'center';
        ctx.fillText('Could not process image. Failed to load AI model.', canvas.width / 2, canvas.height - 20);
    }

    return canvas;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Image Food Product Counter is a tool that detects and counts specific food items within an uploaded image using an AI model. By leveraging advanced object detection algorithms, this tool can identify various food classes, including fruits, vegetables, and packaged foods. It highlights the detected items with bounding boxes on the image and provides a summary of the counts, making it useful for applications such as inventory management in grocery stores, food analytics for health apps, or even educational purposes to teach about food items and nutrition.

Leave a Reply

Your email address will not be published. Required fields are marked *