OpenCV进行图像处理很方便
图像分类
二值图像(1/0)、灰度图像(纯黑 0-255 纯白)、RGB图像(RGB三原色 R0-255 | G0-255 | B0-255 即一个像素三个值)
opencv 里表示彩色图像顺序是BGR,与一般顺序RGB是不一样的,可以转换成RGB再进行处理
1、图形读入(该颜色表示不是必须的)
retval = cv2.imread(完整文件名[,显示控制参数]) 参数 : cv.IMREAD_UNCHANGED(不改变)、cv.IMREAD_GRAYSCALE(以灰度形式显示)、cv.IMREAD_COLOR(以彩色形式显示)
img=cv2.imread("d:\image.jpg")
2、显示图形
None = cv2.imshow(窗口名,图像名) (注意不要写中文,中文不显示)
cv2.imshow("demo",image)
retval = cv2.waitKey( [,delay]) delay : delay>0 等待delay毫秒,delay<0 等待键盘单击,delay=0,无限等待
cv2.waitKey(0)
cv2.destroyAllWindows() 删除所有窗口,从内存里清空,销毁数据
3、保存图像
retval = cv2.imwrite(文件地址,文件名)
cv2.imwrite('D:\test.jpg',img)
4、读取像素
返回值=图像(位置参数)
灰度图像,返回灰度值
p=img[88,142] (返回第88行,142列那个像素)
print(p)
BGR图像,返回值为B、G、R的值(可以分别打印每个通道的值进行查看,0通道为B,1通道为G,2通道为R)
blue=img[78,125,0]
green=img[78,125,1]
red=img[78,125,2]
print(blue)(打印蓝色通道的值)
不指定通道会打印三个值
p=img[78,125]
print(p)
5、修改像素
像素=新值
灰度图像
img[88,99]=255
BGR图像,分通道赋值
img[88,99,0]=255
直接修改
img[88,99]=[255,255,255]
6、使用numpy进行像素处理(不用opencv)
读取像素
返回值=图像.item(位置参数)
灰度图像
p=img.item(88,142)
print(p)
BGR图像,像素点上有三个值,根据下标不同分别取得三个通道的值
blue=img.item(78,125,0)
修改像素
图像名.itemset(位置,新值)
灰度图像 img.itemset((88,99),255)第88行99列的值改成255
BGR图像 img.itemset((88,99,0),255)修改特定的通道的值
7、获取图像属性
shape可以获取图像的形状,返回包含行数,列数,通道数的元组
灰度图像 返回行数,列数 | 彩色图像 返回行数,列数,通道数
import cv2
img1=cv2.imread('灰度图像/彩色图像')
print(img1.shape)
size可以获取图像的像素数目
灰度图像 行数*列数 | 彩色图像 行数*列数*通道数
import cv2
img1=cv2.imread('图像名')
print(img1.size)
dtype返回的是图像的数据类型
import cv2
img1=cv2.imread('图像名称')
print(img1.dtype)
##uint8
8、图像ROI
ROI(region of interest),感兴趣区域
从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区域。
可以通过各种算子(Operator)和函数来求得感兴趣区域ROI,并进行图像的下一步处理。
import cv2
img1=cv2.imread('图像名称')
face=img1[200:400,200:400] 引用图像200行到400,和200列到400列部分区域,取名face
img1[200:400,600:800]=face 可以使用face,比如将另一部分区域等于face
9、通道的拆分
import cv2
img1=cv2.imread('图像名称')
b,g,r=cv2.split(img1)
cv2.imshow("blue",b)
cv2.imshow("green",g)
cv2.imshow("red",r)
只拆分一个通道,下标0,1,2分别表示B,G,R通道
b=cv2.split(a)[0]
10、通道的合并
m=cv2.merge([b,g,r]) 注意b,g,r的顺序
红色通道与都是0的另外两个通道合并,得到的图像是红色的
import cv2
import numpy as np
a = cv2.imread("imagelena.png")
rows.cols.chn=a.shape
b = np.zeros((rows,cols), dtype=a.dtype)
g = np.zeros((rows,cols), dtype=a.dtype)
r = cv2.split(a)[2]
m = cv2.merge([b,g,r])
11、图像加法运算
参与运算的图像大小、类型必须一致
numpy加法,不太自然,多的叠加的部分是黑的
取模加法,运算方式:结果 = 图像1 + 图像2 ---> 像素值<=255 图像1+图像2 ---> 图像值>255 结果对255取模
100+58=158 255+58= (255+58)%255 = 58
二进制 十进制
0000 0000 0
0000 0001 1
...... ......
1111 1110 254
1111 1111 255
opencv加法,更自然,多的叠加的部分是白的
饱和运算,运算方式:结果 = cv2.add(图像1,图像2) ---> 像素值<=255 图像1+图像2 ---> 图像值>255 取值255
100+58=158 255+58= 255
12、图像融合
图像融合:结果图像=图像1*系数1+图像2*系数2+亮度调节量
img=img1*0.3+img2*0.7+18
图像相加相当于两个图像权重系数是一样的,都是1,亮度调节值是0
函数addWeighted
dst = cv.addWeighted(src1,alpha,src2,beta,gamma)
dst = src1*alpha + src2*beta + gamma; 运算公式 参数gamma(亮度调节值)不能省略
13、图像类型转换
OpenCV提供了200多种不同类型之间的转换
彩色转灰度 b = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY) 第一个参数a是原图像,第二个参数是转换的具体类型
BGR转RGB b = cv2.cvtColor(a,cv2.COLOR_BGR2RGB)
灰度转BGR b = cv2.cvtColor(a,cv2.COLOR_GRAY2BGR)
14、图像缩放
语法格式
dst = cv2.resize(src ,dsize[ ,dst[ ,fx[ ,fy[ ,interpolation]]]]) src 原始图像 dsize 缩放大小 fx, fy 缩放大小 (一般没有dsize时使用,fx水平方向上的缩放,如果fx>1就是放大,fx<1缩小,=1表示不变)
b = cv2.resize(a,(200,122)) 200,122分别表示图像的列 和 行
b = cv2.resize(a,None,fx=0.5,fy=0.7)
b = cv2.resize(a, (round(cols*0.5), round(rows*1.2))) 列乘以比例后不一定是整数,但是我们说多少列,列肯定是整数,所以对进行计算的列四舍五入round,让其是整数的列
15、图像翻转
dst = cv2.flip(src, flipCode) src原图像 ,flipCode以哪种模式进行翻转
三种翻转方式, 其一左翻右 ,即以y轴为对称轴进行左右翻转 flipCode>0 ,另一种以x为对称轴进行上下翻转 flipCode=0,还有一种,翻转两次,先以x轴为对称轴上下翻转,再以y轴为对称轴左右翻转 flipCode<0
dst = cv2.flip( src , 1)
16、阈值分割
二进制阈值化 Threshold Binary
先要选定一个特定的阈值量,比如:127
新的阈值产生规则为:大于等于127的像素点的灰度值设定为最大值(如8位灰度值最大为255)
灰度值小于127的像素点的灰度值设定为0,即最小值
dst ( x, y ) = { maxVal if src( x, y ) > thresh
0 otherwise
反二进制阈值化 Threshold Binary,Inverted
与二进制阈值化相反,得到的是其反色的图
大于阈值的设定为0,小于该阈值的设定为255
dst ( x, y ) = { 0 if src( x, y ) > thresh
maxVal otherwise
截断阈值化 Truncate
把比阈值大的像素都处理成阈值,小于该阈值的保持不变。不存在比阈值大的像素值了
dst ( x, y ) = { threshold if src( x, y ) > thresh
src( x, y ) otherwise
反 阈值化为0 Threshold to Zero, Inverted
大于等于阈值的像素处理为0,小于该阈值的像素点值保持不变
dst ( x, y ) = { 0 if src( x, y ) > thresh
src( x, y ) otherwise
阈值化为0 Threshold to Zero
某像素点的值比阈值大,保持不变,如果比阈值小或等于阈值,则处理为0
dst ( x, y ) = { src( x, y ) if src( x, y ) > thresh
0 otherwise
17、函数 threshold 及实现
retval, dst = cv2.threshold( src ,thresh ,maxval ,type)
retval, 阈值(与threshold是一致的) dst, 处理结果图像 src 源图像 threshold 阈值(一般是128) maxval 最大值(1也可以255) type 类型
二进制阈值化 cv2.THRESH_BINARY 把亮的处理为白色,暗的处理为黑色
r, b = cv2.threshold(a ,127 ,255 ,cv2.THRESH_BINARY)
反二进制阈值化 cv2.THRESH_BINARY_INV 把亮的处理为黑色,暗的处理为白色,与二进制阈值化是反色的
截断阈值化 cv2.THRESH_TRUNC 把比较亮的都处理为阈值,整体暗了
反阈值化为0 cv2.THRESH_TOZERO_INV 把比较亮的处理为0,暗一些的像素点不变
阈值化为0 cv2.THRESH_TOZERO 把比较暗的像素点处理为0,比较亮的不变
18、图像平滑,均值滤波
任意一点的像素值,都是周围N*N个像素值的均值
5行5列中心点的像素新值=该5行5列像素值之和除25
核 进行均值滤波时要指定的参数,
针对原始图像内的像素点,逐个采用核进行处理,得到结果图像
上述5行5列的核是 5行5列个1/25
1 1 1 1 1
1 1 1 1 1 1
K = — [ 1 1 1 1 1 ]
25 1 1 1 1 1
1 1 1 1 1
函数 blur
处理结果 = cv2.blur(原始图像,核大小)
核大小:以(宽度,高度)形式表示的元组,上面核大小:(5, 5)
核大小:(3, 3) 表示3行3列,对应如下
1 1 1 1
K = — [ 1 1 1 ]
9 1 1 1
r=cv2.blur(o, (5, 5) )
能平滑椒盐攻击,每个点都是周围值的均值
19、图像平滑,方框滤波
函数boxFilter
处理结果=cv2.boxFilter(原始图像,目标图像深度,核大小,normalize属性)
目标图像深度:Int类型的目标图像深度。通常使用“-1”表示与原始图像一致。
normalize属性(归一化属性):是否对目标图像进行归一化处理。
1 1 ... 1
K = — [ ... ... ... ]
a 1 ... 1
a = { 1/(width * height) normalize = true 与均值滤波相同
1 normalize = false 实际上是求和,很容易发生溢出
r = cv2.boxFilter( o, -1, (5, 5), normalize=1) 等于1表示要进行归一化处理,与均值滤波相同
r = cv2.boxFilter( o, -1, (5, 5)) 省略掉相当于true,进行归一化处理
r = cv2.boxFilter( o, -1, (5, 5), normalize=0) 相当于false,表示不进行归一化处理,求和,目标图像变成白色的
9
20、图像平滑,高斯滤波
让临近的像素具有更高的重要度。对周围像素计算加权平均值,较近的像素具有较大的权重值。与均值滤波不同之处是,离中心点越近权重越大,离中心点越远,权重越小。
函数 GaussianBlur
dst = cv2.GaussianBlur( src, ksize, sigmaX)
src,原始图像,要处理的源图像 ; ksize,核大小,必须是奇数(N,N) ; sigmaX,X方向方差,控制权重
sigmaX=0就可以了,它会根据核的大小自己去算出方差
sigmaX=0时:sigma = 0.3*( (ksize-1)*0.5 - 1 ) + 0.8
y的方差与x的方差保持一致
r=cv2.GaussianBlur(o,(5,5),0)
安装opencv(未验证)
sudo apt-get install libcv-dev
sudo apt-get install libopencv-dev
---网易云课堂