一、图像色彩转换
(1)原理
- 首先我们讲解下图像的一种表示方法:RGB
- 其次我们再了解下图像的另一个表示:HSB,也叫作HSV
RGB
RGB,是指颜色的三原色,分别代表红色(red),绿色(green),蓝色(blue),用这是三种颜色混合可以表示任意的颜色。RGB是根据颜色发光的原理来设计的,比如这里有红绿蓝三道光,当三束光混合在一起的时候,其呈现的最终的光效颜色就取决于这三种原色光的强弱了。
- 比如说红光最强,绿光和蓝光几乎没有,那么最后结果肯定呈现为红光了。
- 如果蓝光很弱,红光和绿光非常强,那么结果就是红光和绿光的混合光,也就黄光。
- 如果红绿蓝三种光都非常强,那么就会呈现三种光的混合光,也就是白光。
- 如果三种光都非常弱,那就几乎没有光,自然就是黑色了。
混合光图
这是一张平面图,没有很好地体现三原色的混合关系,可以看下面的三维立体图。
实际上可以对 RGB 色值建立一个三维坐标系,坐标原点就在上图中所看不见的那个正方体顶点,像左延伸为 R 红色轴,向右延伸为 B 蓝色轴,向上延伸为 G 绿色轴。
RGB 在进行色彩表示时使用了 256 阶,也就是从 0-255,可以由一个字节来表示。数值越大,RGB 三个轴,每个轴对应的数值越大,就代表其亮度越高,最亮就对应着 255,最暗就对应着 0。三个轴上的三个数字联合起来可以用来表示一个颜色。
例如:
- (255, 255, 255) 就代表 RGB 都是满的,组成白色。
- (255, 255, 0) 就代表 R 红色是满的,G 绿色是满的,B 蓝色是没有的,红色和绿色混合为黄色,所以它就表示黄色。
- (0, 0, 0) 就代表 RGB 都是没有的,呈现黑色。
因此,通过这三个数值,我们就可以实现任何颜色的表示了。
HSB
如果我们要做一张图片的色彩的转换,了解RGB还不足以支撑我们去完成这个任务。因为要对一张图片实现色彩的转换,需要调节的是色相。那么色相是什么呢?它就是我们将要谈到的HSB中的H了。
HSB,又叫做 HSV,其实也是三个参数,分别是色调(Hue)、饱和度(Saturation)、明度(Brightness),在 HSV 中 V 代表 Value,也是明度(Brightness)的意思。通过这三个值,我们同样可以表示任意的颜色。
首先我们看看 HSV (HSB) 颜色模型的坐标轴图吧,它可以用这么一个锥形的坐标来表示:
色调,Hue,它是一种角度度量,就是图中 Hue 所示的角度,绕圆锥体一周。它的值是从红色开始逆时针方向计算的,红色是 0,绿色是 120,蓝色为 240,形成一个红绿蓝三原色组成的色带。
饱和度,Saturation,它是图中 Saturation 所示的方向,由最上面圆的圆心向外扩散。它表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为 0,饱和度达到最高。通常取值范围为 0-100,值越大,颜色越饱和。也就是说图中,圆心处饱和度为 0,越靠近边,饱和度越高,最高达到 100。
明度,Brightness,它表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关,对于物体色,此值和物体的透射比或反射比有关。通常取值范围为 0-100,0 对应黑色,100 对应白色。
另外大家如果用到取色板的话,它是这样子的:
你可以看到左边有个大的矩形,右边有个竖直的彩虹带。由于刚才所说的圆锥坐标不好表示,在调色板里面就把圆锥坐标拆成了两部分。
- 右边的彩虹带就可以选择色调 Hue,拖动彩虹带的箭头位置就可以调整 Hue 的值。
- 左边的正方形就和饱和度 Saturation、明度 Brightness 有关,横坐标表示饱和度 Saturation,纵坐标表示 Brightness,从左到右,饱和度 Saturation 变高,从下到上,明度 Brightness 变高。
- 左下角,由于饱和度 Saturation 和明度 Brightness 都为 0,就呈现黑色。
- 左上角,由于饱和度 Saturation 为 0,所以相当于没有颜色,颜色最浅,但是它的明度 Brightness 达到了最高,所以它就显示没有颜色的明度最高的色,即白色。
- 右上角,由于饱和度 Saturation 和明度 Brightness 都为最高,那就显示最纯的 Hue 值。
这也就是 HSB 颜色模型的原理。
同样地,我们可以用 HSB 的三个值来表示任意的颜色,因此 HSB 也成为表示颜色的基本标准之一。
(2)代码
def color_space_demo(image):
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("gray", gray)
hsv=cv.cvtColor(image, cv.COLOR_BGR2HSV)
cv.imshow("hsv", hsv)
gray=cv.cvtColor(src, cv.COLOR_BGR2GRAY)
color_space_demo(src)
(3) 运行结果
RGB
HSV
二、图像直方图
(1)原理
灰度直方图概括了图像的灰度级信息,简单的来说就是每个灰度级图像中的像素个数以及占有率,创建直方图无外乎两个步骤,统计直方图数据,再用绘图库绘制直方图。
统计数据:
首先要稍微理解一些与函数相关的术语,方便理解其在python2库中的应用和处理
BINS: 在上面的直方图当中,如果像素值是0到255,则需要256个值来显示直 方图。但是,如果不需要知道每个像素值的像素数目,只想知道两个像素值之间的像素点数目怎么办?例如,想知道像素值在0到15之间的像素点数目,然后是16到31。。。240到255。可以将256个值分成16份,每份计算综合。每个分成的小组就是一个BIN(箱)。在opencv中使用histSize表示BINS。
DIMS: 数据的参数数目。当前例子当中,对收集到的数据只考虑灰度值,所以该值为1。
RANGE: 灰度值范围,通常是[0,256],也就是灰度所有的取值范围。
该函数的参数在了解以上术语加上自己百度后可以简单应用
使用numpy统计函数,主要应用numpy.histogram()函数(还有np.bincount())
绘制直方图:
绘制直方图一般使用Matplotlib绘制 ,这里要提一下matplotlib的matplotlib.pyplot.hist()函数,该函数可以直接统计绘制中方图。统计函数为calcHist() 或 np.histogram()
(2)代码
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread("D:\images\hua.jpg")
cv.imshow("input image", img)
plt.hist(img.ravel(), 256, [0, 256])
plt.show()
color = ('b', 'g', 'r')
for i, col in enumerate(color):
histr = cv.calcHist([img], [i], None, [256], [0, 256])
plt.plot(histr, color=col)
plt.xlim([0, 256])
plt.show()
(3)运行结果
由于我的是彩色图像,所以我对图像红、绿、蓝三个通道进行直方图的绘制
三、图像均衡化
(1)原理
直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法,其主要思想是将一副图像的直方图分布变成近似均匀分布,从而增强图像的对比度。这种方法通常用来增加许多图像的全局对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布,这样就可以用于增强局部的对比度而不影响整体的对比度。这种方法对于背景和前景都太亮或者太暗的图像非常有用,这种方法尤其是可以带来X光图像中更好的骨骼结构显示以及曝光过度或者曝光不足照片中更好的细节。这种方法的一个主要优势是它是一个相当直观的技术并且是可逆操作,如果已知均衡化函数,那么就可以恢复原始的直方图,并且计算量也不大。这种方法的一个缺点是它对处理的数据不加选择,它可能会增加背景噪声的对比度并且降低有用信号的对比度。直方图均衡化和规定化都是通过全局直方图调节来改变图像的对比度,其实就是根据一个表来做映射。均衡化一句话,就是拿图像本身的累积分布表(cdf)来做映射。规定化就是图像B拿图像A的累积分布表(cdf)来做映射。
(2) 代码
import cv2
import numpy as np
def drawHist(hist):
img = np.zeros((256, 256), np.uint8)
r = max(hist) / 255
for i in range(0, 256):
hist[i] = hist[i] / r
cv2.line(img, (i, 255), (i, 255 - hist[i]), 255)
return img
img = cv2.imread("D:\images\hua.jpg", 0)
hist1 = cv2.calcHist([img],
[0],
None,
[256], # it is a 1D histogram
[0.0, 255.0])
hist11 = hist1.cumsum()
hist111 = hist11.reshape(hist1.shape)
equ = cv2.equalizeHist(img)
hist2 = cv2.calcHist([equ],
[0],
None,
[256], # it is a 1D histogram
[0.0, 255.0])
hist22 = hist2.cumsum()
hist222 = hist22.reshape(hist2.shape)
a = drawHist(hist1)
a1 = drawHist(hist111)
cv2.imshow("before graph", a)
cv2.imshow("before total graph", a1)
print
b = drawHist(hist2)
b1 = drawHist(hist222)
cv2.imshow("after graph", b)
cv2.imshow("after total graph", b1)
cv2.waitKey()
cv2.destroyAllWindows()
(3) 运行结果
四、图像模糊(高斯滤波)
(1) 原理
通常,图像处理软件会提供”模糊”(blur)滤镜,使图片产生模糊的效果。“模糊”的算法有很多种,其中有一种叫做“高斯模糊”(Gaussian Blur)。它将正态分布(又名”高斯分布”)用于图像处理。高斯滤波对于抑制服从正态分布的噪声效果非常好,其代价是使图像变得“模糊”。当然,有时对图像进行平滑滤波的目的就是让图像变得模糊。
(2)代码
def gaussian_noise(image):
h, w, c =image.shape
for row in range(h):
for col in range(w):
s=np.random.normal(0, 20, 3)
b = image[row, col, 0] #blue
g = image[row, col, 1] #green
r = image[row, col, 2] #red
image[row, col, 0] = clamp(b + s[0])
image[row, col, 1] = clamp(b + s[1])
image[row, col, 2] = clamp(b + s[2])
cv.imshow("noise image", image)
print("-------Hello Python------")
src=cv.imread("D:\images\hua.jpg")
cv.imshow("input image", src)
#gray=cv.cvtColor(src, cv.COLOR_BGR2GRAY)
cv.imwrite("D:/images/result.jpg", gray)
get_image_info(src)
gaussian_noise(src)
dst =cv.GaussianBlur(src, (5, 5), 1)
cv.imshow("Gaussian image", dst)
#color_space_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
(3)运行结果
加了噪声处理:
利用高斯函数:(高斯函数中,变量x的值可以改动,从而呈现不同的效果,这里我设置的为0)