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.
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:
-
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:
into this:
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