在深度学习中,无论是人脸识别,目标检测还是其他关于图像方面的技术,都需要用到图片样本。那么样本的预处理、清洗就经常出现在我们视线中,而修改图片的颜色、对比度、色调就可以说是最基本的任务了。Python中提供了Opencv这个库,这个库有着强大的处理功能,程序员可以直接调用里边的函数来对图像进行修改颜色通道以及其他特别处理。
1.灰度图
在现实世界中,万物拥有大量丰富的色彩。通常,我们描绘一幅图是以RGB,也就是三原色的形式来描述。(在opencv中,三通道的顺序是BGR而不是RGB)而在而在计算机运算中,输入的图像一般不是由三原色组成的图像,而是灰度图。所谓灰度图,就是把白色与黑色之间按对数的关系分成256份,也为256阶。
在Opencv作处理图像时,有一种算法,叫做灰度世界算法。这种算法是用来平衡图像颜色,以消除环境的光照强度对图像造成影响。这样,就可以获取原始场景的图像。
算法原理如下:
分别计算RGB三通道的平均值,利用得出的比例因子再作用于图像的每个像素,构成新的图片。
def grey_world(img):
img= img.transpose(2, 0, 1).astype(np.uint32)
avgB = np.average(img[0])
avgG = np.average(img[1])
avgR = np.average(img[2])
avg = (avgB + avgG + avgR) / 3
img[0] = np.minimum(img[0] * (avg / avgB), 255)
img[1] = np.minimum(img[1] * (avg / avgG), 255)
img[2] = np.minimum(img[2] * (avg / avgR), 255)
return img.transpose(1, 2, 0).astype(np.uint8)
但是缺点在于,当图像中出现大量的单色物体时,这种算法就不适用。
2.图像直方图
在图像中,直方图算是一个比较基础的概念,所谓直方图。我们可以通过直方图得出图像的像素位于直方图的哪些区域。虽然有时候并不局限于像素集中在很窄的范围内,也包括某一些的强度值使用频率过大。我们也经常使用直方图均衡化也均衡图像的对比度,通过calcHist方法后,得出的直方图为一维数据。
image = cv2.imread("img.jpg")
hist= cv2.calcHist([image])
在某些情况下,一副图像中大部分像素的强度都集中在某一区域,而质量较高的图像中,像素的强度应该均衡的分布。为此,可将表示像素强度的直方图进行拉伸,将其平坦化,使之均匀分布在全部的灰度范围中,那么黑白之间的像素级就会更加连续,更加均匀。
直方图均衡化
在利用图像直方图处理图像时,一般是需要先将彩色的图像转为灰度图像,之后再做直方图均衡化处理。
当然,彩色图像也可以通过改变颜色空间。首先将RGB颜色空间转为YUV颜色空间,再在YUV颜色空间中修改,以达到均衡化的结果。与灰度图像不同的是,彩色图像需要先用split方法将三个通道拆分开,再分别对每一个通道进行处理。最后再用merge方法合并三个通道。
直方图均衡化处理的“中心思想”是把原始图像的直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布,使重新分配图像像素大小,让整体灰度范围内的像素数量大致相同。
(b, g, r) = cv2.split(img)
blue = cv2.equalizeHist(b)
green = cv2.equalizeHist(g)
red = cv2.equalizeHist(r)
# 合并每一个通道
result = cv2.merge((blue, green, red))
直方图归一化
直方图归一化我用的比较少,这里简单介绍一下。直方图归一化是使整体图像数值的绝对值变成某种相对值关系。是简化计算,缩小量值的有效办法。
cv2.normalize(src, dst, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
函数介绍:cv2.normalize(src, dst, alpha, beta, norm_type, dtype, mask)
src-输入数组
dst-输出数组,支持原地运算
alpha-range normalization模式的最小值
beta-range normalization模式的最大值,不用于norm normalization(范数归一化)模式
normType-归一化的类型
dtype-dtype为负数时,输出数组的type与输入数组的type相同;否则,输出数组与输入数组只是通道数相同,而tpye=CV_MAT_DEPTH(dtype)
mask-操作掩膜,用于指示函数是否仅仅对指定的元素进行操作
3.通过查表方法拉伸直方图
除了以上提及的方法改变直方图,还可以通过查表方法对其进行处理。
def HistProgress(img1, img2):
hist,bins = np.histogram(img1.flatten(), 256, [0,256])
cdf = hist.cumsum()
cdf_m = np.ma.masked_equal(cdf, 0) #除去直方图中的0值
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max() - cdf_m.min())
cdf = np.ma.filled(cdf_m, 0).astype('uint8') #将掩模处理掉的元素补为0
result1 = cv2.LUT(img1, cdf)
result2 = cv2.LUT(img2, cdf)
cv2.imwrite('result11.jpg', result1)
cv2.imwrite('result22.jpg', result2)
以上的程序的意义在于先得出一张图的cdf(累积分布函数),然后分别作用于两张图(一张原图,另一张为其他图片)。这样做在于可以增强原图的对比度;其次还可以通过根据图一的cdf值,改变图二的颜色,使图二的颜色与图一相差无几。
4.颜色空间
RGB
计算机色彩显示器和彩色电视机显示色彩的原理一样,在RGB颜色空间中,任意色光F都可以用R、G、B三色不同分量的相加混合而成。当RGB的三原色分量都为0时,混合后为黑光;当RGB的三原色分量最大时,混合后为白光。
YUV
YUV也叫YCrCb,在欧洲较为常见,是欧洲电视所采用的的颜色编码方法。它与RGB的图像信号映射为:
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
R = Y + 1.14V
G = Y - 0.39U - 0.58V
B = Y + 2.03U
HSV
我们日常所提及的色调,饱和度,亮度就是指HSV颜色空间。HSV颜色空间可以用一个圆锥空间模型来描述。圆锥的顶点处,V=0,H和S无定义,代表黑色。圆锥的顶面中心处V=max,S=0,H无定义,代表白色。
色调(H)是色彩的基本属性,就是平常说的颜色的名称,如红色、黄色等。
饱和度(S)是指色彩的纯度,越高色彩越纯,低则逐渐变灰,取0-100%的数值。
亮度(V)即图像的明亮程度。
RGBA
有时,我们还会以及RGBA这颜色空间,它仅仅是给RGB添加了额外的信息:Alpha,也就是图像的透明度。如果Alpha的值为0,那么它就是完全透明的;而100,则意味着它完全不透明。
5.图片格式
我们在保存图片的时候通常有jpg,jpeg,png选择,那么这一些有什么区别呢?
jpg
jpg应该是使用最多的一种图片格式,但是生成jpg的时候就会损耗图像,它是会将图像中的一些数据丢失后再进行压缩保存。虽然在保存时图像会失真,但是色彩还原程度较好,可以支持适当压缩后保持比较好的色彩度。
jpeg
jpeg格式与jpg格式相差不大,只是这一种格式的存储文件相对于jpg来说较大,因为jpeg还包含色调,饱和度,对比度这一些参数。
png
png是网页中使用最多的一种格式,因为它和jpg,jpeg不同,png格式的图像支持透明。网页设计中为了使图片下面的背景颜色显示出来,我们经常会使用png24透明的图片。
bmp
除了以上介绍的三种,还有bmp格式。它是windows操作系统特有的图片,这种图片保存了大量的图片数据,所以图片相对是比较大的,色彩度也较为真实。
6.色调,对比图,饱和度
色调是指物体反射的光线中以哪种波长占优势来决定的,不同波长产生不同颜色的感觉,色调是颜色色调的重要特征,它决定了颜色本质的根本特征。
对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,差异范围越大代表对比越大,差异范围越小代表对比越小。
饱和度是指色彩的鲜艳程度,也称色彩的纯度。饱和度取决于该色中含色成分和消色成分(灰色)的比例。含色成分越大,饱和度越大;消色成分越大,饱和度越小。
以上内容如有错误,欢迎指出。谢谢!