Home > Blockchain >  How can I turn all red pixels white quickly in an image in R?
How can I turn all red pixels white quickly in an image in R?

Time:10-08

I am trying to selectively turn all red/pink pixels in to white (hence, deleting them). There is a pink/red grid in the background of ECG images I'm working with, and I want to delete that (note: turning the whole image grayscale will not work).

I've ended up writing a laborious for loop that finds all "dark" pixels (IE R < 0.1, G < 0.1, B < 0.1) and then turns those black (0.0, 0.0, 0.0), leaving all other pixels white (1.0, 1.0, 1.0). Here is that code:

DropGrid <- function (im, b.thresh = 0.1)
{
    black.pix <- which (im[,,1,1] < b.thresh & im[,,1,2] < b.thresh & im[,,1,3] < b.thresh)
    black.X <- rep (NA, length(black.pix))
    black.Y <- rep (NA, length(black.pix))

    for (i in 1:length(black.pix))
    {
        black.X[i] <- as.integer(black.pix[i] %% nrow(im))
        black.Y[i] <- as.integer(black.pix[i] / nrow(im))   1
    }

    im.alter <- imfill (x = nrow(im), y = ncol(im), z = 1, val = c(1.0, 1.0, 1.0, 1.0))

    for (i in 1:length(black.pix))
    {
        im.alter[black.X[i], black.Y[i], 1, ] <- c (0.0, 0.0, 0.0, 1.0)
    }

    return (im.alter)
}

In this function, im is the original ECG image and im.alter is the desired image. The problem is that this takes about 60 seconds per image which is desperately slow.

Is there a faster way to mess with all pixels in an image that fit some condition?

I'm using the imager to load images. The results of str(im) are:

'cimg' num [1:1208, 1:927, 1, 1:4] 0.796 1 1 1 1 ...

Here is a representative image. I want to quickly remove the pink/red grid: enter image description here

Thank you so much!

CodePudding user response:

If I make a little test image in the Terminal with ImageMagick by taking a single black, a pink and a red pixel, placing them in a row and resizing, I get this:

magick xc:black xc:pink xc:red  append -resize 400x100 image.png

enter image description here

If I then set the "fill colour" to white and say I want all pixels within 10% of pink to become white:

magick image.png -fill white -fuzz 10% -opaque pink result.png

enter image description here

If I make that 25% to broaden the range around my target colour:

magick image.png -fill white -fuzz 25% -opaque pink result.png

enter image description here

I don't use R but I believe there is an ImageMagick package for it that you could use to implement a version of the above. As I said, I have no idea about R but these seem to be the resources you might need:

enter image description here

You can use RGB coordinates:

magick image.png -fill white -fuzz 25% -opaque "rgb(255,0,128)" result.png

Or hex:

magick image.png -fill white -fuzz 25% -opaque "#ff0080" result.png

I see you have added a sample image now, so you could use:

magick FNr0h.png -fill white -fuzz 20% -opaque "rgb(250,160,170)" result.png

enter image description here

CodePudding user response:

thank you - I read your answer, researched using magick in R, and found the following code to work perfectly on all sample images:

im <- magick::image_read ("sample_image.png")
im.proc <- image_transparent (im, "pink", 20)
magick::image_write (im.proc, "processed_image.png", format = "png", flatten = TRUE)

I can then read in the processed_image.png with whatever image library I want, and the red/pink colors will have been removed. Thank you all again.

  • Related