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 |
|
diagonal_edges_df |
|
clean_lab_df |
data of type |
img |
image providing the dimensions of the output matrix
(import by |
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()