Here is one way to do that in Imagemagick and Python/OpenCV. Threshold the L channel of LAB colorspace using triangle method. Then brighten the whole image. Then merge the original and brightened image using the threshold as a mask.
Imagemagick:
magick girl_on_chair.jpg \
\( -clone 0 -colorspace LAB -channel 0 -separate +channel \
-auto-threshold triangle -negate +write thresh.png \) \
\( -clone 0 -evaluate multiply 4 \) \
+swap -compose over -composite \
girl_on_chair_processed.jpg
Threshold:

Result:

Python/OpenCV:
import cv2
import numpy as np
# read image
img = cv2.imread("girl_on_chair.jpg")
# convert to LAB and extract L channel
LAB = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
L = LAB[:,:,0]
# threshold L channel with triangle method
value, thresh = cv2.threshold(L, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_TRIANGLE)
print(value)
# threshold with adjusted value
value = value + 10
thresh = cv2.threshold(L, value, 255, cv2.THRESH_BINARY)[1]
# invert threshold and make 3 channels
thresh = 255 - thresh
thresh = cv2.merge([thresh, thresh, thresh])
gain = 3
blue = cv2.multiply(img[:,:,0], gain)
green = cv2.multiply(img[:,:,1], gain)
red = cv2.multiply(img[:,:,2], gain)
img_bright = cv2.merge([blue, green, red])
# blend original and brightened using thresh as mask
result = np.where(thresh==255, img_bright, img)
# save result
cv2.imwrite('girl_on_chair_thresh.jpg', thresh)
cv2.imwrite('girl_on_chair_brighten.jpg', result)
cv2.imshow('img', img)
cv2.imshow('L', L)
cv2.imshow('thresh', thresh)
cv2.imshow('img_bright', img_bright)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Threshold:

Result:
