此次学习的是csdn学院中《Python+OpenCV计算机视觉》,比较基础,适合初学者。
第一次尝试以博客形式来记录学习笔记,督促自己,提升自我,供自己和大家学习。
目录
图像的读取、显示和保存
1.读入图像
- retval = cv2.imread(文件名,[显示控制参数])
2.显示图像
-
None = cv2.imshow(窗口名,图像名)
-
retval = cv2.waitKey(delay) #delay>0 : 等待delay毫秒 delay<0 : 等待键盘单击 delay=0 : 无限等待
-
cv2.destroyAllWindows() # 删除所有窗口
3.保存图像
- retval = cv2.imwrite(文件地址,文件名)
范例:
import cv2
i = cv2.imread(".\he.jpg")
cv2.imshow("he",i)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite(".\me.jpg", i)
图像处理基础
像素处理
1.读取像素
-
返回值 = 图像(位置参数)
-
灰度图像,返回灰度值
-
BGR图像,返回值为B、G、R的值
2.修改像素
- 灰度图像 img[66,66] = 255
- BGR图像 img[66,66,0] = 255 \ img[66,66] = [255,255,255]
范例:
import cv2
i = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
print(i[100,100])
i[100,100] = [255,255,255]
print(i[100,100])
使用numpy进行像素处理
1.读取像素
- 返回值 = 图像.item(位置参数)
- 灰度图像,返回值灰度值 p = img.item(66,66)
- BGR图像,返回值为B、G、R的值 blue = img.item(66,66,0)
2.修改像素值
- 图像名.itemset(位置,新值)
- 灰度图像 : img.itemset((66,66),255)
- BGR图像 : img.itemset((66,66,0),255)
范例:
import cv2
import numpy
i = cv2.imread(".\me.bmp",cv2.IMREAD_UNCHANGED)
print(i.item(33,33,0))
i.itemset((33,33,0),255)
print(i.item(33,33,0))
获取图像属性
1.形状:行、列、通道数
- shape 可以获取图像的形状,返回包含行数,列数,通道数的元组。
- 灰度 返回:行数,列数
import cv2
img1 = cv2.imread(".\he.jpg",cv2.THRESH_BINARY)
print(img1.shape)
##(336, 449)
- 彩色 返回:行数,列数,通道数
import cv2
img2 = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
print(img2.shape)
##(336, 449, 3)
2.像素数目
- size 可以获取图像的像素数目。
- 灰度 返回:行数*列数
import cv2
img1 = cv2.imread(".\he.jpg",cv2.THRESH_BINARY)
print(img1.size)
##150864
-
彩色 返回:行数*列数*通道数
import cv2
img2 = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
print(img2.size)
##452592
3.图像的数据类型
- dtype 返回的是图像的数据类型
import cv2
img = cv2.imread(".\he.jpg",cv2.THRESH_BINARY)
print(img.dtype)
##uint8
感兴趣区域ROI
-
ROI(region of interest),感兴趣区域。
-
从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区。
-
可以通过各种算子(Operator)和函数来求得感兴趣区域ROI,并进行图像的下一步处理。
范例:
import cv2
import numpy as np
a = cv2.imread(".\he.jpg")
b = np.ones((101,101,3))
b = a[100:300,200:400]
c = a
c[0:200,0:200] = b
cv2.imshow("original",a)
cv2.imshow("face",b)
cv2.imshow("face2",c)
cv2.waitKey(0)
cv2.destroyAllWindows()
通道的拆分和合并
-
拆分通道
-
合并
范例:
import cv2
import numpy
img = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
b = img[:,:,0]
g = img[:,:,1]
r = img[:,:,2]
b1, g1, r1 = cv2.split(img)
m = cv2.merge([b,g,r])
cv2.imshow("b",b)
cv2.imshow("b1",b1)
cv2.imshow("m",m)
cv2.waitKey()
cv2.destroyAllWindows()
图像运算
加法运算
1.Numpy加法
- 取模加法 结果 = (图像1像素值 + 图像2像素值) % 255
2.OpenCV加法
- 饱和运算 结果 = cv2.add(图像1,图像2)
- 像素值<=255 图像1+图像2
- 像素值 > 255 取值255
注意的问题:参与运算的图像大小、类型必须一致
范例:
import cv2
import numpy
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
b = a
result1 = a + b
result2 = cv2.add(a,b)
cv2.imshow("original",a)
cv2.imshow("result1",result1)
cv2.imshow("result2",result2)
cv2.waitKey()
cv2.destroyAllWindows()
图像融合
-
将2张或2张以上的图像信息的融合到1张图像上
-
融合的图像含有更多的信息、能够更方便人来观察或者计算机处理
- 图像加法: 结果图像 = 图像1 + 图像2
- img = img1 + img2
- 图像融合: 结果图像 = 图像1*系数1 + 图像2*系数2 + 亮度调节量
- img = img1*0.3 + img2*0.7 + 18
- 函数addWeighted
- dst = cv2.addWeighted(src1, alpha, src2, beta, gamma)
- dst = src1 *alpha + src2*beta + gamma
- 参数gamma不能省略
范例:
import cv2
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
b = a
result3 = cv2.addWeighted(a,1,b,1,0)
cv2.imshow("original",a)
cv2.imshow("result3",result3)
cv2.waitKey()
cv2.destroyAllWindows()
类型转换
-
OpenCV提供了200多种不同类型之间的转换
- cv2.COLOR_BGR2GRAY
- cv2.COLOR_BGR2RGB
- cv2.COLOR_GRAY2BGR
- ......
范例:彩色变灰度
import cv2
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
b = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
几何变换
图像缩放
- resize函数
- dst = cv2.resize(src, dsize, dst, fx, fy, interpolation)
- src 原始图像
- dsize 缩放大小
- b = cv2.resize(a, (122,122)) #dsize 表示 (列数,行数)
- fx, fy 放缩大小
- b = cv2.resize(a, None, fx=0.5, fy=0.7)
范例:
import cv2
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
rows,cols = a.shape[:2]
b = cv2.resize(a, (round(cols*0.5),round(rows*0.5)))
cv2.imshow("original",a)
cv2.imshow("resize",b)
cv2.waitKey()
cv2.destroyAllWindows()
图像旋转
- flip函数
- dst = cv2.flip(src, flipCode)
- flipCode = 0 以X轴为对称轴翻转
- flipCode > 0 以Y轴为对称轴翻转
- flipCode < 0 在X轴、Y轴方向同时翻转
范例:
import cv2
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
b = cv2.flip(a,0)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
图像阈值
-
threshold函数
- retval, dst = cv2.threshold(src, thresh, maxval, type)
- retval:阈值
- dst:处理结果
- src:源图像
- threshold:阈值
- maxval:最大值
- type:类型
范例:
import cv2
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
r, b = cv2.threshold(a, 177, 255, cv2.THRESH_BINARY)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
图像平滑处理
均值滤波
- 函数blur
- 处理结果 = cv2.blur(原始图像, 核大小)
范例:
import cv2
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
b = cv2.blur(a, (5, 5))
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
方框滤波
- 函数boxFilter
- 处理结果 = cv2.boxFilter(原始图像,目标图像深度,核大小,normalize属性)
- normalize属性:
范例:
import cv2
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
b = cv2.boxFilter(a, -1, (5, 5), normalize=1)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
高斯滤波
- 让临近的像素具有更高的重要度。对周围像素计算加权平均值,较近的像素具有较大的权重值。
- 函数GaussianBlur
- dst = cv2.GaussianBlur(src, ksize, sigmaX)
- ksize : 核大小(N, N),N必须为奇数
- sigmaX : X方向方差,控制权重
范例:
import cv2
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
b = cv2.GaussianBlur(a,(3,3),0)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
中值滤波
- 让邻近的像素按照大小排列,去排序像素几种位于中间位置的值作为中值滤波后的像素值。
- 函数medianBlur
- dst = cv2.medianBlur(src, ksize)
- kszie : 核大小,必须是比1大的奇数,如3,5,7等
范例:
import cv2
a = cv2.imread(".\he.jpg",cv2.IMREAD_UNCHANGED)
b = cv2.medianBlur(a,3)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
图像腐蚀
- 形态学转换主要针对的是二值图像。
- 两个输入对象:二值图像;卷积核
- 卷积核的中心点逐个像素扫描原始图像。
- 被扫描的原始图像中的像素点,只有当卷积核对应的元素均为1时,其值才为1,否则值为0。
- 函数erode
- dst = cv2.erode(src, kernel, iterations)
- kernel : 源图像
- iterations : 迭代次数
范例:
import cv2
import numpy as np
a = cv2.imread(".\erode.jpg",0)
kernel = np.ones((50,50),np.uint8)
b = cv2.erode(a,kernel)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
形态学处理
图像膨胀
- 是腐蚀操作的逆操作。
- 图像被腐蚀后,去除了噪声,但是会压缩图像。
- 对腐蚀过的图像,进行膨胀处理,可以去除噪声,并保持原有形状。
- 函数dilate
- dst = cv2.dilate(src, kernel, iterations)
范例:
import cv2
import numpy as np
a = cv2.imread(".\erode.jpg",0)
kernel = np.ones((50,50),np.uint8)
b = cv2.dilate(a,kernel)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
开运算
- 图像被腐蚀后,去除了噪声,但是会压缩图像。
- 对腐蚀过的图像,进行膨胀处理,可以去除噪声,并保持原有形状。
- 开运算(image)=膨胀(腐蚀(image))
- 函数morphologyEx
- opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
- cv2.MORPH_OPEN : 开运算
范例:
import cv2
import numpy as np
a = cv2.imread(".\opening.jpg",0)
kernel = np.ones((5,5),np.uint8)
b = cv2.morphologyEx(a, cv2.MORPH_OPEN, kernel)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
闭运算
- 先膨胀,后腐蚀。
- 有助于关闭前景物体内部的小孔,或物体上的小黑点。
- 闭运算(image)=腐蚀(膨胀(image))
- 函数morphologyEx
- opening = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
- cv2.MORPH_CLOSE : 闭运算
范例:
import cv2
import numpy as np
a = cv2.imread(".\closing.jpg",0)
kernel = np.ones((5,5),np.uint8)
b = cv2.morphologyEx(a, cv2.MORPH_CLOSE, kernel)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
梯度运算
- 梯度(image)=膨胀(image)- 腐蚀(image)
- 函数morphologyEx
- opening = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
- cv2.MORPH_GRADIENT : 梯度
范例:
import cv2
import numpy as np
a = cv2.imread(".\gradient.jpg",0)
kernel = np.ones((5,5),np.uint8)
b = cv2.morphologyEx(a, cv2.MORPH_GRADIENT, kernel)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
礼帽运算
- 礼帽图像 = 原始图像 - 开运算
- 得到噪声图像
- 函数morphologyEx
- opening = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
- cv2.MORPH_TOPHAT : 礼帽
范例:
import cv2
import numpy as np
a = cv2.imread(".\tophat.jpg",0)
kernel = np.ones((5,5),np.uint8)
b = cv2.morphologyEx(a, cv2.MORPH_TOPHAT, kernel)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
黑帽运算
- 黑帽图像 = 闭运算图像 - 原始图像
- 得到图像内部的小孔,或前景色中的小黑点
- 函数morphologyEx
- opening = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
- cv2.MORPH_BLACKHAT : 黑帽
范例:
import cv2
import numpy as np
a = cv2.imread(".\blackhat.jpg",0)
kernel = np.ones((5,5),np.uint8)
b = cv2.morphologyEx(a, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
图像梯度
Sobel算子
- 函数Sobel
- dst = cv2.Sobel(src, ddepth, dx, dy, [ksize])
- ddepth : 处理结果图像深度。(通常情况下,可以将该参数的值设置为-1,让处理结果与原始图像保持一致)
- 实际操作中,计算梯度值可能会出现负数,所以,通常计算时,使用更高的数据类型cv2.CV_64F,
- 取绝对值后,再转换为np.uint8(cv2.CV_8V)类型。
- dx : x轴方向(计算x轴方向梯度,可设置为dx=1)
- dy : y轴方向(计算y轴方向梯度,可设置为dy=1)
- [ksize] : 核大小
范例:
import cv2
import numpy as np
a = cv2.imread(".\yuan.jpg",0)
b = cv2.Sobel(a, cv2.CV_64F, 1, 0)
b = cv2.convertScaleAbs(b) # 转回uint8
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
Scharr算子
- 使用3*3的sobel算子时,可能不太精确。
- scharr算子,效果更好。(和sobel差别在于卷积核系数不一样)
- 函数Scharr
- dst = cv2.Scharr(src, ddepth, dx, dy)
范例:
import cv2
import numpy as np
a = cv2.imread(".\yuan.jpg",0)
scharrx = cv2.Scharr(a, cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(a, cv2.CV_64F, 0, 1)
scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
b = cv2.convertScaleAbs(scharrxy) # 转回uint8
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
Laplacian算子
- 函数Laplacian
- dst = cv2.Laplacian(src, ddepth)
范例:
import cv2
import numpy as np
a = cv2.imread(".\yuan.jpg",0)
b = cv2.Laplacian(a, cv2.CV_64F)
b = cv2.convertScaleAbs(b) # 转回uint8
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
Canny边缘检测
-
去噪-梯度-非极大值抑制-滞后阈值
- 函数Canny
- edges = cv2.Canny(image, threshold1, threshold2)
- threshold1 : minVal阈值1
- threshold2 : maxVal阈值2
范例:
import cv2
import numpy as np
a = cv2.imread(".\yuan.jpg",0)
b = cv2.Canny(a, 100, 200 )
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.waitKey()
cv2.destroyAllWindows()
图像金字塔
- 同一图像的不同分辨率的子图集合
- 向下取样:缩小图像
- 1.对图像Gi进行高斯核卷积
- 2.删除所有的偶数行和列
- 原始图像M*N → 处理结果 M/2*N/2
- 每次处理后,结果图像是原来的1/4
- 上述操作被称为:Octavc
- 向上取样:放大图像
- 在每个方向上扩大为原来的2被,新增的行和列以2填充
- 使用与“向下采样”同样的卷积核乘以4,获得“新增像素”的新值
向下取样
- dst = cv2.pyrDown(src)
范例:
import cv2
import numpy as np
a = cv2.imread(".\yuan.jpg",0)
b = cv2.pyrDown(a)
b1 = cv2.pyrDown(b)
b2 = cv2.pyrDown(b1)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.imshow("b1",b1)
cv2.imshow("b2",b2)
cv2.waitKey()
cv2.destroyAllWindows()
向上取样
- dst = cv2.pyrUp(src)
范例:
import cv2
import numpy as np
a = cv2.imread(".\yuan.jpg",0)
b = cv2.pyrUp(a)
b1 = cv2.pyrUp(b)
b2 = cv2.pyrUp(b1)
cv2.imshow("original",a)
cv2.imshow("b",b)
cv2.imshow("b1",b1)
cv2.imshow("b2",b2)
cv2.waitKey()
cv2.destroyAllWindows()
拉普拉斯金字塔
- Li = Gi - PyrUp(PyrDown(Gi)))
- Gi : 原始图像第i层向下取样图像
- Li : 拉普拉斯金字塔图像
范例:
import cv2
import numpy as np
G0 = cv2.imread(".\yuan.jpg",0)
G1 = cv2.pyrDown(G0)
L0 = G0 - cv2.pyrUp(cv2.pyrDown(G0))
L1 = G1 - cv2.pyrUp(cv2.pyrDown(G1))
cv2.imshow("original",G0)
cv2.imshow("L0",L0)
cv2.imshow("L1",L1)
cv2.waitKey()
cv2.destroyAllWindows()
#报错
# L1 = G1 - cv2.pyrUp(cv2.pyrDown(G1))
#ValueError: operands could not be broadcast together with shapes (257,274) (258,274)
#说是图像大小出错,但是不太明白哪出错了???
图像轮廓
- 边缘检测能够测出边缘,但是边缘是不连续的
- 将边缘连接为一个整体,构成轮廓
- 对象是二值图像,所以需要预先进行阈值分割或者边缘检测处理
- 查找轮廓需要更改原始图像,因此,通常使用原始图像的一份拷贝操作
- 在OpenCV中,是冲黑色背景中查找白色对象,因此,对象必须是白色的,背景必须是黑色的
- 函数cv2.findContours()
- image, contours, hierarchy = cv2.findContours(image, mode, method)
- 输出:image,修改后的原始图像 contours,轮廓 hierarchy,图像的拓扑信息(轮廓信息)
- 输入:image,原始图像 mode,轮廓检索模式 method,轮廓的近似方法
- mode,轮廓检索模式:cv2.RETR_EXTERNAL 只检测外轮廓
- cv2.RETR_LIST 检测的轮廓不建立等级关系
- cv2.RETE_CCOMP 建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息
- cv2.RETR_TREE 建立一个等级树结构的轮廓
- method,轮廓的近似方法:cv2.CHAIN_APPROX_NONE 存储所有的轮廓点,相邻的两个点的像素位置差不超过1
- cv2.CHAIN_APPROX_SIMPLE 压缩水平方向,垂直方向,对角线方向的元素,
- 只保留该方向的终点坐标,例如一个矩形轮廓只需4个点保存轮廓信息
- cv2.CHAIN_APPROX_TC89_L1 使用teh-Chinl chain 近似算法
- cv2.CHAIN_APPROX_TC89_KCOS 使用toh-Chinl chain 近似算法
- 函数cv2.drawContours()
- r = cv2.drawCoutours(o, contours, contourldx, color, [, thickness]
- r 目标图像,直接修改目标的像素点,实现绘制
- o 原始图像
- contours 需要绘制的边缘数组
- contourldx 需要绘制的边缘索引,如果全部绘制则为-1
- color 绘制的颜色,为BGR格式的Scalar
- thinckness 可选,绘制的密度,即描绘轮廓时所用的画笔粗细
范例:
import cv2
import numpy as np
a = cv2.imread(".\yuan.jpg",0)
gray = cv2.cvtColor(a,cv2.COLOR_BGR2RGB)
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
r = cv2.drawContours(a, contours, -1, (0,0,255), 1)
cv2.imshow("original",a)
cv2.imshow("r",r)
cv2.waitKey()
cv2.destroyAllWindows()
#报错
#又不知哪错了???
直方图
- 横坐标:图像中各个像素点的灰度级
- 纵坐标:具有该灰度级的像素个数
绘制直方图
- 函数hist
- 根据数据源和像素级绘制直方图
- hist(数据源,像素级)
- 数据源:图像,必须是一维数据;像素级:一般是256
- 函数ravel
- 将多维数组降为一维数组
- 一维数组=多维数组.ravel()
范例:
import cv2
import matplotlib.pyplot as plt
img = cv2.imread(".\he.jpg")
plt.hist(img.ravel(),256)
plt.show()
使用OpenCV统计直方图
- 函数calcHist
- hist = cv2.calcHist(image, channels, mask, histSize, ranges, accumulate)
- hist:直方图,是一个数组
- images:原始图像
- channels:指定通道
- 通道编号需要用中括号括起来
- 输入图像是灰度图时,它的值是[0]
- 彩色图像可以是[0],[1],[2]分别对应通道B,G,R。
- mask:掩码图像
- 统计整幅图像的直方图,设为None
- 统计图像某一部分的直方图时,需要掩码图像
- histSize:BINS的数量,例如:[256]
- ranges:像素值范围
- accumulate:累计标识
- 默认值为false
- 如果被设置为true,则直方图在开始分配时不会被清零
- 该参数允许从多个对象中计算单个直方图,或者用于实时更新直方图
- 多个直方图的积累结果,用于对一组图像计算直方图
范例:
import cv2
import numpy as np
img = cv2.imread(".\he.jpg")
hist = cv2.calcHist([img],[0],None,[256],[0,255])
print(type(hist))
print(hist.size)
print(hist.shape)
#<class 'numpy.ndarray'>
#256
#(256, 1)
绘制OpenCV统计直方图
范例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(".\he.jpg")
hist = cv2.calcHist([img],[0],None,[256],[0,255])
plt.plot(hist,color = 'b')
plt.show()
使用掩膜直方图
- 生成掩膜图像
- mask = np.zeros(image,shape,np.uint8)
- mask[200:400,200:400] = 255
范例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(".\he.jpg",cv2.IMREAD_GRAYSCALE)
mask = np.zeros(img.shape,np.uint8)
mask[200:400,200:400] = 255
hist1 = cv2.calcHist([img],[0],None,[256],[0,255])
hist2 = cv2.calcHist([img],[0],mask,[256],[0,255])
plt.plot(hist1,color='r')
plt.plot(hist2,color='b')
plt.show()
直方图均衡化
- 前提:如果一幅图像占有全部可能的灰度级,并且均匀分布。
- 结论:该图像具有高对比度和多变的灰度色调。
- 外观:图像细节丰富,质量更高。
- 函数equalizeHist
- dst = cv2.equalizeHist(src)
- src:源图像
- dst:处理结果
范例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(".\he.jpg",cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(img)
plt.figure()
plt.hist(img.ravel(),256)
plt.figure()
plt.hist(equ.ravel(),256)
plt.show()
傅里叶变换
numpy实现傅里叶变换函数
- 函数numpy.fft.fft2
- 实现傅里叶变换
- 返回一个复数数组(complex ndarray)
- 函数numpy.fft.fftshift
- 将零频率分量移动到频谱中心
- 20*np.log(np.abs(fshift))
- 设置 频谱的范围
- 注意:
- 傅里叶得到低频、高频信息,针对低频、高频处理能够实现不同的目的
- 傅里叶过程是可逆的,图像经过傅里叶变换、逆傅里叶变换后,能够恢复到原始图像
- 在频域对图像处理,在频域的处理会反应在逆变换图像上
范例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(".\he.jpg",cv2.IMREAD_GRAYSCALE)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
result = 20*np.log(np.abs(fshift))
plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(result,cmap='gray')
plt.title('result')
plt.axis('off')
plt.show()
numpy实现逆傅里叶变换函数
- 函数numpy.fft.ifft2
- 实现逆傅里叶变换,返回一个复数数组
- 函数numpy.fft.ifftshift
- fftshift函数的逆函数
- iimg = np.abs(逆傅里叶变换结果)
- 设置值的范围
范例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(".\he.jpg",cv2.IMREAD_GRAYSCALE)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(iimg,cmap='gray')
plt.title('result')
plt.axis('off')
plt.show()
高通滤波
- 低频,对应图像内变化缓慢的灰度分量。
- 高频,对应图像内变化越来越快的灰度分量。
- 滤波,接受(通过)或者拒绝一定频率的分量。
- 频域滤波,修改傅里叶变换以达到特殊的目的,然后计算IDFT返回到图像域。
- 特殊目的:图像增强、图像去噪、边缘检测、特征提取、压缩、加密等。
范例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(".\he.jpg",cv2.IMREAD_GRAYSCALE)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
rows,cols = img.shape
crow,ccol = int(rows/2),int(cols/2)
fshift[crow-30:crow+30,ccol-30:ccol+30] = 0
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(iimg,cmap='gray')
plt.title('result')
plt.axis('off')
plt.show()
OpenCV实现傅里叶变换
- 函数dft
- 返回结果 = cv2.dft(原始图像,转换标识)
- 返回结果:是双通道,第1个通道是结果的实数部分,第2个通道是结果的虚数部分
- 原始图像:输入图像要首先转换成np.float32格式,np.float32(img)
- 转换标识:flags = cv2.DFT_COMPLEX_OUTPUT,输出一个复试阵列
- 函数magnitude
- 返回值 = cv2.magnitude(参数1,参数2)
- 计算幅值
- 参数1:实部
- 参数2:虚部
范例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(".\he.jpg",cv2.IMREAD_GRAYSCALE)
dft = cv2.dft(np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dftshift = np.fft.fftshift(dft)
result = 20*np.log(cv2.magnitude(dftshift[:,:,0],dftshift[:,:,1]))
plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(result,cmap='gray')
plt.title('result')
plt.axis('off')
plt.show()
OpenCV实现逆傅里叶变换
- 函数idft
- 返回结果 = cv2.idft(原始数据)
范例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(".\he.jpg",cv2.IMREAD_GRAYSCALE)
dft = cv2.dft(np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dftshift = np.fft.fftshift(dft)
ishift = np.fft.ifftshift(dftshift)
iimg = cv2.idft(ishift)
iimg = cv2.magnitude(iimg[:,:,0],iimg[:,:,1])
plt.subplot(121)
plt.imshow(img,cmap='gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(iimg,cmap='gray')
plt.title('iimg')
plt.axis('off')
plt.show()
总结
以前学习过数字图像处理,所以对基本的图像处理知识还算了解,这次学习主要是为了熟悉python语言、OpenCV语言。
用博客记录学习的方式,既可以督促自己,又可以为以后复习,这种形式可以继续。
下面开始认真做毕设,争取在中期检查前把系统构建出来,然后在查找文献,改进算法。