select adjacent pixels

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
idnael

select adjacent pixels

Post by idnael »

Hello,
in Gimp or any other image manipulation program, usually there is a tool called "magic selection", which selects adjacent pixels based on the color and a tolerance value.

This is very useful when processing images, and i would like to know if there is a similar functionality in ImageMagick (command line or perl).

To be more clear, i will give an example:

I have a scanned image whose background is black but with variations of color, and some noise, and i want to make it transparent.

These cannot be done with:

convert input.gif -fuzz 20% -transparent "#15151b" output.gif

Because that would also replace pixels inside the image and not only in the border.

Also, it cannot be done with:

convert input.gif -fuzz 20% -trim output.gif

Because this would only cut a rectagular area.

thanks
dani
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: select adjacent pixels

Post by magick »

A "magic selection" tool is on our list of things to do but it is not implemented just yet.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: select adjacent pixels

Post by anthony »

Actually Cristy means a magick 'follow the edge' selection tool.

What you are wanting is probably -draw floodfill
http://imagemagick.org/Usage/draw/#color

And example of this is in the new 'glitter' section. see last example in
http://imagemagick.org/Usage/anim_mods/#glitter_tiles
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
idnael

Re: select adjacent pixels

Post by idnael »

That's what i need.

It was inside the "draw" command... that's why i was not finding it!


thanks Anthony!
idnael

Re: select adjacent pixels

Post by idnael »

what about if i want to do a flood fill but insteed of paiting i want to make the area transparent?

should i first fill with a color X that was not used in the image, and after, make that color transparent?

like this:

convert 1.jpg -fill '#123456' -fuzz 10% -draw 'color 10,10 floodfill' -fuzz 0% -transparent '#123456' 2.gif

there is a direct and more secure way?

daniel
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: select adjacent pixels

Post by magick »

Instead of 'color', use 'matte' to floodfill a transparent color.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: select adjacent pixels

Post by anthony »

Be sure you use a -fill none when using a 'matte' floodfill
See IM Examples
http://imagemagick.org/Usage/draw/#matte

Also see, this for the use for 'fuzz' factors
http://imagemagick.org/Usage/color/#fuzz
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
idnael

Re: select adjacent pixels

Post by idnael »

thanks again!

Now suppose this:

I have a picture with many objects, under a transparent background (the result of the previous step!)

I want to select the object that is at position 100,100 and save it to a separate image.

That is, like a floodfill, but it should select all the opaque pixels. (All the contiguos area that is surrounded by the transparent background) How to set the fuzz attribute?

And how to save that area insteed of paiting it?

d
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: select adjacent pixels

Post by anthony »

I have a picture with many objects, under a transparent background (the result of the previous step!)

I want to select the object that is at position 100,100 and save it to a separate image.

That is, like a floodfill, but it should select all the opaque pixels. (All the contiguos area that is surrounded by the transparent background) How to set the fuzz attribute?

And how to save that area insteed of paiting it?
Hmmm tricky. The easiest way is for each object to be in a different layer.
That is what multi-image 'layering' is used for. Each image can be trimmed to a minimal size with an appropriate image offset relative to the 'origin'. The -trim command itself (as well as most IM operators) preserves image offsets appropriately for this reason.

However i assume you have a problem becuase you have multiple objects in a single image, and you have at least a rough idea as to some location of that object wanted (some point within the object). You then want to divide that single image into a multiple layers, one object per layer.

I also assuming the objects are not touching or overlaying each other, and that a individual object is one piece, not a disjoint groupping of smaller pieces.

Basically you problem is known as image segmentation and many graphic textbooks are involved with this problem. Their are also a number of ways to separate out the various parts. some easy others hard.
  • If the objects are vertically, or horizontally dividable in a square array or equal sized pieces you can do a tiling crop to divide up the image.
    http://imagemagick.org/Usage/crop/#crop_tile
  • If the image is still vertically, or horizontally dividable but in unequal sizes. I have a script that looks for lines of constant color, and divides the image into segments basied on those blocks. This is a simple script, and probably should be added as a IM operator.
    http://imagemagick.org/Usage/scripts/divide_vert
  • The flood fill method when you know some point within an object is trickier.
    Basically take the image and extract the alpha channel
    http://imagemagick.org/Usage/channels/#trans
    Now threshold that image using -threshold 0 so that you have a mask of pure white and black. The threshold should divide the image into prefect-transparent, and non-transparent areas (that is semi-transparent should be thought of as equivelent to fully-opaque). It is probbaly better to make objects white and background black.

    Next use -opaque to make ALL objects some other color, say red. You can also use -channel GB -evaluate set 0 +channel to do that same thing, but faster. This will make your image a Red and Black image, instead of a white and black image.

    Now 'floodfill' any object you want to keep, white. and then use a -opaque command to globally make anything that is still red, black (make other objects disappear).

    You now have a MASK image that you can use to cut out the object selected from the original image. See this for merging a mask with the original image to erase
    everything that was not masked.
    http://imagemagick.org/Usage/channels/#erase

    That will do ONE object.
  • A better automatic way of separating random objects say from a mask image such as the above, is not directly available in IM, at least not yet, it would be a great addition to IM too. :-(
An external script to seperate one object, given a pixel coordinate (or better still all the objects), would also be a great thing to have.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: select adjacent pixels

Post by fmw42 »

I have created a magicwand script that allows multiple options to save the area of interest as an image or a mask or modify the complement of the area of interest. You can find this script along with my other scripts at

http://www.fmwconcepts.com/imagemagick/index.html

The list of all my scripts that are available is as follows:

3Drotate --- Applies a perspective distortion to an image by providing three rotation angles, zoom, offsets, background color, perspective exaggeration and auto zoom/centering

bcimage --- Changes the brightness, contrast and/or saturation of an image

binomial --- Generates high pass or low pass filtered images based upon convolution kernels whose weights are derived from the binomial coefficients

derivative --- Applies a first directional derivative filter to an image.

gradient --- Applies a gradient filter to an image.

grid --- Superimposes a set of horizontal and/or vertical grid lines on an image.

histog --- Generates an output image which is composed of the histograms from each channel of the input image.

laplacian --- Applies a laplacian filter to an image.

magicwand --- Segments a contiguous region of an image based upon a color determined from a user specified image coordinate.

isonoise --- Reduces isolated noise in an image.

omnistretch --- Enhances the dynamic range of brightness values and optionally saturation values in an image

plm --- Generates a piece-wise linear mapping grayscale look up table and applies it to an image

plmlut --- Generates a piece-wise linear mapping grayscale look up table

profile --- Generates a profile of an image row or column.

pscolor --- Generates a rainbow color look up table image and applies it to a grayscale image to generate a pseudocolored output image.

redist --- Modifies an image so that its (grayscale) histogram has a either Gaussian, distribution or a Uniform Distribution.

rotate3D --- Applies a perspective distortion to an image by providing three rotation angles and an optional perspective exaggeration

saturation --- Changes the color saturation in an image.

sharp --- Adaptively sharpens an image or extract edges.

space --- Applies a spatially adaptive contrast (and brightness) enhancement filter to an image.

statsfilt --- Computes various localized (neighborhood) statistical filters on an image


Fred Weinhaus
Post Reply