Please bookmark this page to avoid losing your image tool!

Image Cars Collector

(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.
function processImage(originalImg, confidenceThreshold = "0.5") {
    // We return a container to display loading states to the user
    // while the AI model downloads and runs asynchronously.
    const container = document.createElement('div');
    container.style.width = "100%";
    container.style.display = "flex";
    container.style.justifyContent = "center";
    container.style.alignItems = "center";
    container.style.backgroundColor = "#1e272e";
    container.style.padding = "20px";
    container.style.fontFamily = "sans-serif";
    container.style.boxSizing = "border-box";

    const canvas = document.createElement('canvas');
    canvas.style.maxWidth = "100%";
    canvas.style.maxHeight = "85vh";
    canvas.style.boxShadow = "0 8px 16px rgba(0,0,0,0.5)";
    canvas.style.borderRadius = "8px";
    container.appendChild(canvas);
    
    const ctx = canvas.getContext('2d');
    
    // Ensure we have a valid initial size
    const initW = originalImg.naturalWidth || originalImg.width || 600;
    const initH = originalImg.naturalHeight || originalImg.height || 400;
    
    canvas.width = initW;
    canvas.height = initH;
    
    let progress = 0.1;

    // Helper for loading screens
    const drawProcessingMessage = (msg) => {
        ctx.fillStyle = "#2d3436";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        ctx.fillStyle = "#dfe6e9";
        ctx.font = `bold ${Math.max(20, Math.floor(canvas.width / 25))}px sans-serif`;
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText(msg, canvas.width/2, canvas.height/2, canvas.width - 40);
        
        // Simple visual progress bar
        progress += 0.2;
        const currentProgress = Math.min(progress, 0.95);
        const barWidth = canvas.width * 0.4;
        const barHeight = 8;
        
        ctx.fillStyle = "#636e72";
        ctx.fillRect((canvas.width - barWidth) / 2, canvas.height / 2 + 30, barWidth, barHeight);
        ctx.fillStyle = "#0984e3";
        ctx.fillRect((canvas.width - barWidth) / 2, canvas.height / 2 + 30, barWidth * currentProgress, barHeight);
    };

    drawProcessingMessage("Initializing Collector Engine...");

    const minConfidence = parseFloat(confidenceThreshold) || 0.5;

    // Main Async Processor
    (async () => {
        try {
            // Function to dynamically load external scripts needed
            const loadScript = async (src, globalVar) => {
                if (window[globalVar]) return; // Already exists
                return new Promise((resolve, reject) => {
                    const script = document.createElement('script');
                    script.src = src;
                    script.onload = resolve;
                    script.onerror = reject;
                    document.head.appendChild(script);
                });
            };

            drawProcessingMessage("Loading TensorFlow.js...");
            await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow/tfjs', 'tf');
            
            drawProcessingMessage("Loading COCO-SSD Object Detector...");
            await loadScript('https://cdn.jsdelivr.net/npm/@tensorflow-models/coco-ssd', 'cocoSsd');

            drawProcessingMessage("Initializing AI Models...");
            const model = await window.cocoSsd.load();

            drawProcessingMessage("Scanning image for vehicles...");
            
            // Draw original image into an off-screen canvas to feed to model
            // This guarantees we only act on fully materialized pixel data
            const imgCanvas = document.createElement('canvas');
            imgCanvas.width = initW;
            imgCanvas.height = initH;
            const imgCtx = imgCanvas.getContext('2d');
            imgCtx.drawImage(originalImg, 0, 0, initW, initH);

            // Execute the model on our canvas
            const predictions = await model.detect(imgCanvas);
            
            // We want cars, trucks, and buses for a complete "car collector"
            const carClasses = ['car', 'truck', 'bus'];
            const carPredictions = predictions.filter(
                p => carClasses.includes(p.class) && p.score >= minConfidence
            );

            if (carPredictions.length === 0) {
                // Return case where no cars are detected
                ctx.fillStyle = "#2d3436";
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                
                ctx.fillStyle = "#ff7675";
                ctx.font = `bold ${Math.max(20, Math.floor(canvas.width / 25))}px sans-serif`;
                ctx.textAlign = "center";
                ctx.textBaseline = "middle";
                ctx.fillText("No cars found in this image.", canvas.width/2, canvas.height/2 - 20, canvas.width - 40);
                
                ctx.fillStyle = "#dfe6e9";
                ctx.font = `${Math.max(16, Math.floor(canvas.width / 35))}px sans-serif`;
                ctx.fillText("Check out the original image below.", canvas.width/2, canvas.height/2 + 20);
                
                // Show original after a small delay
                setTimeout(() => {
                    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
                }, 1500);
                return;
            }

            // Calculations for arranging collected cars in a neat grid
            const margin = 20;
            const cellSizeX = 300;
            const cellSizeY = 250; 
            
            const cols = Math.ceil(Math.sqrt(carPredictions.length));
            const rows = Math.ceil(carPredictions.length / cols);
            
            const headerHeight = 80;
            
            // Adjust canvas size to fit our newly generated collage
            canvas.width = cols * cellSizeX + (cols + 1) * margin;
            canvas.height = headerHeight + rows * cellSizeY + (rows + 1) * margin;
            
            // Paint collage background
            ctx.fillStyle = "#2d3436";
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // Header text
            ctx.fillStyle = "#74b9ff";
            ctx.font = "bold 34px sans-serif";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            ctx.fillText(`Image Cars Collector: Found ${carPredictions.length} Vehicle(s)`, canvas.width/2, headerHeight / 2);
            
            // Render each vehicle piece individually
            carPredictions.forEach((pred, index) => {
                const [x, y, w, h] = pred.bbox;
                const r = Math.floor(index / cols);
                const c = index % cols;
                
                const cellX = margin + c * (cellSizeX + margin);
                const cellY = headerHeight + margin + r * (cellSizeY + margin);
                
                // Card Shadow 
                ctx.fillStyle = "#dfe6e9";
                ctx.shadowColor = "rgba(0,0,0,0.8)";
                ctx.shadowBlur = 15;
                ctx.shadowOffsetX = 5;
                ctx.shadowOffsetY = 5;
                
                // Draw Card Background (Rounded Rectangle path for broad compatibility)
                const radius = 15;
                ctx.beginPath();
                ctx.moveTo(cellX + radius, cellY);
                ctx.lineTo(cellX + cellSizeX - radius, cellY);
                ctx.quadraticCurveTo(cellX + cellSizeX, cellY, cellX + cellSizeX, cellY + radius);
                ctx.lineTo(cellX + cellSizeX, cellY + cellSizeY - radius);
                ctx.quadraticCurveTo(cellX + cellSizeX, cellY + cellSizeY, cellX + cellSizeX - radius, cellY + cellSizeY);
                ctx.lineTo(cellX + radius, cellY + cellSizeY);
                ctx.quadraticCurveTo(cellX, cellY + cellSizeY, cellX, cellY + cellSizeY - radius);
                ctx.lineTo(cellX, cellY + radius);
                ctx.quadraticCurveTo(cellX, cellY, cellX + radius, cellY);
                ctx.closePath();
                ctx.fill();
                
                // Reset shadow before drawing image component
                ctx.shadowColor = "transparent";
                
                // Calculate dimensions for best fit centering
                const imgPadding = 15;
                const innerW = cellSizeX - imgPadding * 2;
                const innerH = cellSizeY - 50 - imgPadding; // space for bottom text
                
                const scale = Math.min(innerW / w, innerH / h);
                const drawW = w * scale;
                const drawH = h * scale;
                const drawX = cellX + imgPadding + (innerW - drawW) / 2;
                const drawY = cellY + imgPadding + (innerH - drawH) / 2;
                
                // Crop directly to visually isolate car
                ctx.drawImage(imgCanvas, x, y, w, h, drawX, drawY, drawW, drawH);
                
                // Car Label (Type and Confidence)
                ctx.fillStyle = "#2d3436";
                ctx.font = "bold 20px sans-serif";
                ctx.textAlign = "center";
                ctx.fillText(
                    `${pred.class.toUpperCase()} - ${Math.round(pred.score * 100)}%`, 
                    cellX + cellSizeX / 2, 
                    cellY + cellSizeY - 25
                );
            });

        } catch (err) {
            // Error handling, ensuring exceptions are surfaced gracefully on-screen
            ctx.fillStyle = "#d63031";
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            ctx.fillStyle = "#ffffff";
            ctx.font = `bold ${Math.max(16, Math.floor(canvas.width / 30))}px sans-serif`;
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            ctx.fillText("An Error Occurred:", canvas.width/2, canvas.height/2 - 20);
            ctx.font = `${Math.max(14, Math.floor(canvas.width / 40))}px sans-serif`;
            ctx.fillText(err.message, canvas.width/2, canvas.height/2 + 20, canvas.width - 40);
        }
    })();
    
    return container;
}

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 Cars Collector is an AI-powered tool designed to automatically detect and isolate vehicles within an image. Using object detection technology, the tool scans your uploaded photos for cars, trucks, and buses, then extracts them to create a neat, organized collage of the detected vehicles. Each vehicle in the collection is presented in its own card, complete with a label identifying the type of vehicle and the detection confidence level. This tool is useful for enthusiasts looking to catalog specific vehicles from busy street scenes, researchers analyzing traffic photography, or anyone wanting to create a quick visual summary of vehicles present in a single shot.

Leave a Reply

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