arn*_*ino 6 python opencv image image-processing python-imaging-library
我正在尝试处理图像,并且想使图像的黑暗区域变亮。我尝试了直方图均衡,但由于图像中也存在一些明亮区域,结果并不令人满意。这就是为什么我正在寻找一种方法来仅使图像的黑暗区域变亮。
例如,输入图像在左侧,预期结果在右侧,女孩的头发和脸部变亮
ImageMagick 似乎提供了一些实现此目的的可能性,但是,我想使用 python 来实现
如果您想避免颜色失真,您可以:
\n事情可能是这样的:
\nfrom PIL import Image\n\n# Open the image\nim = Image.open(\'hEHxh.jpg\')\n\n#\xc2\xa0Convert to HSV colourspace and split channels for ease of separate processing\nH, S, V = im.convert(\'HSV\').split()\n\n# Increase the brightness, or Value channel\n#\xc2\xa0Change 30 to 50 for bigger effect, or 10 for smaller effect\nnewV = V.point(lambda i: i + int(30*(255-i)/255))\n\n#\xc2\xa0Recombine channels and convert back to RGB\nres = Image.merge(mode="HSV", bands=(H,S,newV)).convert(\'RGB\')\n\nres.save(\'result.jpg\')\nRun Code Online (Sandbox Code Playgroud)\n\n本质上,我将亮度从黑色映射更改为绿色映射:
\n\n提醒健忘的自己…… “你把情节弄成了这样,马克”:
\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Generate some straight-line data\nxdata = np.arange(0,256)\n# And the new mapping\nydata = xdata + 30*(255-xdata)/255\n\n# Plot\nplt.plot(xdata,xdata,\'.k\')\nplt.plot(xdata,ydata,\'g^\')\nplt.title(\'Adjustment of V\')\nplt.xlabel(\'Input V\')\nplt.ylabel(\'Output V\')\nplt.grid(True)\nplt.show()\nRun Code Online (Sandbox Code Playgroud)\n
这是在 Imagemagick 和 Python/OpenCV 中执行此操作的一种方法。使用三角法对 LAB 色彩空间的 L 通道进行阈值处理。然后使整个图像变亮。然后使用阈值作为掩模合并原始图像和增亮图像。
图像魔法:
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
Run Code Online (Sandbox Code Playgroud)
临界点:
结果:
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()
Run Code Online (Sandbox Code Playgroud)
临界点:
结果: