目录
一.图像
1.读取图像
2.显示图像
3.保存图像
二.图像处理基础
1.图像处理入门基础
2.像素处理
3.使用numpy进行像素处理
4.获取形状属性(shape)
5.图像ROI
6.通道的拆分与合并
三.图像运算
1.图像的加法运算
2.图像融合
四.图像类型转换
1.图像类型转换
五.几何变换
1.图像缩放
2.图像翻转
六.阈值分割
1.阈值分割
七.图像平滑处理
1.均值滤波
2.高斯滤波
3.中值滤波
八.形态学操作
1.图像腐蚀
2.膨胀
3.开运算操作
4.闭运算
5.图像梯度
6.礼帽操作(图像顶帽)
7.黑帽图像处理
九.图像梯度
1.sobel使用
十,Canny边缘检测
1.canny边缘检测原理
2.canny边缘检测使用
十,图像金字塔
1.理论基础
2.图像金字塔向下取样函数及应用
3向上取样.
4.拉普拉斯金字塔
14.直方图
1.使用opencv统计直方图
2.使用掩模的直方图
tu_xiang = cv2.imread(文件名,[显示控制参数])
import cv2#导入opencv2
tupian = cv2.imread("E:\jre\eee.jpg")#读取图片
xianshi_tupian = cv2.imshow(窗口名,图像名)
例子:
import cv2
tupian = cv2.imread("E:\jre\eee.jpg")#读取图像
cv2.imshow("窗口名",tupian)#显示图像
1.因为上面的程序会闪退,所以需要让图像在屏幕上停留一会
delay>0 等待delay毫秒
delay<0 等待键盘敲击
delay = 0 无限等待
范例:
cv2.waitKey(0)
""""
读取一张图片。并显示一秒
延时1000毫秒(1秒)
参数delay(1000)
"""
import cv2
tupian = cv2.imread("E:\jre\eee.jpg")
cv2.imshow("窗口名",tupian)
cv2.waitKey(1000)
""""
读取一张图片。并显示一秒
delay为0,无限延时
"""
import cv2
tupian = cv2.imread("E:\jre\eee.jpg")
cv2.imshow("窗口名",tupian)
cv2.waitKey(0)
""""
读取一张图片。并显示一秒
delay<0等待敲击键盘
"""
import cv2
tupian = cv2.imread("E:\jre\eee.jpg")
cv2.imshow("窗口名",tupian)
cv2.waitKey(-1)
2.cv2.destroyAllWindows()
功能:
删除所有窗口(关掉从内存里删掉所有窗口)
""""
读取一张图片。并显示一秒
delay=1000等待敲击键盘
"""
import cv2
tupian = cv2.imread("E:\jre\eee.jpg")
cv2.imshow("窗口名",tupian)
cv2.waitKey(1000)
cv2.destroyAllWindows() #关闭从内存中删除所有窗口
bao_cun = cv2.imwrite(文件地址,文件名)
文件地址要存到什么地方,文件名:要保存哪个文件
""""
保存图片
"""
import cv2
img = cv2.imread("E:\jre\eee.jpg")
cv2.imwrite("E:\jre\jrf.png",img)
cv2.imshow("窗口名",img)
cv2.waitKey(1000)
cv2.destroyAllWindows() #关闭从内存中删除所有窗口
图像是由像素组成的
二值图像:非黑即白(0和1)一个像素点一个值
灰度图像:黑 白 灰 灰度(256个不同值)(0全黑,255全白)一个像素点一个值
RGB图像: 彩色图像(不同比例三原色混合成各种各样的颜色 ) opencv里面是BGR 一个像素点三个值
因为彩色图像3个值处理起来比较麻烦,灰度图像一个值处理起来比较方便
RGB装灰度图像
1.读取像素
返回值 = 图像(位置参数)
p =img[23,199]#这个时候访问的是23行142列的像素
print(p)#打印像素值
因为BGR是三通道BGR
第0个通道:blue
第一个通道:green
第三个通道:red
所以要增加一个通道数
blue = img[78,125,0]
print(blue)
green = img[78,125,1]
print(green)
red = img[78,125,2]
print(red)
例如:打印图片像素值
""""
保存图片
"""
import cv2
p = [0,0,0]
img = cv2.imread("E:\jre\eee.jpg")
cv2.imshow("窗口名",img)
p[0] = img[23,56,0]
p[1] = img[23,56,1]
p[2] = img[23,56,2]
print(p[0])
print(p[1])
print(p[2])
cv2.waitKey(1000)
cv2.destroyAllWindows() #关闭从内存中删除所有窗口
如果没有指定是哪个通道:
p = img[78,125]
print(p)
这个时候回出现三个值分别是BGR
2.修改像素
img[88,99] = 255#第88行99列像素值等于255
"""
改变一个灰度图像像素
"""
import cv2 as cv
p=cv.imread("E:\jre\eee.jpg")
print(p[25,25])
p[25,25] = 255
print(p[25,25])
img = [88,99,0] = 255#第88行99列,第零个通道
img = [88,99,1] = 255
img = [88,99,2] = 255
也可以直接赋值
img[88,99] = [255,255,255]
实例:
"""
改变一个RGB图像像素
"""
import cv2 as cv
p=cv.imread("E:\jre\eee.jpg")
print(p[25,25])
p[25,25] = [255,254,253]
print(p[25,25])
修改一定范围内图片并显示
"""
改变一个RGB图像像素
"""
import cv2 as cv
p=cv.imread("E:\\OPCV_yuanma\\image\\test.png")
cv.imshow("jieguo",p)
p[0:100,0:100,0:100] = [255,255,255]#将一定范围设置修改像素值
cv.imshow("jieguo1",p)
cv.waitKey(0)
cv.destroyAllWindows()
灰度图像:
p = img.item(88,142)
print(p)
BGR图像:
blue = img.item(78,87,0)#对每个通道进行打印
import cv2
import numpy as np
i=cv2.imread("E:\OPCV_yuanma\image\lena512.bmp",cv2.IMREAD_UNCHANGED)#不改变类型,如果不添加参数下面必须添加通道数
print(i.item(88,55))
#print(i.item(100,100))#但因第100行100列
1.shape可以获取图像的形状,返回包含行数,列数,通道数的元祖
例子:
灰度图像:
import cv2
img = cv2.imread("灰度图像")
print(img.shape)
输出##(512,512)
彩色图像:
import cv2
img = cv2.image("彩色图像")
print("img.shape)
输出##(512,512,3)#512行,512列3通道
2.像素数目
size可以获取图像像素数目
灰度 返回:行数*列数
彩色 返回:行数*列数*通道数
例子:
import cv2
img = cv2.imread(“图像名”)
print(img.size)
3.图像类型(dtype)
返回当前图像数据类型
例子:
import cv2
img = imread("图像名称")
print(img.dtype)
##uint8
例子:
import cv2 as cv
img1 = cv.imread("E:\\OPCV_yuanma\\image\\airfield.bmp",cv.IMREAD_UNCHANGED)
img2 = cv.imread("E:\\OPCV_yuanma\\image\\A.png")
print(img1.shape)
print(img2.shape)
print(img1.size)
print(img2.size)
比如当前黄色区域是一个图像,
可以通过下标的方式吧这个区域
import cv2
img = imread("图像名称")
face = img[200:400,200:400]
下面是赋值Roi区域的例程
"""复制roi区域"""
import cv2
import numpy as np
a = cv2.imread("E:\OPCV_yuanma\image\logo.png")#读取一张图片
b = np.ones((101,101,3))#创建了一个图像,这个图像三个通道,每一行都是101行,101列
b = a[220:400,250:350]
a[0:180,0:100]=b
cv2.imshow("original",a)
cv2.waitKey()
cv2.destroyAllWindows()
下面是我自己总结的简单的方法
"""复制roi区域"""
import cv2
import numpy as np
a = cv2.imread("E:\OPCV_yuanma\image\logo.png")#读取一张图片
a[0:180,0:100]=a[220:400,250:350]
cv2.imshow("original",a)
cv2.waitKey()
cv2.destroyAllWindows()
b,g,r = cv2.split(a)
b = cv2.split(a)[0]
m = cv2.message([b,g,r])
"""利用split函数快速拆分BGR通道"""
import cv2
import numpy as np
a = cv2.imread("E:\OPCV_yuanma\image\logo.png")
b,g,r = cv2.split(a)
cv2.imshow("B",b)
cv2.imshow("G",g)
cv2.imshow("R",r)
cv2.waitKey()
cv2.destroyAllWindows()
如果每次只想得到一个结果,就在split(a)[1]
"""利用split函数快速拆分BGR通道"""
import cv2
import numpy as np
a = cv2.imread("E:\OPCV_yuanma\image\logo.png")
g= cv2.split(a)[1]
cv2.imshow("G",g)
cv2.waitKey()
cv2.destroyAllWindows()
与拆分类似
m = cv2.merge([b,g,r])
"""利用split函数快速拆分并且合并BGR通道"""
import cv2
import numpy as np
a = cv2.imread("E:\OPCV_yuanma\image\logo.png")
b,g,r = cv2.split(a)
cv2.imshow("B",b)
cv2.imshow("G",g)
cv2.imshow("R",r)
m = cv2.merge([b,g,r])#合并三通道
cv2.imshow("ref",m)
cv2.waitKey()
cv2.destroyAllWindows()
注意顺序为BGR
参与运算图像大小和类型必须保持一致
取模运算
饱和运算
接下来是实例:
"""
两个图像相加程序
"""
import cv2
import numpy as np
a = cv2.imread("E:\OPCV_yuanma\image\lena256.bmp")
b = a
add1 = a+b#利用numpy运算
add2 = cv2.add(a,b)#利用opencv进行饱和运算
cv2.imshow("原始图像",a)
cv2.imshow("add1",add1)#
cv2.imshow("add2",add2)
cv2.waitKey()#等待用户输入
cv2.destroyAllWindows()#释放所有窗口
图像融合虽然也是图像相加,进行图像融合的时候往往融合一些算法进去
参数1:src1,第一个原数组.
参数2:alpha,第一个数组元素权重
参数3:src2第二个原数组
参数4:beta,第二个数组元素权重
例如:
import cv2
a = cv2.imread("E:\\OPCV_yuanma\\image\\add\\boat.bmp")
b = cv2.imread("E:\\OPCV_yuanma\\image\\add\\lena.bmp")
c = cv2.addWeighted(a,0.3,b,0.6,0)#系数是调节亮度系数,最后系数是亮度调节值
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.imshow("c",c)
cv2.waitKey()
cv2.destroyAllWindows()
例如
b = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)#参数依次是原图像,转换的图像类型
实例:
彩色图像转灰度图像
b = cv2.cvtColor(a,cv2.COLOR_BGR2RGB)
b = cv2.cvtColor(a,cv2.COLOR_GRAY2BGR)
转换实例:
""
import cv2#导入opencv库
#适用于灰度图像
"""
a= cv2.imread("E:\OPCV_yuanma\image\lena256.bmp",cv2.IMREAD_UNCHANGED)#第二个参数是读入他原始的样子,
b = cv2.cvtColor(a,cv2.COLOR_GRAY2BGR)#将灰度图像转换成彩色图像,本程序不适用
"""
#适用于彩色图像,不用时请屏蔽
a= cv2.imread("E:\OPCV_yuanma\image\lenacolor.png")
b = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)#彩色图像装换为灰度图像
b = cv2.cvtColor(a,cv2.COLOR_BGR2RGB)#BGR转RGB
cv2.imshow("原始图像",a)#显示读取的图像
cv2.imshow("转换图像",b)#转换后的灰度图像
cv2.waitKey()#等待用户输入
cv2.destroyAllWindows()#释放所有窗口
因为上图灰度图像视觉上没有区别:。所以打印出来,看一下区别:
""
import cv2#导入opencv库
#适用于灰度图像
a= cv2.imread("E:\OPCV_yuanma\image\lena256.bmp",cv2.IMREAD_UNCHANGED)#第二个参数是读入他原始的样子,
b = cv2.cvtColor(a,cv2.COLOR_GRAY2BGR)#将灰度图像转换成彩色图像,本程序不适用
"""
#适用于彩色图像,不用时请屏蔽
a= cv2.imread("E:\OPCV_yuanma\image\lenacolor.png")
b = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)#彩色图像装换为灰度图像
b = cv2.cvtColor(a,cv2.COLOR_BGR2RGB)#BGR转RGB
"""
print(a.shape)
print(b.shape)
结果为:
E:\untitled5\venv\Scripts\python.exe E:/untitled5/first.py
(256, 256)
(256, 256, 3)
我们看一下三个通道的图片是什么样子
""
import cv2#导入opencv库
a= cv2.imread("E:\OPCV_yuanma\image\lena256.bmp",cv2.IMREAD_UNCHANGED)#第二个参数是读入他原始的样子,
b = cv2.cvtColor(a,cv2.COLOR_GRAY2BGR)#将灰度图像转换成彩色图像,本程序不适用
print(a.shape)
print(b.shape)
bb,bg,br = cv2.split(b)
cv2.imshow("bb",bb)#显示B通道
cv2.imshow("bg",bg)
cv2.imshow("br",br)
cv2.waitKey()
cv2.destroyAllWindows()
得到三个窗口的图像是一样的
dst = cv2.resize(src,desize[, dst,[,fx[,fy[,interpolation]]]])
这么多参数里有两个参数是必备的,其他参数是可有可无
1.dst = cv2.resize(src,dsize)
src原始图像
desize:缩放大小
l例如:
b = cv2.resize(a,(122,122))行列
import cv2
a = cv2.imread("E:\OPCV_yuanma\chapter6\image\lenacolor.png")
#定义一个元祖,方便下面引用
rows,cols,chn = a.shape
size = (round(cols*0.5),round(rows*1.5))#round是取整
b = cv2.resize(a,size)#对a调整大小为200列100行
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
2.多了两个参数通常是在第二个参数不使用的时候
det = cv2.resize(src,desize,fx,fy)
fx,fy缩放大小,大于1表示放大
小于1表示缩小
等于1表示不变
例如:
b = cv2.resize(a,None,fx = 0.5,fy = 0.7),表示水平方向上,缩小0.5倍,fy缩小为原来的0.7倍
desize和fx,fy只需要设置一个就行了
import cv2
a = cv2.imread("E:\OPCV_yuanma\chapter6\image\lenacolor.png")
#定义一个元祖,方便下面引用
rows,cols,chn = a.shape
b = cv2.resize(a,None,fx=0.5,fy=1.3)#横向0.5倍,纵向103倍
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
dst = cv2.flip(src,flipCode)#src原始图像,模式参数
范例:
flipCode = 0:现实的是以x轴为对称轴,上下翻转
flipCode > 0:以y轴为对称轴进行 左右翻转
flipCode<0 :在x轴方向和外轴方向同时翻转
dst = cv2.flip(src,1)
实现翻转
import cv2
a = cv2.imread("E:\OPCV_yuanma\chapter6\image\lenacolor.png")
b = cv2.flip(a,0)#0表示上下翻转
#b = cv2.flip(a,1)#0表示上下翻转
#b = cv2.flip(a,2)#0表示上下翻转
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
retval,dst = cv2.threshold(src,thresh,maxval,type)
二进制阈值化:大于阈值的值处理为255,小于等于 阈值的值处理为0
关键字:cv2.THREST_BINARY
"""
二进制阈值化
用到关键字
cv2.THRESH_BINARY
"""
import cv2
a = cv2.imread("E:\OPCV_yuanma\chapter6\image\lenacolor.png")
r,b = cv2.threshold(a,127,255,cv2.THRESH_BINARY)#a表示原始图像,b表示处理后的图像,r表示阈值127
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
小于阈值或等于阈值的像素处理为最大值,大于阈值的像素处理为0
关键字:cv2.THRESH_BINARY_INV
大于阈值的像素都处理为阈值,小于阈值的像素值不变
关键字:cv2.THREST_TRUNC
例如:
"""
二进制阈值化
用到关键字
cv2.THRESH_BINARY
"""
import cv2
a = cv2.imread("E:\OPCV_yuanma\chapter6\image\lenacolor.png")
r,b = cv2.threshold(a,127,255,cv2.THRESH_TRUNC)#a表示原始图像,b表示处理后的图像,r表示阈值127
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
把大于阈值的像素处理为0,小于等于等于阈值的像素点不变
关键字:cv2.THRESH_TOZERO_INV
把小于阈值的像素点处理为0.大于阈值的像素点不变
关键字:cv2.THRESH_TOZERO_INV
处理结果 = cv2.blur(原始图像,核大小)
例如:
r = cv2.blur(o,(5,5)#核大小5*5
核大小:以(宽度,高度)表示的一个元祖
import cv2
a = cv2.imread("E:\OPCV_yuanma\chapter8\image\lenaNoise.png")
b = cv2.blur(a,(5,5))#均值滤波
cv2.imshow("a",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
函数boxFilter
处理结果 = cv2.boxFilter(原始图像,目标图像深度,核大小,normalize属性)
目标图像深度:int类型的目标,图像深度。通常使用“-1”表示与原始图像一致
normalize属性:是否对目标图像进行归一化处理
分两种情况:
1.求均值:与均值滤波相同发
import cv2
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\lenaNoise.png")
r = cv2.boxFilter(o,-1,(5,5,),normalize = 1)#normalize可省略默认为1
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
2.求和:很容易发生溢出,25个这样的雨元素相加很容易超过255
例如:
import cv2
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\lenaNoise.png")
r = cv2.boxFilter(o,-1,(5,5,),normalize = 0)#normalize可省略默认为1
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
核换成2行2列,效果会好一些
import cv2
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\lenaNoise.png")
r = cv2.boxFilter(o,-1,(2,2,),normalize = 0)#normalize可省略默认为1
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
r = cv2.boxFilter(o,-1,(5,5),normalize = 1)#归一化处理与均值滤波相同,normalize省略默认为1
-1:深度和运势图像保持一致
核大小(5,5)
r = cv2.boxFliter(o,-1,(5,5),normalize = 1#不进行归一化处理,几个像素点相加很可能超过255,最后得到一个纯白色的图像
让临近的像素具有更高的重要度,对周围像素计算加权平均值,较近的像素具有较大的权重值。
GaussionBlur函数
dst = cv2.GaussionBlur(src,ksize,sigmaX)#sigmaX,他自己会计算x方向上的方差
Ksize:核大小(N,N)必须是奇数
sigmaX:X方向方差,控制权重
sigmaX = 0时:sigma = 0.3*((ksize-1)*0.5-1)+0.8
y的方差和X保持一致
关键核心代码:
r = cv2.GaussianBlur(o,(3,3),0)
import cv2
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\lenaNoise.png")
r = cv2.GaussianBlur(o,(5,5),0)
cv2.imshow("ee",o)
cv2.imshow("eew",r)
cv2.waitKey()
cv2.destroyAllWindows()
滤波效果比前面的都好
让临近像素按照大小排列,取排列像素集中于中间位置的值作为中值滤波后的像素值,可以把那些离群的点,
函数:
medianBlur函数
dst = cv2.medianBlur(src,ksize)
src,源文件
ksize;核大小:必须是比1大的奇数
关键代码:
r = cv2.medianBlur(o,3)#o原始图像,核大小3
历程:
import cv2
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\lenaNoise.png")
r = cv2.medianBlur(o,3)#核大小是3,越大越模糊
cv2.imshow("ooo",o)
cv2.imshow("rrr",r)
cv2.waitKey()
cv2.destroyAllWindows()
形态学转换主要是针对二值图像,腐蚀的是像素点为1的那个点,腐蚀的是白色,
对象1:二值图像
对象2:卷积核:也是一个二值图像
用卷积核遍历每个原始图像的像素点,如果每个在核大小周围的像素点为1(白色),这个白色就保持不变。
如果在核的范围之内存在黑色的点,就将当前的点设为0(黑色)
dst = cv2.erode(src,kernel,iteration)
det:处理结果
src:源图像 kernel 卷积核,iteration 迭代次数,默认情况下进行1次腐蚀,根据需要可多次腐蚀
生成一个卷积核,
kernel = np.ones((5,5),np.uint8)#ones表示数组里面的元素都是1,5行5列,np.uint8表示数据类型
dst = cv2.erode(src,kernel,iteration)
代码如下:
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\erode.bmp",cv2.IMREAD_UNCHANGED)
k = np.ones((5,5),np.uint8)#定义一个卷积核
r = cv2.erode(o,k,3)#开始腐蚀,不写默认一次
cv2.imshow("o",o)
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
膨胀是腐蚀的逆操作
可通过一次膨胀,一次腐蚀来达到去除噪声(毛刺)的操作
先腐蚀后膨胀,形态学运算中叫做开运算
在卷积核对应大小这篇区域中,有1个像素点为1的点这个点像素就为1,
函数:dilat
dst = cv2.dilat(src,keral,iterations)
dst:处理结果
src:源图像
kernel:卷积核
iterations,迭代次数
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\erode.bmp",cv2.IMREAD_UNCHANGED)
k = np.ones((5,5),np.uint8)#定义一个卷积核
r = cv2.dilate(o,k)#开始腐蚀,不写默认一次
cv2.imshow("o",o)
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
先腐蚀后膨胀
图像被腐蚀后,去除了噪声,但是图像会压缩,
腐蚀过得图像通过膨胀,可以去除噪声,并曝出,原来的形状
开运算(image) = 膨胀(腐蚀(image)
函数:morphologyEx
opening = cv2.morpholoyEx(img,cv2.MORPH_OPEN,kernel)
opencving :开运算结果
img:源图像
cv2.MORPH_OPEN:开运算
kernel:卷积核
kernel = np.opes((5,5),np.uint8) #生成一个5行5列,用它作为一个卷积核,对原始图像进行开运算
核心代码:
k = np.ones((5,5),np.uint8)
r = cv2.morphologyEx(o,cv2.MORPH_OPEN,K)
import cv2
import numpy as np
a = cv2.imread("E:\OPCV_yuanma\chapter8\image\erode.bmp")
k = np.ones((8,8,),np.uint8)#根据不同要求调解卷积核大小
r = cv2.morphologyEx(a,cv2.MORPH_OPEN,k)
cv2.imshow("a",a)
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
先膨胀后腐蚀,
有助于关闭,前景物体内部小孔,或物体上的小黑点
闭运算(image) = 腐蚀(膨胀(image))
函数:morphologyEx
closing = cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)
close ,闭运算结果
img:源图像
cv2.MORPH_CLOSE:闭运算
kernel:卷积核
kernel = np.ones((5,5),np.uint8)
核心代码:
k = np.ones((5,5),np.uint8)
r = cv2.morphologyEx(o,cv2.MORPH_CLOSE,K)
在二值图像里白色的像素值是1,黑色的像素值是0
梯度操作 :膨胀图像 - 腐蚀图像 = 轮廓图像
梯度(image) = 膨胀(image)-腐蚀(image)
在opencv中我们不关心细节是怎么实现的,直接调用封装好的函数就行了
函数:morphologyEx
result = cv2.morphpologyEx(img,cv2.MORPH_GRADIENT,kenal)
result梯度结果
img:源图像
cv2.MORPH_GRADIENT,梯度
kernel:卷积核
核心代码
kernel = np.ones((5,5),np.uint8)
r = cv2.morphologyEx(o,cv2.MORPH_GRADIENT,K)
import cv2
import numpy as np
a = cv2.imread("E:\OPCV_yuanma\chapter8\image\gradient.bmp")
k = np.ones((10,10,),np.uint8)#根据不同要求调解卷积核大小
r = cv2.morphologyEx(a,cv2.MORPH_GRADIENT,k)
cv2.imshow("a",a)
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
礼帽图像 = 原始图像-开运算图像
结果得到噪声图像
函数:morphologyEx
result = cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel)
result 礼帽结果
img:源图像
cv2.MORPH_TOPHAT,礼帽
kernel:卷积核
核心代码
k = np.ones((5,5),np.uint8)
r = cv2.morphologyEx(o.cv2.MORPH_TOPHAT,k)
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\opening.bmp")
k = np.ones((5,5),np.uint8)
r = cv2.morphologyEx(o,cv2.MORPH_TOPHAT,k)
cv2.imshow("o",o)
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
黑帽图像 = 闭运算-原始图像
得到图像内部小点的图像
函数
morphologyEx
result = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel)
result :黑帽结果
img :源图像
cv2.MORPH_BLACKHAT:黑帽
kernel:卷积核
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\closing2.bmp")
k = np.ones((5,5),np.uint8)
r = cv2.morphologyEx(o,cv2.MORPH_BLACKHAT,k)
cv2.imshow("o",o)
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
dst = cv2.Sobel(src,ddepth,dx,dy,[ksize])#kzize 不写默认是3
dst :计算结果
src:原始图像
ddepth:处理结果图像深度,很多函数里可以直接写成-1,让处理图像和原始图像深度保持一致,
dx:x轴方向
dy:轴方向
ksize:核大小
x轴方向上的梯度,dx = 1,dy = 0
y轴上的梯度,dy = 1,dx = 0
dst = cv2.Sobel(src,ddepth,dx,dy,[ksize])
实例只计算出右边的边界:
"""
只计算出右边边界
"""
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\sobel.bmp",cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o,-1,1,0)#因为第二个参数为-1,只计算出右边的边界
cv2.imshow("o",o)
cv2.imshow("s",sobelx)
cv2.waitKey()
cv2.destroyAllWindows()
计算出左右边界:
"""
计算出左右边界
把-1改成cv2.CV_64F
"""
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\sobel.bmp",cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o,cv2.CV_64F,1,0)#计算出左右边的边界
sobelx = cv2.convertScaleAbs(sobelx)#取绝对值,有的图像可能不用调节也可以显示,最好加上
cv2.imshow("o",o)
cv2.imshow("s",sobelx)
cv2.waitKey()
cv2.destroyAllWindows()
计算出上下左右边界:
"""
计算出左右边界
把-1改成cv2.CV_64F
"""
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\man.bmp",cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o,cv2.CV_64F,1,0)#计算出左右边的边界
sobely = cv2.Sobel(o,cv2.CV_64F,0,1)#计算出上下边界
sobelx = cv2.convertScaleAbs(sobelx)#取绝对值,有的图像可能不用调节也可以显示,最好加上
sobely = cv2.convertScaleAbs(sobely)#取绝对值,有的图像可能不用调节也可以显示,
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)#x和y的系数都输0.5.修正系数设置成0
#sobelxy11 = cv2.Sobel(o,cv2.CV_64F,1,1)#这种方法显示效果不好
sobelxy11 = cv2.convertScaleAbs(sobelxy11)
cv2.imshow("o",o)#显示原始图像
cv2.imshow("x",sobelx)#显示x边界
cv2.imshow("y",sobely)#显示y边界
cv2.imshow("xy",sobelxy)
#cv2.imshow("xy11",sobelxy11)
cv2.waitKey()
cv2.destroyAllWindows()
canny边缘检测步骤
.去噪——梯度——非极大值抑制——滞后阈值
梯度的方向一般总是与边界垂直。
梯度的方向分为4类:垂直,水平,和两个对角线
3.非极大值抑制:
逐个遍历像素点,判断当前像素点 是不是所有相同方向中最大的,如果是最大的保留,
4.滞后阈值:
如果梯度值>边界值,就处理为边界
如果梯度值<边界值,抛弃
中间值,:
如果和边界值相连的保留
与边界不相连抛弃
函数canny
edges = cv2.Canny(image,theshole1,threshold2)
edges 边界图像
image,原始图像
threshold1,阈值1
threshole2阈值2,
如果想让canny边缘检测边界更多,把阈值调小一点
如果想让边界没那么丰富,把这两个阈值调大一点
例如:
"""
cany边缘检测
"""""
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\man.bmp",cv2.IMREAD_GRAYSCALE)
r1 = cv2.Canny(o,100,200)#检测边缘值较大,边缘少
r2 = cv2.Canny(o,64,128)#检测边缘值小,边缘多
cv2.imshow("r1",r1)
cv2.imshow("r2",r2)
cv2.waitKey()
cv2.destroyAllWindows()
向上取样分辨率越来越大
1.对图像Gi中进行高斯核卷积
2.删除所有的偶数行和列
向下取样:缩小 图像
原始图像:M*N——>处理结果是M/2*N/2
每次处理后都是原有图像的1/4
上述操作被称为:Octave
在每个方向上扩大为原来的两倍,新增的 行和列以0填充
使用与“向下采样”同样的卷积核乘以4,获取“新增像素”的新值
如果直接滤波的话,整体来说像素会降低1/4
所以要乘以4,来保证这是一个正常的图像,而不是所有像素值都变为原来1/4这样的一个图像
所有的元素都被规范化为4而不是1
上图告诉我们图像向下以后再向上取样,这个过程不是互逆的无法恢复原有图像,
opencv中提供了cv2.pyrDown(src)
dst = cv2.pyrDown(src)
dst ,向下取样结果
src, 原始图像
"""
向下取样
"""""
import cv2
import numpy as np
o = cv2.imread("E:\jre\\32945694.jpg",cv2.IMREAD_GRAYSCALE)
r = cv2.pyrDown(o)#向下取样
cv2.imshow("o",o)
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
进行多次取样的变化,每个图像都是原来的1/4
"""
向下取样
"""""
import cv2
import numpy as np
o = cv2.imread("E:\jre\\32945694.jpg",cv2.IMREAD_GRAYSCALE)
r = cv2.pyrDown(o)#向下取样
s = cv2.pyrDown(r)
t = cv2.pyrDown(s)
cv2.imshow("o",o)#原始图像
cv2.imshow("r",r)#第一次取样
cv2.imshow("s",s)#第二次取样
cv2.imshow("t",t)#第三次取样
cv2.waitKey()
cv2.destroyAllWindows()
都是以4倍为单位进行变化的
如果向下取样图像的大小变为原来的1/4
opencv中向上取样函数
dst = cv2.pyrUp9(src)
dst :原始图像
src ,原始图像
"""
向上取样
"""""
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\lena256.bmp",cv2.IMREAD_GRAYSCALE)
r = cv2.pyrUp(o)#向下取样
cv2.imshow("o",o)#原始图像
cv2.imshow("r",r)#第一次取样
cv2.waitKey()
cv2.destroyAllWindows()
多次向上取样
"""
向上取样
"""""
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\lena256.bmp",cv2.IMREAD_GRAYSCALE)
r = cv2.pyrUp(o)#向下取样
s = cv2.pyrUp(r)
t = cv2.pyrUp(s)
cv2.imshow("o",o)#原始图像
cv2.imshow("r",r)#第一次取样
cv2.imshow("s",s)#第二次取样
cv2.imshow("t",t)#第三次取样
cv2.waitKey()
cv2.destroyAllWindows()
4.图像金字塔向上取样与向下取样的可逆性研究
先进性向下取样在进行向上取样
"""
向上取样
"""""
import cv2
import numpy as np
o = cv2.imread("E:\OPCV_yuanma\chapter8\image\lena256.bmp",cv2.IMREAD_GRAYSCALE)
r = cv2.pyrDown(o)#向下取样
s = cv2.pyrUp(r)#向上取样
cv2.imshow("o",o)#原始图像
cv2.imshow("r",s)#
cv2.waitKey()
cv2.destroyAllWindows()
Li = Gi - PyrUp(PyDown(Gi))
Gi ,原始图像
Li ,拉普拉斯金字塔图像
“”“”“
中间这段笔记没有保存
”“”
横坐标:[0:255]
纵坐标:各个灰度级的像素个数
绘图的时候仅仅一个纵坐标就能绘制一个图像了
现在计算一个图像的直方图由绘图变成了求数据
opencv第一步就是求出这样一个数据(每一个灰度值对应的个数)
函数calcHist(用来计算这个数组)
hist = cv2.calcHist(images,channels,mask,histSize,range,accumulate)
hist,直方图
images:原始图像 histSizeBINS的数量例如:[256]
channels:指定通道 range: 像素值范围:RANGE例如[0,255]
mask :掩码图像 accumlate:累计标识 可选参数,一般默认省略掉
import cv2
import numpy as np
img = cv2.imread("E:\OPCV_yuanma\chapter8\image\lena.bmp")
hist = cv2.calcHist([img],[0],None,[256],[0,255])
print(type(hist))#返回的类型
print(hist.size)#大小是256个元素
print(hist.shape)#形状256行1列
print(hist)#输出每个灰度级在图像有多少个
掩模:黑色不透明,白色为透明
把掩模放到原始图像上
黑色部分就被覆盖了,白色部分因为是透明的,所以他会映衬过来一个图像,
关键代码:
mask = np.zeros(image.shape,np.uint8)#一般是对灰度图像进行操作
mask = [200:400,200:400] = 255#第200行到400行,200列到400列为白色
生成直方图的时候要先获取统计直方图,
一般形式:
hist = cv2.calc.Hist(image,channels,mask,histSize,ranges)