adaptiveInterpolation {biopixR}R Documentation

Connects Line Ends with the nearest labeled region

Description

The function scans an increasing radius around a line end and connects it with the nearest labeled region.

Usage

adaptiveInterpolation(
  end_points_df,
  diagonal_edges_df,
  clean_lab_df,
  img,
  radius = 5
)

Arguments

end_points_df

data.frame with the coordinates of all line ends (can be obtained by using image_morphology)

diagonal_edges_df

data.frame with coordinates of diagonal line ends (can also be obtained by using image_morphology)

clean_lab_df

data of type data.frame, containing the x, y and value information of every labeled region in an image (only the edges should be labeled)

img

image providing the dimensions of the output matrix (import by importImage)

radius

maximal radius that should be scanned for another cluster

Details

This function is designed to be part of the fillLineGaps function, which performs the thresholding and line end detection preprocessing. The adaptiveInterpolation generates a matrix with dimensions matching those of the original image. Initially, the matrix contains only background values (0) corresponding to a black image. The function then searches for line ends and identifies the nearest labeled region within a given radius of the line end. It should be noted that the cluster of the line end in question is not considered a nearest neighbor. In the event that another cluster is identified, the interpolatePixels function is employed to connect the line end to the aforementioned cluster. This entails transforming the specified pixels of the matrix to a foreground value of (1). It is important to highlight that diagonal line ends receive a special treatment, as they are always treated as a separate cluster by the labeling function. This makes it challenging to reconnect them. To address this issue, diagonal line ends not only ignore their own cluster but also that of their direct neighbor. Thereafter, the same procedure is repeated, with pixel values being changed according to the interpolatePixels function.

Value

Binary matrix that can be applied as an overlay, for example with imager.combine to fill the gaps between line ends.

Examples

# Creating an artificial binary image
mat <- matrix(0, 8, 8)
mat[3, 1:2] <- 1
mat[4, 3] <- 1
mat[7:8, 3] <- 1
mat[5, 6:8] <- 1
mat_cimg <- as.cimg(mat)
plot(mat_cimg)

# Preprocessing / LineEnd detection / labeling (done in fillLineGaps())
mat_cimg_m <- mirror(mat_cimg, axis = "x")
mat_magick <- cimg2magick(mat_cimg)
lineends <- image_morphology(mat_magick, "HitAndMiss", "LineEnds")
diagonalends <- image_morphology(mat_magick, "HitAndMiss", "LineEnds:2>")
lineends_cimg <- magick2cimg(lineends)
diagonalends_cimg <- magick2cimg(diagonalends)
end_points <- which(lineends_cimg == TRUE, arr.ind = TRUE)
end_points_df <- as.data.frame(end_points)
colnames(end_points_df) <- c("x", "y", "dim3", "dim4")
diagonal_edges <- which(diagonalends_cimg == TRUE, arr.ind = TRUE)
diagonal_edges_df <- as.data.frame(diagonal_edges)
colnames(diagonal_edges_df) <- c("x", "y", "dim3", "dim4")
lab <- label(mat_cimg_m)
df_lab <- as.data.frame(lab) |> subset(value > 0)
alt_x <- list()
alt_y <- list()
alt_value <- list()
for (g in seq_len(nrow(df_lab))) {
  if (mat_cimg_m[df_lab$x[g], df_lab$y[g], 1, 1] == 1) {
    alt_x[g] <- df_lab$x[g]
    alt_y[g] <- df_lab$y[g]
    alt_value[g] <- df_lab$value[g]
  }
}
clean_lab_df <- data.frame(
  x = unlist(alt_x),
  y = unlist(alt_y),
  value = unlist(alt_value)
)

# Actual function
overlay <- adaptiveInterpolation(
  end_points_df,
  diagonal_edges_df,
  clean_lab_df,
  mat_cimg
)
parmax(list(mat_cimg_m, as.cimg(overlay$overlay))) |> plot()

[Package biopixR version 1.1.0 Index]