我需要对彩色图像进行直方图均衡化。
首先,我将彩色图像转换为灰色并将其转换为equalizeHist
函数:
image = cv2.imread("photo.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.equalizeHist(image)
cv2.imshow("equalizeHist", image)
cv2.waitKey(0)
但在此之后我需要将图像转换回RGB;我怎么能这样做?
答案 0 :(得分:28)
import cv2
import numpy as np
img = cv2.imread('input.jpg')
img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
# equalize the histogram of the Y channel
img_yuv[:,:,0] = cv2.equalizeHist(img_yuv[:,:,0])
# convert the YUV image back to RGB format
img_output = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
cv2.imshow('Color input image', img)
cv2.imshow('Histogram equalized', img_output)
cv2.waitKey(0)
答案 1 :(得分:6)
import cv2
def run_histogram_equalization(image_path):
rgb_img = cv2.imread(image_path)
# convert from RGB color-space to YCrCb
ycrcb_img = cv2.cvtColor(rgb_img, cv2.COLOR_BGR2YCrCb)
# equalize the histogram of the Y channel
ycrcb_img[:, :, 0] = cv2.equalizeHist(ycrcb_img[:, :, 0])
# convert back to RGB color-space from YCrCb
equalized_img = cv2.cvtColor(ycrcb_img, cv2.COLOR_YCrCb2BGR)
cv2.imshow('equalized_img', equalized_img)
cv2.waitKey(0)
直方图均衡化 (HE) 是一种用于分散强度值的统计方法。在图像处理中,HE用于提高任何图像的对比度,即让暗部更暗,亮部更亮。
对于灰度图像,每个像素由强度值(亮度)表示;这就是为什么我们可以将像素值直接提供给 HE 函数的原因。但是,对于 RGB 格式的彩色图像,它不是这样工作的。 R、G和B的每个通道代表相关颜色的强度,而不是图像整体的强度/亮度.因此,在这些颜色通道上运行 HE 不是正确的方法。
我们应该首先将图像的亮度与颜色分开,然后对亮度运行 HE。现在,已经有标准化的色彩空间,分别对亮度和颜色进行编码,例如-YCbCr、HSV 等;所以,我们可以在这里使用它们来分离然后重新合并亮度。正确的方法:
将色彩空间从 RGB 转换为 YCbCr >> 在 Y 通道上运行 HE(该通道代表亮度)>>将色彩空间转换回 RGB
对于 HSV 色彩空间,HE 应该在 V 通道上运行。然而,YCbCr的Y通道比HSV的V通道更能代表亮度。因此,使用 YCbCr 格式会为 HE 产生更正确的结果。
答案 2 :(得分:3)
您不必先将图像转换为灰度。您可以使用以下方法。上面建议的解决方案使用了YUV颜色空间,但是我将使用HSV颜色空间进行此示例。
image = cv2.imread("photo.jpg")
# convert image from RGB to HSV
img_hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
# Histogram equalisation on the V-channel
img_hsv[:, :, 2] = cv2.equalizeHist(img_hsv[:, :, 2])
# convert image back from HSV to RGB
image = cv2.cvtColor(img_hsv, cv2.COLOR_HSV2RGB)
cv2.imshow("equalizeHist", image)
cv2.waitKey(0)
答案 3 :(得分:2)
我不确定它是否正常运行:
def histogram_equalize(img):
b, g, r = cv2.split(img)
red = cv2.equalizeHist(r)
green = cv2.equalizeHist(g)
blue = cv2.equalizeHist(b)
return cv2.merge((blue, green, red))
答案 4 :(得分:2)
颜色转换方法 cv2.cvtColor() 用于在 RGB/BGR 和 YUV 之间转换原始图像。这是最好的代码片段 -
# convert it to grayscale
img_yuv = cv2.cvtColor(img,cv2.COLOR_BGR2YUV)
# apply histogram equalization
img_yuv[:,:,0] = cv2.equalizeHist(img_yuv[:,:,0])
hist_eq = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
您可以从这里了解更多信息 - https://www.etutorialspoint.com/index.php/311-python-opencv-histogram-equalization
答案 5 :(得分:1)
更通用的方法是将RGB值转换为包含发光/强度值(Luv,Lab,HSV,HSL)的另一个空间,仅在强度平面中应用histeq并执行逆变换。
答案 6 :(得分:1)
img_yuv = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(2,2))
img_yuv[:,:,0] = clahe.apply(img_yuv[:,:,0])
img = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
cv2.imshow("equalizeHist", img)
cv2.waitKey(0)
答案 7 :(得分:0)
如果你想要均衡固定RGB图像,你不应该转换为灰色而不是逐个均衡RGB通道。
所以,我想也许这就是你想要的:
def equalize_hist(img):
for c in xrange(0, 2):
img[:,:,c] = cv2.equalizeHist(img[:,:,c])
cv2.imshow('Histogram equalized', img)
cv2.waitKey(0)
return img
答案 8 :(得分:0)
这是一个将彩色图像作为输入并返回直方图均衡图像的函数。
# function for color image equalization
def histogram_equalization(img_in):
# segregate color streams
b, g, r = cv2.split(img_in)
h_b, bin_b = np.histogram(b.flatten(), 256, [0, 256])
h_g, bin_g = np.histogram(g.flatten(), 256, [0, 256])
h_r, bin_r = np.histogram(r.flatten(), 256, [0, 256])
# calculate cdf
cdf_b = np.cumsum(h_b)
cdf_g = np.cumsum(h_g)
cdf_r = np.cumsum(h_r)
# mask all pixels with value=0 and replace it with mean of the pixel values
cdf_m_b = np.ma.masked_equal(cdf_b, 0)
cdf_m_b = (cdf_m_b - cdf_m_b.min()) * 255 / (cdf_m_b.max() - cdf_m_b.min())
cdf_final_b = np.ma.filled(cdf_m_b, 0).astype('uint8')
cdf_m_g = np.ma.masked_equal(cdf_g, 0)
cdf_m_g = (cdf_m_g - cdf_m_g.min()) * 255 / (cdf_m_g.max() - cdf_m_g.min())
cdf_final_g = np.ma.filled(cdf_m_g, 0).astype('uint8')
cdf_m_r = np.ma.masked_equal(cdf_r, 0)
cdf_m_r = (cdf_m_r - cdf_m_r.min()) * 255 / (cdf_m_r.max() - cdf_m_r.min())
cdf_final_r = np.ma.filled(cdf_m_r, 0).astype('uint8')
# merge the images in the three channels
img_b = cdf_final_b[b]
img_g = cdf_final_g[g]
img_r = cdf_final_r[r]
img_out = cv2.merge((img_b, img_g, img_r))
# validation
equ_b = cv2.equalizeHist(b)
equ_g = cv2.equalizeHist(g)
equ_r = cv2.equalizeHist(r)
equ = cv2.merge((equ_b, equ_g, equ_r))
# print(equ)
# cv2.imwrite('output_name.png', equ)
return img_out