Please bookmark this page to avoid losing your image tool!

Image Verb Identifier

(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.
async function processImage(originalImg, confidenceThreshold = 0.5) {

    /**
     * Dynamically loads a script and returns a promise that resolves when it's loaded.
     * Caches promises to avoid reloading the same script.
     * @param {string} url The URL of the script to load.
     * @param {string} id A unique ID for the script tag.
     * @returns {Promise<void>}
     */
    const _loadScript = (url, id) => {
        if (!window._scriptPromises) {
            window._scriptPromises = {};
        }
        if (!window._scriptPromises[id]) {
            window._scriptPromises[id] = new Promise((resolve, reject) => {
                if (document.getElementById(id)) {
                    return resolve();
                }
                const script = document.createElement('script');
                script.src = url;
                script.id = id;
                script.onload = () => resolve();
                script.onerror = (err) => {
                    delete window._scriptPromises[id];
                    reject(err);
                };
                document.head.appendChild(script);
            });
        }
        return window._scriptPromises[id];
    };

    /**
     * A dictionary mapping pairs or groups of detected nouns to specific verbs.
     * Keys are sorted object class names, joined by a comma.
     */
    const interactionMap = {
        'person,bicycle': ['riding'],
        'person,car': ['driving'],
        'person,motorcycle': ['riding'],
        'person,skateboard': ['skateboarding'],
        'person,surfboard': ['surfing'],
        'person,skis': ['skiing'],
        'person,snowboard': ['snowboarding'],
        'person,horse': ['riding'],
        'person,sports ball': ['playing', 'throwing', 'catching'],
        'person,frisbee': ['throwing', 'catching'],
        'person,kite': ['flying'],
        'person,baseball bat': ['swinging', 'playing baseball'],
        'person,baseball glove': ['catching', 'playing baseball'],
        'person,tennis racket': ['playing tennis'],
        'person,cell phone': ['talking', 'texting', 'using'],
        'person,laptop': ['working', 'typing', 'using'],
        'person,keyboard': ['typing'],
        'person,book': ['reading'],
        'person,chair': ['sitting'],
        'person,couch': ['sitting', 'resting'],
        'person,bed': ['sleeping', 'lying down'],
        'person,dining table': ['eating', 'sitting'],
        'person,fork': ['eating'],
        'person,knife': ['eating', 'cutting'],
        'person,spoon': ['eating'],
        'person,bowl': ['eating'],
        'person,cup': ['drinking'],
        'person,wine glass': ['drinking'],
        'person,bottle': ['drinking'],
        'person,sandwich': ['eating'],
        'person,pizza': ['eating'],
        'person,donut': ['eating'],
        'person,cake': ['eating'],
        'person,toothbrush': ['brushing teeth'],
        'person,umbrella': ['holding'],
    };

    /**
     * A dictionary mapping single detected nouns to generic verbs.
     * This is used as a fallback if no specific interaction is found.
     */
    const nounToVerbMap = {
        'person': ['standing', 'posing', 'looking'],
        'bird': ['flying', 'perching'],
        'cat': ['sitting', 'sleeping', 'playing'],
        'dog': ['running', 'playing', 'sitting'],
        'horse': ['running', 'grazing', 'standing'],
        'boat': ['sailing', 'floating'],
        'airplane': ['flying', 'landing'],
        'train': ['traveling', 'moving'],
        'car': ['parking'],
        'motorcycle': ['parking'],
        'bus': ['driving'],
        'truck': ['driving'],
    };

    const canvas = document.createElement('canvas');
    const FONT_SIZE = Math.max(16, Math.min(originalImg.width, originalImg.height) / 30);
    const PADDING = FONT_SIZE / 2;
    canvas.width = originalImg.width;
    canvas.height = originalImg.height;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(originalImg, 0, 0);

    /**
     * Helper function to draw text on the canvas with a background.
     * @param {string} text The text to display.
     */
    const drawTextOnCanvas = (text) => {
        ctx.font = `bold ${FONT_SIZE}px 'Arial', sans-serif`;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        
        const textMetrics = ctx.measureText(text);
        const textWidth = textMetrics.width;
        const boxHeight = FONT_SIZE + PADDING * 2;
        const boxY = canvas.height - boxHeight;

        ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
        ctx.fillRect(0, boxY, canvas.width, boxHeight);

        ctx.fillStyle = 'white';
        ctx.fillText(text, canvas.width / 2, boxY + boxHeight / 2);
    };

    drawTextOnCanvas('Analyzing image, please wait...');

    try {
        await _loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.11.0/dist/tf.min.js', 'tfjs_script');
        await _loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd@2.2.2/dist/coco-ssd.min.js', 'cocossd_script');

        // Ensure tf is ready, sometimes there can be a race condition.
        await tf.ready();
        
        const model = await cocoSsd.load();
        const predictions = await model.detect(originalImg);
        const filteredPredictions = predictions.filter(p => p.score >= confidenceThreshold);

        const detectedNouns = new Set(filteredPredictions.map(p => p.class));
        const identifiedVerbs = new Set();
        const usedNouns = new Set();

        // 1. Check for specific interactions first
        for (const key in interactionMap) {
            const nounsInKey = key.split(',');
            const isInteractionPresent = nounsInKey.every(noun => detectedNouns.has(noun));
            
            if (isInteractionPresent) {
                interactionMap[key].forEach(verb => identifiedVerbs.add(verb));
                nounsInKey.forEach(noun => usedNouns.add(noun));
            }
        }

        // 2. Add generic verbs for nouns that were not part of an interaction
        detectedNouns.forEach(noun => {
            if (!usedNouns.has(noun) && nounToVerbMap[noun]) {
                nounToVerbMap[noun].forEach(verb => identifiedVerbs.add(verb));
            }
        });

        // Redraw image to clear the loading message
        ctx.drawImage(originalImg, 0, 0);

        if (identifiedVerbs.size > 0) {
            const verbString = Array.from(identifiedVerbs).join(', ');
            drawTextOnCanvas(`Potential Verbs: ${verbString}`);
        } else {
            drawTextOnCanvas('No specific actions identified.');
        }

    } catch (error) {
        console.error("Image processing error:", error);
        ctx.drawImage(originalImg, 0, 0); // Redraw to be safe
        drawTextOnCanvas('Error: Could not analyze the image.');
    }

    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 Verb Identifier is a tool that analyzes images to identify potential action verbs associated with objects and scenes within the image. It utilizes machine learning models to detect various nouns, such as people and objects, and maps them to corresponding verbs like ‘riding’, ‘driving’, or ‘playing’. This tool can be useful for various applications including content creation, educational tools, accessibility features, and enhancing user interactions in photo-sharing platforms. By providing insights into the actions depicted in an image, users can gain a deeper understanding of the visual content.

Leave a Reply

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