参考:https://zhuanlan.zhihu.com/p/44255577
一、图像色彩空间变换函数cv2.cvtColor
图像色彩空间变换函数十分常用,我们应该明白为什么需要做图像色彩的空间处理。
图像色彩空间变换函数的定义:
cv2.cvtColor(input_image, flag)
参数一: input_image表示将要变换色彩的图像ndarray对象
参数二: 表示图像色彩空间变换的类型,以下介绍常用的两种:
· cv2.COLOR_BGR2GRAY: 表示将图像从BGR空间转化成灰度图,最常用
· cv2.COLOR_BGR2HSV: 表示将图像从RGB空间转换到HSV空间
如果想查看参数flag的全部类型,请执行以下程序便可查阅,总共有274种空间转换类型:
import cv2
flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags)
print(len(flags)) # 274
这里简单说一下python 的startswitch()函数的使用方法
描述:
Python startswith() 方法用于检查字符串是否是以指定子字符串开头,如果是则返回 True,否则返回 False。如果参数 beg 和 end 指定值,则在指定范围内检查。
语法:
str.startswith(str, beg=0,end=len(string));
str – 检测的字符串。
strbeg – 可选参数用于设置字符串检测的起始位置。
strend – 可选参数用于设置字符串检测的结束位置。
str = "this is string example....wow!!!"
print(str.startswith( 'this' ))
print(str.startswith( 'is', 2, 4 ))
print(str.startswith( 'this', 2, 4 ))
# 输出结果
True
True
False
回归正题
在之后的图像特征提取和识别学习中,我们经常使用的是将彩色图像转化成灰度图像, 这里解释一下为什么我们总是对灰度图进行处理,增强对以后图像处理操作的理解
图像的颜色主要是由于图像受到外界光照影响随之产生的不同颜色信息,同一个背景物的图像在不同光源照射下产生的不同颜色效果的图像,因此在我们做图像特征提取和识别过程时,我们要的是图像的梯度信息,也就是图像的本质内容,而颜色信息会对我们对梯度信息提取造成一定的干扰,因此我们会在做图像特征提取和识别前将图像转化为灰度图,这样同时也降低了处理的数据量并且增强了处理效果。
二、绘制自定义的数字图像
对于一个长宽分别为w、h的RGB彩色图像来说,它的每个像素值是由(B、G、R)的一个tuple组成,opencv-python中每个像素三个值的顺序是B、G、R,而对于灰度图像来说,每个像素对应的便只是一个整数,如果要把像素缩放到0、1,则灰度图像就是二值图像,0便是黑色,1便是白色。我们通过下面的例子来理解一下
import cv2
# 彩色图像
rgb_img = cv2.imread('fengjing1.jpg')
print(rgb_img.shape) # (1200, 1920, 3)
print(rgb_img[0, 0]) # [209 200 203]
print(rgb_img[0, 0, 0]) # 209
cv2.imshow('rgb_img',rgb_img)
cv2.waitKey()
# 灰度图像
# 这两种方式都可以生成灰度图像,但是gray_img[0,0]的值会有差别
#gray_img = cv2.imread('fengjing2.jpg',0)
gray_img = cv2.cvtColor(rgb_img, cv2.COLOR_BGR2GRAY)
print(gray_img.shape) # (1200,1920)
print(gray_img[0, 0]) # 202/148
print(rgb_img[0, 0, 0]) # 209
cv2.imshow('gray_img',gray_img)
cv2.waitKey()
从上面我们可以看到彩色图像的高度height = 1200, 宽度w=1920且通道数为3, 像素(0, 0)的值是(209 200 203),即R=209, G=200, B=203, 对于灰度图像来说便只是单通道的了
因此(0, 0, 0)便是代表一个黑色像素,(255, 255, 255)便是代表一个白色像素。这么想,B=0, G=0, R=0相当于关闭了颜色通道也就相当于无光照进入,所以图像整个是黑的,而(255, 255, 255)即B=255, G=255, R=255, 相当于打开了B、G、R所有通道光线全部进入,因此便是白色。
明白了上面的原理我们便可以通过创建numpy的ndarray对象来创建任意的彩色图像和灰度图像了,例如:
import cv2
import numpy as np
# 白
white_img = np.ones((512,512,3), np.uint8)
# print(white_img)
white_img = 255*white_img
# 黑
black_img = np.zeros((512,512,3),np.uint8)
#print(black_img)
# 灰
gray_img = np.ones((512,512,3), np.uint8)
gray_img = 125*gray_img
cv2.imshow('white_img', white_img)
cv2.imshow('black_img',black_img)
cv2.imshow('unknown_img',gray_img)
if cv2.waitKey(-1) == ord('A'):
cv2.destroyAllWindows()
白
黑
灰
三、对图像的像素进行简单的操作
1、对图像像素取反
reverse_img = 255 - gray_img
2、对图像像素线性变换
for i in range(gray_img.shape[0]):
for j in range(gray_img.shape[1]):
random_img[i, j] = gray_img[i, j]*1.2
整合后的代码如下:
import cv2
import imutils
import numpy as np
rgb_img = cv2.imread('fengjing1.jpg')
gray_img = cv2.cvtColor(rgb_img, cv2.COLOR_BGR2GRAY)
reverse_img = 255 - gray_img
# print(gray_img)
# print(gray_img.shape[0],gray_img.shape[1]) # 1200 1920
random_img = np.zeros((gray_img.shape[0],gray_img.shape[1]),np.uint8)
for i in range(gray_img.shape[0]):
for j in range(gray_img.shape[1]):
random_img[i,j] = gray_img[i,j]*1.2
cv2.imshow('reverse_img',imutils.resize(reverse_img,800))
cv2.imshow('random_img',imutils.resize(random_img,800))
if cv2.waitKey(-1) == ord('A'):
cv2.destroyAllWindows()
生成的图片如下:
可以看出两幅灰色图的浅色和深色区域互补