Home > Software engineering >  Create a curve which adjust the contrast and brightness respectively of an image that is loaded
Create a curve which adjust the contrast and brightness respectively of an image that is loaded

Time:11-30

I have a series of images and was wondering if there is a possibility to write something in python to apply a contrast and brightness curve Like in the images below.

enter image description here. enter image description here

CodePudding user response:

You should refer to, for instance, the OpenCV website (you can learn a lot of interesting methods and have a lot of examples on CV problems), here you have some documentation to check:

  • enter image description here

    The actual code you need only really starts here:

    # Derive Catmull-Rom spline for our X,Y
    res = splines.CatmullRom(yvals, xvals)
    
    # Make LUT (Lookup Table) from spline
    LUT = np.uint8(res.evaluate(range(0,256)))
    
    # Load ramp image as greyscale
    im = cv2.imread('ramp.png', cv2.IMREAD_GRAYSCALE)
    
    # Apply LUT to image
    stretched = cv2.LUT(im, LUT)
    
    # Save result
    cv2.imwrite('result.png', stretched)
    

    That turns this ramp:

    enter image description here

    into this:

    enter image description here

    Note that I artificially added a thin red border so you can see the extent of the image on StackOverflow's annoying background.


    As regards reading a Photoshop Curves file (ACV or .acv), I wrote some code a while back that parses them but I haven't integrated that with the code above - it shouldn't be too hard - you basically save the points from the ACV file and use them to generate the spline for the above code. I leave it below for anyone interested to play with:

    """
    ################################################################################
    fauxtoshop - does some things like Adobe Photoshop
    
    Mark Setchell ([email protected])
    
    Reads, interprets and possibly applies Photoshop files:
    
    - Curves files (*.acv)
    - Levels files (*.alv)
    - Filter Kernel files (*.acf)
    - Hue Saturation files (*.ahu)
    ################################################################################
    """
    
    import sys
    import numpy
    from struct import unpack
    
    def loadFilter(filename):
    
        if filename.lower().endswith('.acv'):
            loadCurvesFilter(filename)
            return
    
        if filename.lower().endswith('.alv'):
            loadLevelsFilter(filename)
            return
    
        if filename.lower().endswith('.acf'):
            loadKernelFilter(filename)
            return
    
        if filename.lower().endswith('.ahu'):
            loadHSLFilter(filename)
            return
    
        sys.exit(f'ERROR: Unknown file extension {filename}')
    
    def loadCurvesFilter(filename):
    
        with open(filename, 'rb') as f:
           version, ncurves = unpack('>HH', f.read(4))
           print(f'File: {filename}')
           print(f'Version: {version}')
           if version != 4:
              sys.exit('ERROR: Cowardly refusing to read version other than 4')
           print(f'Curve count: {ncurves}')
           curves = []
           for c in range(ncurves):
              npoints, = unpack('>H', f.read(2))
              print(f'Curve: {c}, {npoints} points follow:')
              curve = []
              for p in range(npoints):
                 y, x = unpack('>HH', f.read(4))
                 print(f'Curve: {c}, point: {p}, x={x}, y={y}')
                 curve.append((x,y))
              curves.append(curve)
        return curves
    
    def loadLevelsFilter(filename):
        sys.exit("ERROR: Levels filter not yet implemeted")
    
    def loadKernelFilter(filename):
        sys.exit("ERROR: Kernel filter not yet implemeted")
    
    def loadHSLFilter(filename):
    
        with open(filename, 'rb') as f:
           version, usage, pad = unpack('>HBB', f.read(4))
           print(f'File: {filename}')
           print(f'Version: {version}')
           if version != 2:
              sys.exit('ERROR: Cowardly refusing to read version other than 2')
           if usage == 0:
               print('Usage: Hue adjustment')
           else:
               print('Usage: Colorization')
               sys.exit(f'ERROR: Cowardly refusing to apply colorization rather than Hue adjustment')
           MasterHue, MasterSaturation, MasterLightness = unpack('>HHH', f.read(6))
           print(f'Master Hue: {MasterHue}')
           print(f'Master Saturation: {MasterSaturation}')
           print(f'Master Lightness: {MasterLightness}')
           # There follow 6 hextants, each with 4 range values and 3 settings values
           for h in range(6):
               ranges = unpack('>HHHH',f.read(8))
               settings = unpack('>HHH', f.read(6))
               print(f'Hextant: {h}, ranges: {ranges}, settings: {settings}')
               
    ################################################################################
    # main
    ################################################################################
    if __name__ == '__main__':
    
       if len(sys.argv) not in set([2,3]):
          print('Usage: {sys.argv[0]} filter.[acv|ahu|alv|acf] [image]', file=sys.stderr)
          sys.exit(1)
    
       if len(sys.argv) == 2:
          loadFilter(sys.argv[1])
    

    Note also that you can apply a Photoshop Curves (ACV) file using ffmpeg like this:

    ffmpeg -i input.jpg -vf curves=psfile="curves.acv" output.jpg 
    
  • Related