目录
- 图像数据读取
- 1. 读取图像 imread()
- 2. 显示图像 imshow()
- 3. 灰度图像
- 4. 保存图片 imwrite()
- 5. 截取部分图像
- 6. 颜色通道提取
- 7. 边界填充
- 8. 数值计算
- 9. 图像融合
图像数据读取
一幅完整的图像,是由红、绿、蓝三个通道组成的。红色、绿色、蓝色三个通道的缩览图都是以灰度显示的。用不同的灰度色阶来表示" 红,绿,蓝"在图像中的比重。通道中的纯白,代表了该色光在此处为最高亮度,亮度级别是 255。图像分为彩色图像和灰度图像,灰度图像是每个像素只有一个采样颜色的图像。
在 opencv 中,
彩色图像用 cv2.IMREAD_COLOR 表示;
灰度图像用 cv2.IMREAD_GRAYSCALE
以一张梦幻背景图片进行举例:
1. 读取图像 imread()
import cv2 #opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np
img=cv2.imread('szj.jpg') #注意路径及文件命名为英文,否则会报错
2. 显示图像 imshow()
#显示图像
cv2.startWindowThread()
cv2.imshow('image',img)
cv2.waitKey(0) #0表示任意键终止
cv2.destroyAllWindows()
# 也可定义一个函数cv_show( ),显示图像调用该函数即可,不需要每次显示图像都要写四行代码
def cv_show(name,img):
cv2.startWindowThread()
cv2.imshow(name,img)
cv2.waitKey(0) #0表示任意键终止
cv2.destroyAllWindows()
运行代码后图片自动显示出来,按任意键终止。
3. 灰度图像
shape 函数:返回的是图像的行数,列数,色彩通道数。img.shape,h高度 w宽度 c通道
import cv2 #opencv读取的格式是BGR
import matplotlib.pyplot as plt
import numpy as np
img=cv2.imread('sky.jpg',cv2.IMREAD_GRAYSCALE)#灰度图像
img.shape # 只有 h w ,即一个颜色通道
#显示图像 调函数cv_show( )
cv_show('tu',img)
运行得到图像:
4. 保存图片 imwrite()
cv2.imwrite('skygrey.jpg',img)
img.size # size( )获取图像的像素数目,返回行数 * 列数 * 通道数
img.dtype # 数据类型
5. 截取部分图像
img = cv2.imread("sky.jpg")
sky = img[0:200,0:200] #截取范围:高200,宽200
cv_show('tu',sky)
plt.imshow(sky)
效果如下:
6. 颜色通道提取
b,g,r = cv2.split(img) #cv2.split分割通道
r.shape #输出(607, 540)
#b.shape,g.shape结果均为(607, 540)
img = cv2.merge((b,g,r)) #cv2.split合并通道
img.shape #输出(607, 540, 3)
#只保留R
img_c = img.copy() #复制图片
#B G R -- 相当于数组arr下标0 1 2
img_c[:,:,0] = 0 #设置B通道为0,arr[0]=0
img_c[:,:,1] = 0 #设置G通道为0,arr[1]=0
cv_show("R",img_c) #参数:图片名称、图片
plt.imshow(img_c)
同理只保留G和B。
7. 边界填充
BORDER_REPLICATE:复制原图中最临近的行或者列 aaaaaa|abcdefgh|hhhhhhh
BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制 fedcba|abcdefgh|hgfedcb
BORDER_REFLECT_101:反射法,以最边缘像素为轴 gfedcb|abcdefgh|gfedcba
BORDER_WRAP:外包装法 cdefgh|abcdefgh|abcdefg
BORDER_CONSTANT:使用常数填充边界 iiiiii|abcdefgh|iiiiiii
top_size,bottom_size,left_size,right_size = (50,50,50,50) #上下左右
#参数:图像、上边界、下边界、左边界、右边界、边界填充方法
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0) #此处多一个参数,value=0表示黑色
#绘制图片,共六张(2行,每行3张)
plt.subplot(2,3,1), plt.imshow(img, 'gray'), plt.title('ORIGINAL')
plt.subplot(2,3,2), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
plt.subplot(2,3,3), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
plt.subplot(2,3,4), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')
plt.subplot(2,3,5), plt.imshow(wrap, 'gray'), plt.title('WRAP')
plt.subplot(2,3,6), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
plt.show()
8. 数值计算
img_sky = cv2.imread("sky.jpg")
img_szj = cv2.imread("szj.jpg")
img_sky[:5,:,0] #打印前5行
img_sky2 = img_sky + 10 #加10表示每个像素点加10
img_sky2[:5,:,0]
# 相当于取余%256 (范围是0~255)
(img_sky+img_sky2)[:5,:,0] #拿左上角元素举例:(175+185)%256 = 104
cv2.add(img_sky,img_sky2)[:5,:,0] #cv2.add将两个图片进行加和,大于255的用255表示
9. 图像融合
img_sky.shape #输出(290, 400, 3)
img_szj.shape #输出(414, 500, 3)
#cv2.resize图像缩放
img_szj = cv2.resize(img_szj,(400,290))
img_szj.shape #再输出时变为(290, 400, 3)
注意:使用 cv2.resize 时,参数输入是:宽×高×通道 ,与以往操作不同
#cv2.addWeighted()图像混合/叠加
#第一幅图像的权重是0.4,第二幅图像的权重是0.6,gamma=0
#公式:dst = src1 * 权重 + src2 * 权重 + 偏移量gamma
res = cv2.addWeighted(img_sky,0.4,img_szj,0.6,0)
plt.imshow(res)
resize 还可以改变图片倍数
# 尺寸变换resize
res = cv2.resize(img, (0, 0), fx=2, fy=3) # x放大2倍, y放大3倍
plt.imshow(res)