A common preprocessing step for image recognition/classification problems is to crop out areas which are not of interest. I have been trying to figure out how to do this in a robust way with magick
, opencv
and imager
(imager is not of much use). Below is an example image where I'd like to crop remove as much of the black area as possible. Unfortunately, the black areas contain non-black artifact pixel areas, so I cannot simply use imager::autocrop()
.
For a single image, automatic cropping can easily be achieved by using magick::image_trim()
:
img_path <- "image.jpeg"
img <- magick::image_read(img_path)
magick::image_trim(img, fuzz = 20)
The result:
However, the required fuzz
will vary from image to image. image_trim()
is thus not the most robust way of cropping a large number of images. One idea I had was to instead use the magick::image_canny()
-function to detect the edges of the object.
img_edge <- magick::image_canny(img, "0x2+10%+30%")
img_edge
Based on the above image I can then trim or autocrop the img_edge
image that the Canny algorithm was applied on. My question however is: How can I apply the crop to the original img
based off of the results of applying the Canny algorithm?
In other words: is there a way in which, instead of trimming/cropping, I can instead get the coordinates of the area to be cropped/trimmed (identifying a "bounding box")? The ultimate goal is to apply the crop to the original image.
Do I have to convert the images to arrays and do this manually, or is there some built in functionality in magick
or opencv
which can help with this?