Fast single-threaded SSIM (Structural Similarity Index) metric for CI visual testing
npm install @blazediff/ssim

Fast SSIM (Structural Similarity Index) implementations for perceptual image quality assessment. Includes standard SSIM, MS-SSIM (Multi-Scale SSIM), and Hitchhiker's SSIM for various use cases and performance requirements.
Features:
- Three SSIM Variants - Standard SSIM, MS-SSIM, and Hitchhiker's SSIM
- MATLAB-compatible - Matches reference implementation with <0.01% error
- High Performance - Optimized implementations with ~4x faster Hitchhiker's SSIM
- Perceptual Metrics - Structural similarity scoring (0-1 scale)
- SSIM Map Output - Optional grayscale visualization
- Zero Dependencies
- TypeScript Support out of the box
For detailed algorithm explanation and mathematical formulas, see FORMULA.md.
``bash`
npm install @blazediff/ssim
Compares two images using the standard SSIM algorithm with automatic downsampling and returns a similarity score.
| Parameter | Type | Description |
|---|---|---|
image1 | Uint8Array, Uint8ClampedArray, or Buffer | First image data (RGBA format, 4 bytes per pixel) |
image2 | Uint8Array, Uint8ClampedArray, or Buffer | Second image data (RGBA format, 4 bytes per pixel) |
output | Uint8Array, Uint8ClampedArray, Buffer, or undefined | Optional output buffer for SSIM map visualization (RGBA format) |
width | number | Image width in pixels |
height | number | Image height in pixels |
options | SsimOptionsExtended | SSIM computation options (optional) |
Returns: number - SSIM score (0-1, where 1 is identical)
#### Options
| Option | Type | Default | Description |
|---|---|---|---|
windowSize | number | 11 | Size of the Gaussian window |
k1 | number | 0.01 | Algorithm parameter for luminance |
k2 | number | 0.03 | Algorithm parameter for contrast |
L | number | 255 | Dynamic range of pixel values |
Compares two images using the Multi-Scale SSIM (MS-SSIM) algorithm and returns a similarity score.
Same parameters as ssim(), but analyzes images at multiple scales (default: 5 levels) for better perceptual accuracy.
Returns: number - MS-SSIM score (0-1, where 1 is identical)
#### Options
| Option | Type | Default | Description |
|---|---|---|---|
windowSize | number | 11 | Size of the Gaussian window |
scales | number | 5 | Number of scales to use |
weights | number[] | [0.0448, 0.2856, 0.3001, 0.2363, 0.1333] | Weights for each scale |
method | 'product' or 'sum' | 'product' | Aggregation method |
Compares two images using Hitchhiker's SSIM (fast rectangular-window version with integral images).
Performance: ~4x faster than standard SSIM using integral images for O(1) window computation.
| Parameter | Type | Description |
|---|---|---|
image1 | Uint8Array, Uint8ClampedArray, or Buffer | First image data (RGBA format, 4 bytes per pixel) |
image2 | Uint8Array, Uint8ClampedArray, or Buffer | Second image data (RGBA format, 4 bytes per pixel) |
output | Uint8Array, Uint8ClampedArray, Buffer, or undefined | Optional output buffer for SSIM map |
width | number | Image width in pixels |
height | number | Image height in pixels |
options | HitchhikersSsimOptions | SSIM computation options (optional) |
Returns: number - SSIM score (0-1, where 1 is identical)
#### Options
| Option | Type | Default | Description |
|---|---|---|---|
windowSize | number | 11 | Size of the rectangular window |
windowStride | number | windowSize | Stride for window sliding (non-overlapping by default) |
covPooling | boolean | true | Use Coefficient of Variation pooling (recommended) |
k1 | number | 0.01 | Algorithm parameter for luminance |
k2 | number | 0.03 | Algorithm parameter for contrast |
L | number | 255 | Dynamic range of pixel values |
`typescript
import ssim from '@blazediff/ssim/ssim';
const score = ssim(image1.data, image2.data, undefined, width, height);
console.log(Similarity: ${score.toFixed(4)}); // e.g., "Similarity: 0.9823"
// Use in tests
if (score < 0.95) {
throw new Error(Images differ too much: ${score});`
}
`typescript
import msssim from '@blazediff/ssim/msssim';
// MS-SSIM provides better perceptual accuracy by analyzing at multiple scales
const score = msssim(image1.data, image2.data, undefined, width, height);
console.log(MS-SSIM: ${score.toFixed(4)});`
`typescript
import hitchhikersSSIM from '@blazediff/ssim/hitchhikers-ssim';
// ~4x faster than standard SSIM
const score = hitchhikersSSIM(image1.data, image2.data, undefined, width, height);
console.log(Hitchhiker's SSIM: ${score.toFixed(4)});
// With custom options
const scoreCustom = hitchhikersSSIM(image1.data, image2.data, undefined, width, height, {
windowSize: 16,
windowStride: 8, // Overlapping windows
covPooling: true, // CoV pooling (recommended)
});
`
`typescript
import ssim from '@blazediff/ssim/ssim';
// Basic SSIM with custom window size
const score = ssim(image1, image2, undefined, width, height, {
windowSize: 7, // Smaller window for more local detail
k1: 0.01,
k2: 0.03,
L: 255
});
// MS-SSIM with custom scales and method
import msssim from '@blazediff/ssim/msssim';
const msScore = msssim(image1, image2, undefined, width, height, {
scales: 5, // Number of scales (default: 5)
method: 'product', // 'product' or 'sum'
windowSize: 11
});
`
The SSIM map shows local similarity values as a grayscale image:
`typescript
import ssim from '@blazediff/ssim/ssim';
// Create output buffer for SSIM map
const output = new Uint8ClampedArray(width height 4);
const score = ssim(image1, image2, output, width, height);
// output now contains grayscale SSIM map
// White (255) = high similarity, Black (0) = low similarity
// Can be saved as PNG or displayed for debugging
`
Use SSIM when:
- You need MATLAB-compatible results for research or comparison
- You want high accuracy with Gaussian weighting
- You need automatic downsampling for large images
- Performance is not critical
Use MS-SSIM when:
- You need multi-scale analysis for better perceptual correlation
- You're working with images at different resolutions
- You want better correlation with human perception
- You can afford the ~2-3x computation cost
Use Hitchhiker's SSIM when:
- You need maximum performance (~4x faster than standard SSIM)
- You're processing large images or many images
- You want O(1) window computation regardless of window size
- You need flexible window stride for overlapping/non-overlapping windows
- CoV pooling provides better perceptual correlation than mean
| Score Range | Similarity Level | Description |
| ----------- | ---------------- | ----------- |
| 1.0 | Identical | Images are identical or perceptually identical |0.99+
| | Excellent | Extremely high similarity (minor compression artifacts) |0.95-0.99
| | Very Good | High similarity (small compression or noise) |0.90-0.95
| | Good | Noticeable but acceptable differences |0.80-0.90
| | Fair | Significant but tolerable differences |<0.80` | Poor | Major structural differences |
|
See ../../licenses for algorithm attribution and licensing information.