十四天入门opencv的TASK2,本次任务给了两天时间,主要学习图像色彩空间转换、图像对象的创建和赋值、图像像素的读写操作、图像运算操作。
人眼可见光波长范围大概在380nm到760nm左右,一般人的眼睛可以感知的电磁波的波长在780nm到400nm之间,但还有一些人能够感知到波长大约在880nm到380nm之间的电磁波。
(1)HSV
HSV是根据颜色的直观特性由 A. R. Smith 在 1978 年创建的一种颜色空间, 也称六角锥体模型。这个模型中颜色的参数分别是色调(H)、饱和度(S)和明度(V)。HSV色彩空间,对计算机友好,区分各种色彩。
色调H用角度度量,正常取值范围为0°到360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。但是在opencv中取值范围为0°到180°。
饱和度S表示颜色接近光谱色的程度。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。opencv中取值范围为0到255。
明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。opencv中取值范围为0到255。
(2)RGB
RGB色彩模式是是通过对红®、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色。RGB色彩空间,设备独立,是计算机显示器的标准支持色彩系统,取值范围0~255。
(3)YCrCb
YCrCb即YUV,主要用于优化彩色视频信号的传输,其中Y表示明亮度,也就是灰阶值;而U和V表示的则是色度,作用是描述影像色彩及饱和度,用于指定像素的颜色。CrCb, Y分量表示信息,CrCb可以被压缩。
亮度是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。
色度则定义了颜色的两个方面─色调与饱和度,分别用Cr和Cb来表示;其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而Cb反映的是RGB输入信号蓝色部分与RGB信号亮度值之间的差异。Y
从一个色彩空间转换到另外一个色彩空间,信息传递可能存在损失,有的过程可逆而有的不可逆。比如,从RGB转到灰度图就会存在信息损失,是一个不可逆的过程;而从RGB转到BGR或者HSV则不存在信息损失,是可逆的。
实验代码:
import cv2 as cv
import numpy as np
image = cv.imread("./apple.jpg")
cv.imshow("apple",image)
hsv = cv.cvtColor(image,cv.COLOR_BGR2HSV)
ycrb = cv.cvtColor(image,cv.COLOR_BGR2YCrCb)
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("hsv",hsv)
cv.imshow("ycrb",ycrb)
cv.imshow("gray",gray)
cv.waitKey(0)
cv.destroyAllWindows()
实验结果:
图像的基本属性由像素、分辨率、大小、颜色、位深、色调、饱和度、亮度、色彩通道、图像的层次组成。opencv-python中一切图像数据皆numpy array,因此array 数组的属性和操作方法也都适用于 OpenCV 的图像对象。比如通过shape属性获取一个图像像素的行列数(高、宽)、通道数;通过numpy.copy进行图像数组的深拷贝。opencv-python支持的数据类型有np.uint8、np.float32、np.int32、np.int64。
创建图像最常用函数np.zeros()(创建一个黑色背景图像)、
np.zeros_like()(创建一个与输入图像大小一致的黑色背景图像)、np.ones()(创建一个全部像素值是1的图像)等。图像赋值就是给numpy array数组赋值,一个图像数组三个维度分别代表高、宽、通道数,如m = np.zeros((3, 3, 3), dtype=uint8)表示擦创建一个高x宽为3x3、通道数为3的图像。
实验代码:
import cv2 as cv
import numpy as np
m1 = np.array([[2,3],[4,5]],dtype=np.uint8)
print(m1)
black = np.zeros((512,512,3),dtype=np.uint8)
black[:,0:256]=(255,0,0)
black[:,256:512]=(0,0,255)
cv.imshow("black",black)
cv.waitKey(0)
cv.destroyAllWindows()
像素指的是构成图片的小方格,每个方格都有一个清晰的位置和指定的颜色,这个小方格就是像素。分辨率越高,所包含的像素就越多,图像就越清晰,印刷的质量也就越好,屏幕呈现的色彩也越好,同时它也会增加文件占用的存储空间。像素、分辨率、尺寸三者关系是:像素=分辨率×尺寸,即分辨率越高,像素就越高;分辨率越低,相对地,像素也会减少,两者之间是成正比关系。图像分辨率单位为ppi:,表示每英寸的像素数目。
opencv中图像原点在左上角,opencv的图像存储是和数组一致的。彩色图像与灰度图像的区别是每个点有三个通道值,灰色图像只有一个。
像素遍历本质就是numpy数组访问。
实验代码:
import cv2 as cv
import numpy as np
image = cv.imread("./apple.jpg")
cv.imshow("aplle", image)
h, w, c = image.shape
for row in range(h):
for col in range(w):
b, g, r = image[row, col]
image[row, col] = (255-b, 255-g, 255-r)
cv.imshow("visited",image)
cv.waitKey(0)
cv.destroyAllWindows()
实验结果:
opencv提供了对图像进行加减乘除等算数操作的函数,如cv.add(src1, src2[, dst[, mask[, dtype]]]) ->dst
cv.subtract(src1,src2[,dst[,mask[,dtype]]])->dst
cv.multiply(src1,src2[,dst[,scale[,dtype]]])->dst
cv.divide(src1, src2[, dst[, scale[, dtype]]])->dst
src1 & src2表示图像,进行算术操作的图像大小应一致,这里的加减法越界后置0或255。add中的mask参数使得最终结果只有在mask中值为1的地方计算有效,其余mask中值为0的部分结果为0。
实验代码:
import cv2 as cv
import numpy as np
image1 = cv.imread("./apple.jpg")
h, w, c = image1.shape
image2 = np.zeros_like(image1)
image2[:, :] = (22, 33, 50)
mask = np.zeros((h, w), dtype=np.uint8)
mask[200:300, 200:300] = 1
cv.imshow("image1", image1)
cv.imshow("image2", image2)
added = cv.add(image1, image2, mask=mask)
cv.imshow("added", added)
cv.waitKey(0)
cv.destroyAllWindows()