skip to Main Content

I want to do something similar to the levels function in Photoshop, but can’t find the right openCV functions.

Basically I want to stretch the greys in an image to go from almost white to practically black instead of from almost white to slightly greyer, while leaving white as white and black as black (I am using greyscale images).

3

Answers


  1. I don’t know what are the “Photoshop levels”. But from description, I think you should try the following:

    1. Convert your image to YUV using cvtColor. Y will represent the intensity plane. (You can also use Lab, Luv, or any similar colorspace with separate intensity component).
    2. Split the planes using split, so that the intensity plane will be a separate image.
    3. Call equalizeHist on the intensity plane
    4. Merge the planes back together using merge

    Details on histogram equalization can be found here

    Also note, that there’s an implementation of somewhat improved histogram equalization method – CLAHE (but I can’t find a better link than this, also @berak suggested a good link on the topic)

    Login or Signup to reply.
  2. I think this is a function mapping input levels to output levels as shown below in the figure.

    enter image description here

    For example, the orange curve is a straight line from (a, c) to (b, d), blue curve is a straight line from (a, d) to (b, c) and green curve is a non-linear function from (a,c) to (b, d).

    We can define the blue curve as (x – a)/(y – d) = (a – b)/(d – c).
    Limiting values of a, b, c and d depend on the range supported by the channel that you are applying this transformation to. For gray scale this is [0, 255].

    For example, if you want a transformation like (a, d) = (10, 200), (b, c) = (250, 50) for a gray scale image,

    y = -150*(x-10)/240 + 200 for x [10, 250]

    y = x for [0, 10) and (250, 255] if you want remaining values unchanged.

    You can use a lookup table in OpenCV (LUT function) to calculate the output levels and apply this transformation to your image or the specific channel. You can apply any piecewise transformation this way.

    Login or Signup to reply.
  3. The following python code fully implements Photoshop Adjustments -> Levels dialog.

    Change the values for each channel to the desired ones.

    img is input rgb image of np.uint8 type.

    inBlack  = np.array([0, 0, 0], dtype=np.float32)
    inWhite  = np.array([255, 255, 255], dtype=np.float32)
    inGamma  = np.array([1.0, 1.0, 1.0], dtype=np.float32)
    outBlack = np.array([0, 0, 0], dtype=np.float32)
    outWhite = np.array([255, 255, 255], dtype=np.float32)
    
    img = np.clip( (img - inBlack) / (inWhite - inBlack), 0, 255 )                            
    img = ( img ** (1/inGamma) ) *  (outWhite - outBlack) + outBlack
    img = np.clip( img, 0, 255).astype(np.uint8)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search