Midtone Mask

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?".
afre
Posts: 57
Joined: 2014-01-22T15:02:53-07:00
Authentication code: 6789

Midtone Mask

Post by afre »

Hello All, I would like to process the midtones of an image. What I think I need to do:
  1. Create a mask with L* midtones as white and the rest black.
  2. Feather the mask to ensure a smooth undetectable transition.
  3. Process my image and composite with original using mask.
I don't know if that's the best approach, but right now, I am stuck on #1. Currently, I only know how to black out the shadows and highlights, e.g.

Code: Select all

-colorspace LCHuv -channel R -fx "u>=.8?0:u" -fx "u<=.2?0:u" -separate
but not how to white out the midtones after that.

Code: Select all

-fill White +opaque Black
doesn't change the rest into white.
ImageMagick 7.0.7-25 Q16 x64 2018-03-04 · Cipher DPC HDRI Modules OpenMP · Windows 7
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Midtone Mask

Post by snibgo »

I would consider points 1 and 2 together.

Because my images are usually large, I would implement this with a clut, then apply the clut to the L channel to make the mask. My page http://im.snibgo.com/ckbkClut.htm shows many ways of making the clut.

One method uses appended gradients. Suppose you want black in the bottom 30%, then a gradient from black to white over 10% (between 30% and 40%), then white over 20% (between 40% and 60%), then white to black over 10% (between 60% and 70%), then black for 30% (between 70% and 100%).

Windows BAT syntax:

Code: Select all

convert ^
  -size 30x1 xc:black ^
  -size 10x1 gradient:black-white ^
  -size 20x1 xc:white ^
  -size 10x1 gradient:white-black ^
  -size 30x1 xc:black ^
  +append ^
  midclut.png

call %PICTBAT%graph1d midclut.png
Calling my script graph1d isn't necessary, but shows the clut as a graph.
Image
The clut can then be used to make a mask, for example of the rose image:

Code: Select all

convert ^
  rose: ^
  -colorspace Lab -channel R -separate +channel -set colorspace sRGB ^
  midclut.png ^
  -clut ^
  midmask.png
Of course, this can be done in a single command:

Code: Select all

convert ^
  rose: ^
  -colorspace Lab -channel R -separate +channel -set colorspace sRGB ^
  ( ^
    -size 30x1 xc:black ^
    -size 10x1 gradient:black-white ^
    -size 20x1 xc:white ^
    -size 10x1 gradient:white-black ^
    -size 30x1 xc:black ^
    +append ^
  ) ^
  -clut ^
  midmask.png
snibgo's IM pages: im.snibgo.com
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Midtone Mask

Post by snibgo »

If you don't want a linear transition, you can apply operations such as "-sigmoidal-contrast" to the clut. A cuter way is to make a black and white clut, then blur it:

Code: Select all

%IM%convert ^
  -size 35x1 xc:black ^
  -size 30x1 xc:white ^
  -size 35x1 xc:black ^
  +append ^
  -blur 0x3 ^
  midclutbl.png
snibgo's IM pages: im.snibgo.com
afre
Posts: 57
Joined: 2014-01-22T15:02:53-07:00
Authentication code: 6789

Re: Midtone Mask

Post by afre »

A midtone mask with hard B&W edges isn't ideal for photo manipulation. I would like to soften the edges in a perceptually smooth (nonlinear) and gradual (stretched out) way so that the "seams" don't show. Feathering works to a certain extent but it doesn't look natural. Any ideas?

[Edited for clarity.]
Last edited by afre on 2015-03-24T19:14:40-07:00, edited 1 time in total.
ImageMagick 7.0.7-25 Q16 x64 2018-03-04 · Cipher DPC HDRI Modules OpenMP · Windows 7
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Midtone Mask

Post by snibgo »

Sorry, I don't understand any of that paragraph on feathering.

Perhaps you simply want to blur the mask?
snibgo's IM pages: im.snibgo.com
afre
Posts: 57
Joined: 2014-01-22T15:02:53-07:00
Authentication code: 6789

Re: Midtone Mask

Post by afre »

Blurring alone doesn't solve my problem; however, it does help smooth the feathering. Unfortunately, the feathering doesn't always work either. Anyway, I'll dodge the issue by dropping the xc:black/whites and using gradient:s exclusively.

How about something more complex? E.g., how would I go about doing this in YCbCr space?

Code: Select all

177 > Cr > 137
127 > Cb > 77
215 > Cb + 0.6Cr > 190
ImageMagick 7.0.7-25 Q16 x64 2018-03-04 · Cipher DPC HDRI Modules OpenMP · Windows 7
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Midtone Mask

Post by snibgo »

You could do this (Windows BAT syntax):

Code: Select all

convert ^
  in.png ^
  -colorspace YCbCr ^
  -fx "177/255>u.b&&u.b>137/255&&127/255>u.g&&u.g>77/255&&215/255>u.g+0.6*u.b&&u.g+0.6*u.b>190/255?1:0" ^
  -set colorspace sRGB ^
  out.png
For large images, it will be slow. You could make a hald-clut image, which only needs making once, then use that on as many images as you want.

Code: Select all

convert ^
  hald:12 ^
  -colorspace YCbCr ^
  -fx "177/255>u.b&&u.b>137/255&&127/255>u.g&&u.g>77/255&&215/255>u.g+0.6*u.b&&u.g+0.6*u.b>190/255?1:0" ^
  -set colorspace sRGB ^
  ycbcr_hc.png

convert ^
  in.png ^
  ycbcr_hc.png ^
  -hald-clut ^
  -threshold 50%% ^
  out.png
snibgo's IM pages: im.snibgo.com
afre
Posts: 57
Joined: 2014-01-22T15:02:53-07:00
Authentication code: 6789

Re: Midtone Mask

Post by afre »

snibgo wrote:You could do this (Windows BAT syntax):
Thanks. That helps answer the second part of my initial post, giving me a better idea of how -fx works.

I also edited my other post so that it makes more sense. I'm not very good at articulating my thoughts :?
ImageMagick 7.0.7-25 Q16 x64 2018-03-04 · Cipher DPC HDRI Modules OpenMP · Windows 7
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Midtone Mask

Post by snibgo »

A sudden change of tonal gradient will be visible in a mask, though perhaps not in the masked photograph. "-sigmoidal-contrast" steepens the gradient at the mid-point but reduces it at the ends, so it reduces this sudden change. Other transformations can entirely eliminate the gradient at the ends (#5 below). For example, using a blur method of Fred's (Windows BAT syntax):

Code: Select all

%IM%convert -size 100x100 xc:white -background black -gravity center -extent 200x200 fthr_test.png

%IM%convert fthr_test.png -blur 20x65000 -level 0x50%% fthr_test2.png

%IM%convert fthr_test.png -blur 20x65000 -level 0x50%% -sigmoidal-contrast 5,50%% fthr_test3.png

%IM%convert fthr_test.png -blur 25x65000 -level 0x50%% -sigmoidal-contrast 5,50%% fthr_test4.png

%IM%convert fthr_test.png -blur 20x65000 -level 0x50%% -function sinusoid 0.5,-90,0.5,0.5 fthr_test5.png
Image
Image
Image
Image
Image
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Midtone Mask

Post by fmw42 »

afre
Posts: 57
Joined: 2014-01-22T15:02:53-07:00
Authentication code: 6789

Re: Midtone Mask

Post by afre »

I have 2 questions regarding syntax that's loosely related to the topic.
  1. I am trying to combine these two commands:

    Code: Select all

    convert in.png -define modulate:colorspace=LCHuv -modulate 100,100,85 ycbcr_hc.png -hald-clut -threshold 50% mask.png
    and

    Code: Select all

    convert in.png mask.png -compose CopyOpacity -composite out.png
    I've tried using +clone with ( ) but get a complaint about -compose and what's after.
  2. snibgo, I would like to learn more about the multi-line syntax you use. Please point me in the right direction. I normally scrunch everything up into a single line, which isn't very readable. What I've noticed so far:
    • Command line doesn't like nested indentation.
    • Sometimes the ^ notation doesn't work perhaps due to the expected amount of spaces (e.g. after DO)
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Midtone Mask

Post by snibgo »

I would combine your two commands like this (Windows BAT syntax). The mask should be black and white only, so I add "-alpha off ".

Code: Select all

convert ^
  in.png ^
  ( +clone ^
    -define modulate:colorspace=LCHuv -modulate 100,100,85 ^
    ycbcr_hc.png -hald-clut ^
    -threshold 50%% ^
  ) ^
  -alpha off ^
  -compose CopyOpacity -composite ^
  out2.png
The way I do this is:

1. I break your commands into lines, which makes them easier for me to understand. I use BAT files, so "50%" needs to be "50%%".

Code: Select all

convert ^
  in.png ^
  -define modulate:colorspace=LCHuv -modulate 100,100,85 ^
  ycbcr_hc.png -hald-clut ^
  -threshold 50%% ^
  mask.png

convert ^
  in.png ^
  mask.png ^
  -alpha off -compose CopyOpacity ^
  -composite out.png
2. I see that your first command reads in.png and write mask.png. The second command reads these two files, and creates out.png. So my version can read in.png, create the mask as a temporary (in-memory) result, then create the output. So I make a clone of the input to create the mask. I use parentheses ( and ) so the processing will be done to the mask only, not also to in.png.

3. I compare my output with yours, for a certain in.png:

Code: Select all

%IM%compare -metric RMSE out.png out2.png NULL:
The result is zero, meaning they are identical.
I would like to learn more about the multi-line syntax you use. Please point me in the right direction.
See me web pages for many examples.

"convert" commands can be split anywhere there is a space (apart from spaces inside quotes), and its lines can be indented. (Indents are just extra spaces.) They work exactly as if they were on a single line. I split them so I can understand them more easily.

The Windows "for" command can't be split anywhere there is a space, and indenting can cause problems. These days, my usual syntax is something like:

Code: Select all

for /F "usebackq" %%L in (`convert ^
  infile ^
  {procesing} ^
  outfile`) do {something}
The last character on each line apart from the last must be caret ^.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Midtone Mask

Post by fmw42 »

Here is another way to created a midtone mask

# select the L channel from LAB
# do black threshold at about 25% so everything below 25% graylevel is black
# do white threshold at about 75% so everhthing above 75% is white, but then make white into black so all above 75% is black, also
# threshold at 0 so everything but pure black is white
# blur by a small amount and use -level 0x50% to feather, so anything above 50% after the blur is white and anything below is left as feather ramp

I believe this is correct Windows syntax, but snibgo can correct, if needed as I am a Mac user and use unix syntax

convert yourimage -colorspace LAB -channel red -separate +channel ^
-black-threshold 25% -white-threshold 75% -fill black -opaque white -threshold 0 ^
-blur 0x2 -level 0x50% mask.png

You can use any intensity like channel such as Y from YCbCr/YUV/YIQ or from another L* colorspace or just grayscale or rms.

You can blur more or less.

You can choose your percents differently, such as the mean +- the std. There are lots of variations, but this is the basic technique I have used.
afre
Posts: 57
Joined: 2014-01-22T15:02:53-07:00
Authentication code: 6789

Re: Midtone Mask

Post by afre »

fmw42: that's the answer I was looking for.
snibgo: I'll continue the syntax discussion in a new topic.
afre
Posts: 57
Joined: 2014-01-22T15:02:53-07:00
Authentication code: 6789

Re: Midtone Mask

Post by afre »

  1. I would like to quickly display the result; however, when I do

    Code: Select all

    > display rose: -OR- convert rose: show: -OR- convert rose: win:
    display: unable to open X server `' @ error/display.c/DisplayImageCommand/426.
    -OR-

    Code: Select all

    > convert rose: x:
    convert: unable to open X server `' @ error/display.c/DisplayImages/1667.
  2. Also, is there a way to display an image and mouse-select a pixel position or range to use later in the script? I.e. I would like to select an object and see if it ends up in or outside of the mask. If it isn't, then it does something to make it so.
Thanks again.
Post Reply