Menu

#37 neutralize gray with R=G=B channels

v1.0_(example)
open
nobody
None
5
2020-03-11
2020-03-11
Hakan
No

Hello,

I would like to execute a 'neutralize gray' effect at the pixel level. Is the following pseude function possible with GM command line ?

gm convert -neutralize-gray <threshold-value> input.jpg output.jpg

the command should loop over each RGB pixel and find the max(RGB) and the min(RGB)
If the max(RGB) minus min(RGB) is less than <threshold-value> then output pixel = average(RGB)
otherwise output pixel = original(RGB)</threshold-value>

example with numbers
gm convert -neutralize-gray 15 input.jpg output.jpg

pixel(x,y) = RGB(200,210,199)
max(RGB) = 210
min(RGB) =199
difference = 11 < threshold
set output pixel = (200+210+199)/3 = 203

pixel(x,y) = RGB(200,210,180)
max(RGB) = 210
min(RGB) =180
difference = 30 > threshold
set output pixel = RGB(200,210,180)

This effect will turn 'distorted' (or dirty) gray that still looks 'gray enough' to the human eye, into pure R=G=B gray which print devices need in order to determine if the page counts as color or grayscale

thank you in advance

Discussion

  • Bob Friesenhahn

    Bob Friesenhahn - 2020-03-11

    On Wed, 11 Mar 2020, Hakan wrote:

    I would like to execute a 'neutralize gray' effect at the pixel
    level. Is the following pseude function possible with GM command
    line ?

    It seems like your algorithm is a single-pass algorithm where each
    pixel is analyzed/accessed just once. Is my interpretation correct?

    If so, this is easily implemented in C/C++ using the GraphicsMagick
    library, and could be implemented (albeit much more slowly) using
    PerlMagick or another interpreted extension which allows updating
    pixels. I lack sufficient imagination for how to implement it using
    the existing command-line, but it might be possible.

    Your command syntax is similar to the existing threshold commands
    (-black-threshold, -threshold, and -white-threshold) and so the
    implementation could copy one of those implementations and make minor
    changes. If the algorithm works well, this seems useful to have in
    GraphicsMagick.

    Bob

    Bob Friesenhahn
    bfriesen@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
    GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
    Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt

     
  • Hakan

    Hakan - 2020-03-11

    Yes, it is a single pass algorithm.
    It is 1 read operation (from input) and 1 write (to output bitmap) to the same pixel location with no dependency on other pixels.

    I experimented with
    -operator channel operator rvalue[%] and was hoping it could be implemented with that structure

    -operator all neutralize-gray rvalue[%]

    there are very similar other commands but nothing that does a decision based on max(RGB)-min(RGB)
    For someone familiar with the C/C++ interface it should be a few lines of code.

    I am doing the same operation using C# but the looping is too slow and .NET cannot adress the large memory pool that GraphicsMagick can. I am convinced this will run extremely fast in GM because there are many other similar functions.

     
    • Bob Friesenhahn

      Bob Friesenhahn - 2020-03-11

      On Wed, 11 Mar 2020, Hakan wrote:

      Yes, it is a single pass algorithm.
      It is 1 read operation (from input) and 1 write (to output bitmap) to the same pixel location with no dependency on other pixels.

      I experimented with
      -operator channel operator rvalue[%] and was hoping it could be implemented with that structure

      -operator all neutralize-gray rvalue[%]

      there are very similar other commands but nothing that does a decision based on max(RGB)-min(RGB)
      For someone familiar with the C/C++ interface it should be a few lines of code.

      I thought about the -operator command but it is designed to handle an
      arbitrary number of channels, which is not what you need

      The work in the C code is relatively easy due to copying an existing
      threshold implementation and then making a small change to the
      implementation.

      The C version would execute quite quickly.

      You might consider if your algorithm would be improved or more generic
      if the RGB color was converted to an RGB intensity value using a
      standard algorithm and then the threshold is based on the computed
      intensity rather than absolute peak in the R, G, or B channel. This
      makes more sense to me since perception is based on intensity and the
      contributions are highly non-linear.

      There are these two standard conversions from RGB to intensity:

      define PixelIntensityRec601(pixel) \

      ((unsigned int) \
      (((double)306.0(pixel)->red+ \
      (double)601.0
      (pixel)->green+ \
      (double)117.0*(pixel)->blue) \
      / 1024.0))

      define PixelIntensityRec709(pixel) \

      ((unsigned int) \
      (0.2126(pixel)->red+ \
      0.7152
      (pixel)->green+ \
      0.0722*(pixel)->blue))

      It is said that Rec709 should be the one used in the modern world
      since it is what ATSC TV and modern displays are using.

      If intensity can be used, then it might be possible to implement the
      algorithm without modifying GraphicsMagick because a grayscale image
      can be created and then perhaps a composite operator could be used to
      implement the modification to the RGB image.

      Bob

      Bob Friesenhahn
      bfriesen@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
      GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
      Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt

       
  • Hakan

    Hakan - 2020-03-11

    can you suggest a command line(s) to create a grayscale image that can seperate 'perceived gray' from 'perceived color' based on a threshold on intensity and how to compose it back into the RGB original , if you think this can be done without modifications to GM ? I am not clear how that could be done.

    Obviously your technical knowledge in this field is far more than mine and I cannot comment if your generic suggesting will work, or how well it works without testing an example.

    I just know that the algorthim I explained with absolute numbers works very well on any kind of input (200/300dpi scans of largeformat drawings) because I use it, just with fairly slow code.

    thank you

     
    • Bob Friesenhahn

      Bob Friesenhahn - 2020-03-11

      On Wed, 11 Mar 2020, Hakan wrote:

      can you suggest a command line(s) to create a grayscale image that
      can seperate 'perceived gray' from 'perceived color' based on a
      threshold on intensity and how to compose it back into the RGB
      original , if you think this can be done without modifications to GM
      ? I am not clear how that could be done.

      Obviously your technical knowledge in this field is far more than
      mine and I cannot comment if your generic suggesting will work, or
      how well it works without testing an example.

      I am more like a race-car mechanic than a race-car driver. The
      race-car driver is usually much better at driving than her mechanic.
      :-)

      There are other people who are far better at doing interesting things
      with the available algorithms than I am.

      To me it is easiest to implement the C source code.

      Bob

      Bob Friesenhahn
      bfriesen@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
      GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
      Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.