Python+OpenCV学习笔记

此次学习的是csdn学院中《Python+OpenCV计算机视觉》,比较基础,适合初学者。

第一次尝试以博客形式来记录学习笔记,督促自己,提升自我,供自己和大家学习。


目录

图像的读取、显示和保存

图像处理基础

图像运算

类型转换

几何变换

图像阈值

图像平滑处理

形态学处理

图像梯度

Canny边缘检测

图像金字塔

图像轮廓

直方图

傅里叶变换

总结


图像的读取、显示和保存

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属性:
  • Python+OpenCV学习笔记_第1张图片

范例:

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算子

  • Python+OpenCV学习笔记_第2张图片
  • 函数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)


#
#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语言。

用博客记录学习的方式,既可以督促自己,又可以为以后复习,这种形式可以继续。

下面开始认真做毕设,争取在中期检查前把系统构建出来,然后在查找文献,改进算法。

你可能感兴趣的:(Python+OpenCV学习笔记)