Please bookmark this page to avoid losing your image tool!

Image Confusion Analysis Tool

(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, neighborhoodSize = 5, sensitivity = 1.0, overlayOpacity = 0.75) {
    // Utility to safely parse numerical inputs, even if provided as strings
    const parseNum = (val, defaultVal) => {
        const num = parseFloat(val);
        return isNaN(num) ? defaultVal : num;
    };

    // Configuring analysis parameters
    const nSize = Math.max(1, Math.round(parseNum(neighborhoodSize, 5)));
    const r = Math.floor(nSize / 2); // Neighborhood radius
    const sens = Math.max(0.01, parseNum(sensitivity, 1.0));
    const opacity = Math.max(0, Math.min(1, parseNum(overlayOpacity, 0.75)));

    const width = originalImg.width;
    const height = originalImg.height;

    // Set up canvas and draw original image
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(originalImg, 0, 0);

    const imgData = ctx.getImageData(0, 0, width, height);
    const data = imgData.data;

    // We use integral images (Summed Area Tables) for O(1) local mean & variance calculation.
    // Float64Array avoids precision loss over large accumulations of square values.
    const S = new Float64Array((width + 1) * (height + 1));
    const Sq = new Float64Array((width + 1) * (height + 1));

    // Calculate integral images in a single pass
    for (let y = 0; y < height; y++) {
        const rowOffset = y * width;
        const sRowOffset = y * (width + 1);
        const sNextRowOffset = (y + 1) * (width + 1);

        for (let x = 0; x < width; x++) {
            const outIdx = (rowOffset + x) * 4;
            
            // Standard BT.601 Luma
            const lumaVal = data[outIdx] * 0.299 + data[outIdx + 1] * 0.587 + data[outIdx + 2] * 0.114;
            
            const sumAbove = S[sRowOffset + (x + 1)];
            const sumLeft = S[sNextRowOffset + x];
            const sumAboveLeft = S[sRowOffset + x];
            S[sNextRowOffset + (x + 1)] = lumaVal + sumAbove + sumLeft - sumAboveLeft;
            
            const lumaSq = lumaVal * lumaVal;
            const sqAbove = Sq[sRowOffset + (x + 1)];
            const sqLeft = Sq[sNextRowOffset + x];
            const sqAboveLeft = Sq[sRowOffset + x];
            Sq[sNextRowOffset + (x + 1)] = lumaSq + sqAbove + sqLeft - sqAboveLeft;
        }
    }

    // Precalculate Heatmap Colors (LUT for Extreme Performance)
    // Blue (Low Confusion) -> Cyan -> Green -> Yellow -> Red (High Confusion)
    const lut = new Uint8Array(256 * 3);
    for (let i = 0; i < 256; i++) {
        const norm = i / 255;
        const h = (1 - norm) * 240;
        const c = 1; 
        const x_col = c * (1 - Math.abs((h / 60) % 2 - 1));
        
        let r_ = 0, g_ = 0, b_ = 0;
        if (h >= 0 && h <= 60) { r_ = c; g_ = x_col; b_ = 0; }
        else if (h > 60 && h <= 120) { r_ = x_col; g_ = c; b_ = 0; }
        else if (h > 120 && h <= 180) { r_ = 0; g_ = c; b_ = x_col; }
        else { r_ = 0; g_ = x_col; b_ = c; }
        
        lut[i * 3] = Math.round(r_ * 255);
        lut[i * 3 + 1] = Math.round(g_ * 255);
        lut[i * 3 + 2] = Math.round(b_ * 255);
    }

    const outputData = ctx.createImageData(width, height);
    const out = outputData.data;

    // Apply Heatmap and Blend
    for (let y = 0; y < height; y++) {
        const y0_ = Math.max(0, y - r);
        const y1_ = Math.min(height - 1, y + r);
        
        const rowWidth = width + 1;
        const offset_y0 = y0_ * rowWidth;
        const offset_y1 = (y1_ + 1) * rowWidth;

        for (let x = 0; x < width; x++) {
            const outIdx = (y * width + x) * 4;
            const a = data[outIdx + 3];
            
            // Skip fully transparent pixels
            if (a === 0) continue;
            
            const x0 = Math.max(0, x - r);
            const x1 = Math.min(width - 1, x + r);
            
            const x0_ = x0;
            const x1_ = x1 + 1;

            // Extract window sums from integral images
            const S_rect = S[offset_y1 + x1_] - S[offset_y0 + x1_] - S[offset_y1 + x0_] + S[offset_y0 + x0_];
            const Sq_rect = Sq[offset_y1 + x1_] - Sq[offset_y0 + x1_] - Sq[offset_y1 + x0_] + Sq[offset_y0 + x0_];
            
            const count = (x1 - x0 + 1) * (y1_ - y0_ + 1);
            
            const mean = S_rect / count;
            const variance = Math.max(0, (Sq_rect / count) - (mean * mean));
            
            // Standard Deviation serves as our local "Confusion / Entropy" metric
            const stdDev = Math.sqrt(variance);

            // Normalize complexity metric, dynamically mapped based on user sensitivity
            let norm = stdDev / (48 / sens);
            norm = Math.max(0, Math.min(1, norm));

            const lutIdx = Math.round(norm * 255) * 3;
            const lumaVal = data[outIdx] * 0.299 + data[outIdx + 1] * 0.587 + data[outIdx + 2] * 0.114;

            // Blend chosen heatmap color with the underlying grayscale base image
            out[outIdx] = lut[lutIdx] * opacity + lumaVal * (1 - opacity);
            out[outIdx + 1] = lut[lutIdx + 1] * opacity + lumaVal * (1 - opacity);
            out[outIdx + 2] = lut[lutIdx + 2] * opacity + lumaVal * (1 - opacity);
            out[outIdx + 3] = a;
        }
    }

    ctx.putImageData(outputData, 0, 0);

    // Build the visual container to present the tool nicely
    const container = document.createElement('div');
    container.style.display = 'flex';
    container.style.flexDirection = 'column';
    container.style.alignItems = 'center';
    container.style.fontFamily = 'system-ui, -apple-system, sans-serif';
    container.style.gap = '16px';
    container.style.padding = '16px';
    container.style.width = '100%';
    container.style.boxSizing = 'border-box';
    container.style.backgroundColor = '#f9fafb';
    container.style.borderRadius = '8px';

    canvas.style.maxWidth = '100%';
    canvas.style.height = 'auto';
    canvas.style.boxShadow = '0 10px 15px -3px rgba(0, 0, 0, 0.1)';
    canvas.style.borderRadius = '6px';

    // Construct Legend Info Container
    const legendContainer = document.createElement('div');
    legendContainer.style.width = '100%';
    legendContainer.style.maxWidth = '500px';
    legendContainer.style.display = 'flex';
    legendContainer.style.flexDirection = 'column';
    legendContainer.style.gap = '8px';
    
    const title = document.createElement('div');
    title.innerText = 'Confusion Analysis Heatmap (Visual Complexity Filter)';
    title.style.fontWeight = '600';
    title.style.fontSize = '14px';
    title.style.color = '#374151';
    title.style.textAlign = 'center';

    const bar = document.createElement('div');
    bar.style.height = '12px';
    bar.style.width = '100%';
    bar.style.background = 'linear-gradient(to right, hsl(240, 100%, 50%), hsl(180, 100%, 50%), hsl(120, 100%, 50%), hsl(60, 100%, 50%), hsl(0, 100%, 50%))';
    bar.style.borderRadius = '999px';

    const labels = document.createElement('div');
    labels.style.display = 'flex';
    labels.style.justifyContent = 'space-between';
    labels.style.fontSize = '12px';
    labels.style.fontWeight = '500';
    labels.style.color = '#6b7280';
    labels.innerHTML = '<span>Low Detail (Smooth)</span><span>Medium</span><span>High Details (Confusion)</span>';

    legendContainer.appendChild(title);
    legendContainer.appendChild(bar);
    legendContainer.appendChild(labels);
    
    container.appendChild(canvas);
    container.appendChild(legendContainer);

    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 Confusion Analysis Tool visualizes the local complexity and detail density of an image using a color-coded heatmap. By calculating the local variance and standard deviation of pixel intensity, the tool identifies areas of high detail (high ‘confusion’) versus smooth or low-detail areas. Users can adjust parameters such as neighborhood size, sensitivity, and overlay opacity to fine-tune the analysis. This tool is useful for computer vision research, analyzing image texture, assessing visual noise, or identifying complex patterns within high-resolution photography and medical imaging.

Leave a Reply

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