- 图像以像素存储,若只有黑白颜色的三色图,为单通道,一个像素对应矩阵中的一个数字,数值为0到255。其中0表示最暗(黑色),255表示最亮(白色)。
对于RGB模式的彩色图片,为三通道图,Red、Green、Blue三原色。一个像素块对应矩阵中的一个向量,分别表示三种颜色的比例。
需要注意的是,由于历史遗留问题,opencv采用BGR模式,而不是RGB
-
图像的读取:cv2.imread(img_path,flag)
img_path: 图片的路径
flag:
cv2.IMREAD_COLOR,读取彩色图片,图片透明性会被忽略,为默认参数,也可以传入1
cv2.IMREAD_GRAYSCALE,按灰度模式读取图像,也可以传入0
cv2.IMREAD_UNCHANGED,读取图像,包括其alpha通道,也可以传入-1 -
图像的写入:cv2.imshow(window_name,img)
window_name: 指定窗口的名字
img:显示的图片对象
可以指定多个窗口名称,显示多个图片 -
图像的保存:cv2.imwrite(img_path_name,img)
img_path_name:保存的文件名
img:文件对象
# 将导入包名另命名
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1 读取图像
img = cv.imread('messi5.jpg',0)
# 2 显示图像
# 2.1 利用opencv展示图像
cv.imshow('image',img)
# 调用cv.waitKey()给图像绘制留下时间,否则窗口会出现无响应情况,并且图像无法显示出来。
k = cv.waitKey(0)
# 3 保存图像
cv.imwrite('messigray.png',img)
用cv2读取彩色图片通道顺序为B、G、R,PIL显示图片是R、G、B顺序,因此读出来图片颜色会改变,需要对图像通道进行调序。
未调整前
import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
img = cv.imread("E:\3.jpg")
# 将图片输出到屏幕
plt.imshow(img)
plt.show()
调整后
import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
img = cv.imread("E:\3.jpg")
# 调整通道顺序
# split()将img分裂为三通道
b,g,r = cv.split(img)
# merge()将三通道合并
img = cv.merge([r,g,b])
# 将图片输出到屏幕
plt.imshow(img)
plt.show()
加入了两行代码,如下
b,g,r = cv.split(img)
img = cv.merge([r,g,b])
三、图像像素获取和编辑
- 获取像素值,更改像素值
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
# 获取(100,100)处的像素值
pixel = img[100,100]
# 将[100,100]处的像素值设置为[0,0,0]
img[100,100]=[0,0,0]
# 将图片输出到屏幕
plt.imshow(img)
plt.show()
更改前,[100,100]处像素值为[254,174,201]
更改后,[100,100]处的像素值为[0,0,0]
- 获取[100,100]处单通道像素值,并更改单通道像素值
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
# 获取(100,100)处的像素值
pixel = img[100,100]
#获取单通道像素值
b = img[100,100,0]
g = img[100,100,1]
r = img[100,100,2]
#更改red通道值
r = img[100,100,2]=0
# 将图片输出到屏幕
plt.imshow(img)
plt.show()
更改后[100,100]处red像素值变为0.
- 使用函数获取单通道像素值:piexl = img.item(x,y,i)
x表示横坐标,y表示纵坐标,i表示从左到右第几个元素。
此处i可选用0,1,2.从左到右分别为b通道,g通道,r通道 - 使用函数设置单通道像素值:img.itemset((x,y,i),num)
x,y,i同上。num自0~255取值,表示rgb颜色数值。
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
# 获取(100,100)处的像素值
pixel = img[100,100]
# 通过img.item() *** 作,可以直接定位到对应的区域。
# 即获取[100,100]处的第1个元素
piexl = img.item(100,100,0)
# itemset((x, y), z) 中的(x,y)代表的就是矩阵中元素位置,‘z’为该元素的值
img.itemset((100,100,0),99)
# 将图片输出到屏幕
plt.imshow(img)
plt.show()
四、图片性质及截取
- List item
输出图片宽,长,通道数
import numpy as np
from PIL import Image
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
print(img.shape)
此处表示图片为宽500(rows),长500(cols),3通道(channels)
- 输出所有像素数
import numpy as np
from PIL import Image
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
print(img.size)
此处表示5005003=750000
- 输出图片数字类型
import numpy as np
from PIL import Image
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
print(img.dtype)
- ROI截取
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
#截取100行到200行,300列到400列
roi = img[100:200,300:400]
#将截取的区域roi移动到该区域
img[50:150,200:300] = roi
# 将图片输出到屏幕
plt.imshow(img)
plt.show()
原图
移动完
截取通道
import numpy as np
from PIL import Image
import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
img = Image.open("E:\3.jpg")
# 导入数组
img = np.array(img)
# 截取整个蓝色通道
b = img[:,:,0]
# 截取三个通道
b,g,r = cv.split(img)
# 按照rgb重新组合
img = cv.merge((r,g,b))
# 将图片输出到屏幕
plt.imshow(img)
plt.show()
五、添加边界
- cv2.copyMakeBorder()
参数:
img:图像对象
top,bottom,left,right: 上下左右边界宽度,单位为像素值
borderType:
cv2.BORDER_CONSTANT, 带颜色的边界,需要传入另外一个颜色值
cv2.BORDER_REFLECT, 边缘元素的镜像反射做为边界
cv2.BORDER_REFLECT_101/cv2.BORDER_DEFAULT
cv2.BORDER_REPLICATE, 边缘元素的复制做为边界
CV2.BORDER_WRAP
value: borderType为cv2.BORDER_CONSTANT时,传入的边界颜色值,如[0,255,0]
- 像素算数运算
cv2.add(img1,img2,mask:None,dtype:-1)
相加的两个图片,应该有相同的大小和通道
img1:图片对象1
img2:图片对象2
mask:None (掩膜,一般用灰度图做掩膜,img1和img2相加后,和掩膜与运算,从而达到掩盖部分区域的目的)
dtype:-1
import numpy as np
from PIL import Image
import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
plt.rc("font", family='Microsoft YaHei')
img1 = Image.open("E:\3.jpg")
img2 = Image.open("E:\4.jpg")
img1 = np.array(img1)
img2 = np.array(img2)
# cv中的加法
img3 = cv.add(img1,img2)
# 直接相加
img4 = img1+img2
# 图像显示
fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,8),dpi=100)
axes[0].imshow(img3[:,:,::-1])
axes[0].set_title("cv中的加法")
axes[1].imshow(img4[:,:,::-1])
axes[1].set_title("直接相加")
plt.show()
-
混合
这其实也是加法,但是不同的是两幅图像的权重不同,这就会给人一种混合或者透明的感觉。img3 = cv.addWeighted(img1,alpha,img2,beta,gamma,dtype)
参数:
img1:图片对象1
alpha:img1的权重
img2:图片对象2
beta:img1的权重
gamma:常量值,图像相加后再加上常量值
dtype:返回图像的数据类型,默认为-1,和img1一样
(img1alpha+img2beta+gamma)
import numpy as np
from PIL import Image
import cv2 as cv
import matplotlib.pyplot as plt
# 读取图像
plt.rc("font", family='Microsoft YaHei')
img1 = Image.open("E:\3.jpg")
img2 = Image.open("E:\4.jpg")
img1 = np.array(img1)
img2 = np.array(img2)
# 2 图像混合
img3 = cv.addWeighted(img1,0.7,img2,0.3,0)
# 3 图像显示
plt.figure(figsize=(8,8))
plt.imshow(img3[:,:,::-1])
plt.show()
-
图像位运算
cv2.btwise_and(): 与运算
参数:
img1:图片对象1
img2:图片对象2
mask:掩膜cv2.bitwise_or():或运算
参数:
img1:图片对象1
img2:图片对象2
mask:掩膜cv2.bitwise_not(): 非运算
img1:图片对象1
mask:掩膜cv2.bitwise_xor():异或运算,相同为1,不同为0(11=0,10=1)
img1:图片对象1
img2:图片对象2
mask:掩膜
如何得到下方的效果:(接下来讲解步骤,详细代码请下滑)
第一步,截取 *** 作区域
img1 = cv.imread(r"E:.jpg")
# 读取前景的行数与列数
rows,cols = img1.shape[0:2]
#读取背景
img2 = cv.imread(r"E:.jpg")
#roi中存放的为背景分割出的与前景同行同列大小的图片,从[0,0]开始
roi = img2[0:rows,0:cols]
第二步,使用cv2.cvtColor()函数将图片转成灰度图
#是RGB到gray进行颜色转换
img1_gray = cv.cvtColor(img1,cv.COLOR_BGR2GRAY)
第三步,使用二值化函数cv2.threshold()将灰度图二值化
图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。
把大于某个临界灰度值的像素灰度设为灰度极大值,把小于这个值的像素灰度设为灰度极小值,从而实现二值化。
如此处阈值为200,即小于200设置为0,大于200设置为255
#threshold()函数形式:retval,dst = cv2.threshold(src,thresh,maxval,type)
#retval:阈值(临界值)、dst:处理后的图像、src:需要处理的图像、thresh:阈值
#maxval:最大像素值、type:阈值分割类型
ret,img1_thres = cv.threshold(img1_gray,200,255,cv.THRESH_BINARY)
第四步,使用“非” *** 作函数cv2.bitwise_not()将上图颠倒黑白:
img1_thres_inv = cv.bitwise_not(img1_thres)
第五步,使用“与” *** 作函数cv2.bitwise_and()对图像掩膜(遮挡)
# 对 *** 作区域掩膜
roi_bg = cv.add(roi,roi,mask=img1_thres_inv)
#对img1掩膜
#用灰度图做掩膜,img1与img1相加后,与淹没与运算可以达到掩盖部分区域的目的。去黑留白
img1_fg =cv.add(img1,img1,mask=img1_thres)
掩膜(mask):以图和掩膜的与运算为例:
原图中的每个像素和掩膜中的每个对应像素进行与运算。比如1 & 1 = 1;1 & 0 = 0;
比如一个3 * 3的图像与3 * 3的掩膜进行运算,得到的结果图像就是:
- List item
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)