---
title: Laplacian
---

import { Image } from 'astro:assets';
import exampleImage from '../../../assets/laplacian-example.png';

<span title="Label: Pro" data-view-component="true" class="Label Label--api text-uppercase">
  Unstable API
</span>
<span title="Label: Pro" data-view-component="true" class="Label Label--version text-uppercase">
  0.8.0
</span>
<span title="Label: Pro" data-view-component="true" class="Label Label--package">
  <a target="_blank" href="https://www.npmjs.com/package/@project-lakechain/laplacian-image-processor">
    @project-lakechain/laplacian-image-processor
  </a>
</span>
<span class="language-icon">
  <svg role="img" viewBox="0 0 24 24" width="30" xmlns="http://www.w3.org/2000/svg" style="fill: #3178C6;"><title>TypeScript</title><path d="M1.125 0C.502 0 0 .502 0 1.125v21.75C0 23.498.502 24 1.125 24h21.75c.623 0 1.125-.502 1.125-1.125V1.125C24 .502 23.498 0 22.875 0zm17.363 9.75c.612 0 1.154.037 1.627.111a6.38 6.38 0 0 1 1.306.34v2.458a3.95 3.95 0 0 0-.643-.361 5.093 5.093 0 0 0-.717-.26 5.453 5.453 0 0 0-1.426-.2c-.3 0-.573.028-.819.086a2.1 2.1 0 0 0-.623.242c-.17.104-.3.229-.393.374a.888.888 0 0 0-.14.49c0 .196.053.373.156.529.104.156.252.304.443.444s.423.276.696.41c.273.135.582.274.926.416.47.197.892.407 1.266.628.374.222.695.473.963.753.268.279.472.598.614.957.142.359.214.776.214 1.253 0 .657-.125 1.21-.373 1.656a3.033 3.033 0 0 1-1.012 1.085 4.38 4.38 0 0 1-1.487.596c-.566.12-1.163.18-1.79.18a9.916 9.916 0 0 1-1.84-.164 5.544 5.544 0 0 1-1.512-.493v-2.63a5.033 5.033 0 0 0 3.237 1.2c.333 0 .624-.03.872-.09.249-.06.456-.144.623-.25.166-.108.29-.234.373-.38a1.023 1.023 0 0 0-.074-1.089 2.12 2.12 0 0 0-.537-.5 5.597 5.597 0 0 0-.807-.444 27.72 27.72 0 0 0-1.007-.436c-.918-.383-1.602-.852-2.053-1.405-.45-.553-.676-1.222-.676-2.005 0-.614.123-1.141.369-1.582.246-.441.58-.804 1.004-1.089a4.494 4.494 0 0 1 1.47-.629 7.536 7.536 0 0 1 1.77-.201zm-15.113.188h9.563v2.166H9.506v9.646H6.789v-9.646H3.375z"/></svg>
</span>
<div style="margin-top: 26px"></div>

---

The Laplacian image processor makes it possible to compute the Laplacian variance of images, and enrich the metadata of the document with the computed variance.
This metric is useful for detecting edges in images, and is more generally used as a blur detection metric to identify the *blurriness* of an image.

<br />
<p align="center">
  <img width="680" src={exampleImage.src} />
</p>

<p align="center" style="font-size: 14px">
  <em>Credits <a href="https://unsplash.com/fr/photos/une-chaise-avec-un-magazine-dessus-6Y4wlHeiGhM#:~:text=Remerciez-,Branislav%20Rodman,-sur%20les%20r%C3%A9seaux">Branislav Rodman</a> on <a href="https://unsplash.com/fr/photos/une-chaise-avec-un-magazine-dessus-6Y4wlHeiGhM">Unsplash</a></em>
</p>
<br />

<br />

---

### 📷 Computing Variance

To use this middleware, you import it in your CDK stack and instantiate it as part of a pipeline.

```typescript
import { LaplacianImageProcessor } from '@project-lakechain/laplacian-image-processor';
import { CacheStorage } from '@project-lakechain/core';

class Stack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string) {
    const cache = new CacheStorage(this, 'Cache');
    
    // Computes the Laplacian variance of images.
    const laplacianProcessor = new LaplacianImageProcessor.Builder()
      .withScope(this)
      .withIdentifier('LaplacianProcessor')
      .withCacheStorage(cache)
      .withSource(source) // 👈 Specify a data source
      .build();
  }
}
```

<br />

---

#### Depth Level

The Laplacian image processor can be configured to compute the Laplacian variance at different depth levels. This is useful when you want to compute the variance at different scales, and detect edges at different levels of granularity.
See the [OpenCV data types](https://docs.opencv.org/4.x/d1/d1b/group__core__hal__interface.html) for more information on the available depth levels.

> 💁 The default value is set to `64F`.

```typescript
import { LaplacianImageProcessor, Depth } from '@project-lakechain/laplacian-image-processor';

const laplacianProcessor = new LaplacianImageProcessor.Builder()
  .withScope(this)
  .withIdentifier('LaplacianProcessor')
  .withCacheStorage(cache)
  .withSource(source)
  .withDepth(Depth.CV_64F) // 👈 Optionally specify the depth level.
  .build();
```

<br />

---

#### Kernel Size

The kernel size used in the Laplacian algorithm can be configured to compute the variance at different scales.
The kernel size is used to compute the second derivative of the image, and is used to customize detection of edges in the image.

> 💁 The default value is set to `3`.

```typescript
import { LaplacianImageProcessor } from '@project-lakechain/laplacian-image-processor';

const laplacianProcessor = new LaplacianImageProcessor.Builder()
  .withScope(this)
  .withIdentifier('LaplacianProcessor')
  .withCacheStorage(cache)
  .withSource(source)
  .withKernelSize(3) // 👈 Optionally specify the kernel size.
  .build();
```

<br />

---

### 📄 Output

The Laplacian image processor does not modify or alter source images in any way. It instead enriches the metadata of their document by setting the `variance` field to the output of the captioning result.

<details>
  <summary>💁 Click to expand example</summary>
  
  > ℹ️ Below is an example of a [CloudEvent](/project-lakechain/general/events) emitted by the Laplacian image processor.

  ```json
  {
    "specversion": "1.0",
    "id": "1780d5de-fd6f-4530-98d7-82ebee85ea39",
    "type": "document-created",
    "time": "2023-10-22T13:19:10.657Z",
    "data": {
        "chainId": "6ebf76e4-f70c-440c-98f9-3e3e7eb34c79",
        "source": {
            "url": "s3://bucket/image.png",
            "type": "image/png",
            "size": 245328,
            "etag": "1243cbd6cf145453c8b5519a2ada4779"
        },
        "document": {
            "url": "s3://bucket/image.png",
            "type": "image/png",
            "size": 245328,
            "etag": "1243cbd6cf145453c8b5519a2ada4779"
        },
        "metadata": {
          "properties": {
            "kind": "image",
            "attrs": {
              "variance": 63.463
            }
          }
        },
        "callStack": []
    }
  }
  ```

</details>

<br />

---

### 🏗️ Architecture

This middleware runs within a Lambda compute, and packages OpenCV to compute the Laplacian variance of images.

![Architecture](../../../assets/laplacian-image-processor-architecture.png)

<br />

---

### 🏷️ Properties

<br />

##### Supported Inputs

|  Mime Type  | Description |
| ----------- | ----------- |
| `image/jpeg` | JPEG image |
| `image/png` | PNG image |
| `image/bmp` | BMP image |
| `image/webp` | WebP image |

##### Supported Outputs

|  Mime Type  | Description |
| ----------- | ----------- |
| `image/jpeg` | JPEG image |
| `image/png` | PNG image |
| `image/bmp` | BMP image |
| `image/webp` | WebP image |

##### Supported Compute Types

| Type  | Description |
| ----- | ----------- |
| `CPU` | This middleware only supports CPU compute. |

<br />

---

### 📖 Examples

- [Laplacian Variance Pipeline](https://github.com/awslabs/project-lakechain/tree/main/examples/simple-pipelines/image-processing-pipelines/laplacian-variance-pipeline) - An example showcasing how to compute the Laplacian variance of images.
