Stéphane Laurent
Stéphane Laurent

Reputation: 84539

Correlation of two images by Haskell 'hip' library (LoG filter)

The logFilter in the 'hip' Haskell library is obtained with the help of the correlate function. When I apply this filter to this image:

enter image description here

then I obtain this image:

enter image description here

I tried to reproduce it in R with the imager package and no way to get this result: I tried several ways which all gave a gray image. I tried with the built-in methods and I also tried manually, roughly:

for(r in 1:512) {
  for(c in 1:512){
    red[r, c] <- gre[r, c] <- blu[r, c] <- 0
    for(u in 1:9){
      for(v in 1:9) {
        red[r, c] <- red[r, c] + kernel[u, v] * RED[r+u, c+v]
        gre[r, c] <- gre[r, c] + kernel[u, v] * GRE[r+u, c+v]
        blu[r, c] <- blu[r, c] + kernel[u, v] * BLU[r+u, c+v]
      }
    }
  }
}

up to the problem with the borders.

I don't completely understand the code of correlate, in particular I don't understand what the toManifest function does. What does toManifest do? Is correlate an implementation of the previous algorithm with the double loop or is it something else?

Upvotes: 4

Views: 92

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 173898

If you follow the links through to the page that explains the logFilter function, it appears to essentially be a correlation of the image with the following matrix as a kernel:

enter image description here

Which in R is

LoG_kernel <- matrix(c(0, 1, 1,   2,   2,   2, 1, 1, 0, 
                       1, 2, 4,   5,   5,   5, 4, 2, 1, 
                       1, 4, 5,   3,   0,   3, 5, 4, 1, 
                       2, 5, 3, -12, -24, -12, 3, 5, 2, 
                       2, 5, 0, -24, -40, -24, 0, 5, 2, 
                       2, 5, 3, -12, -24, -12, 3, 5, 2, 
                       1, 4, 5,   3,   0,   3, 5, 4, 1, 
                       1, 2, 4,   5,   5,   5, 4, 2, 1, 
                       0, 1, 1,   2,   2,   2, 1, 1, 0), 9L)

However, your image sppears to be the Laplacian of the LoG. The Laplacian is the correlation of the image with this matrix:

L_kernel <- matrix(c(-1, -1, -1,
                     -1,  8, -1, 
                     -1, -1, -1), 3L)

Furthermore, Haskell seems to truncate values to the 0, 1 range, meaning we need the following little helper function:

truncate <- function(image) {
  image[image < 0] <- 0
  image[image > 1] <- 1
  image
}

That done, we can replicate your Haskell result with:

library(imager)

load.image("Klein.png") |>
  correlate(as.cimg(LoG_kernel)) |> 
  correlate(as.cimg(L_kernel)) |>
  truncate() |>
  save.image("LLoG.png")

enter image description here

Created on 2023-08-30 with reprex v2.0.2

Upvotes: 4

Related Questions