常见的图像变换
直方图处理
基本概念
直方图
- 横坐标:图像中各个像素点的灰度级
- 纵坐标:具有该灰度级的像素个数
归一化直方图
- 横坐标:图像中各个像素点的灰度级
- 纵坐标:出现这个灰度级的概率
DIMS
:使用参数的数量
dims=1
:灰度直方图——仅考虑灰度的情况
BINS
:参数子集的数目
RANGE
:统计灰度值的范围
- 一般为[0, 255]
- 最小值:0——黑色
- 最大值:255——白色
使用matplotlib.pyplot
绘制直方图
- 导入:
import matplotlib.pyplot as plt
- 函数
hist
- 功能:根据数据源和像素级绘制直方图
- 语法:
hist(数据源, 像素级)
- 说明:
- 数据源:图像,必须是一维数组
- 像素级:一般是256,指[0, 255]
- 函数
ravel
- 功能:将多维数组降为一维数组
- 格式:
一维数组=多维数组.ravel()
使用cv2.calcHist()
获取8位图像的统计值(数组)
- 函数
hist=cv2.calcHist(images, channels, mask, histSize, ranges, accumulate)
hist
:直方图(二维数组)images
:原始图像channels
:指定通道- 通道编号需要用中括号括起来
- 输入图像是灰度图时,它的值是
[0]
- 彩色图像可以是
[0]
、[1]
、[2]
分别对应通道B、G、R
mask
:掩码图像- 统计整幅图像的直方图,设为
None
- 统计图像某一部分的直方图时,需要掩码图像
- 统计整幅图像的直方图,设为
histSize
:BINS的数量- 需要用中括号括起来
- 例如:
[256]
ranges
:像素值范围RANGEaccumulate
:累计(累计、叠加)标识- 默认值为false
- 如果被设置为true,则直方图在开始分配时不会被清零
- 该参数允许从多个对象中计算单个直方图,或者用于实时更新直方图
- 多个直方图的累积结果,用于对一组图像计算直方图
- 例:
hist=cv2.calcHist([img], [0], None, [256], [0,256])
绘制OpenCV统计直方图
- 函数
plt.plot
import cv2
import matplotlib.pyplot as plt
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg")
histb = cv2.calcHist([o], [0], None, [256], [0, 256])
histg = cv2.calcHist([o], [1], None, [256], [0, 256])
histr = cv2.calcHist([o], [2], None, [256], [0, 256])
plt.plot(histb, color='b')
plt.plot(histg, color='g')
plt.plot(histr, color='r')
plt.show()
效果:
使用掩模绘制直方图
- 效果
- 原理
- 操作小记1——掩模绘制
import cv2
import numpy as np
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
mask = np.zeros(o.shape, np.uint8)
mask[100:200, 100:200] = 255
mi = cv2.bitwise_and(o, mask)
cv2.imshow('ori', o)
cv2.imshow('mask', mask)
cv2.imshow('mi', mi)
cv2.waitKey()
cv2.destroyAllWindows()
效果
- 操作小记2——绘制直方图
import cv2
import numpy as np
import matplotlib.pyplot as plt
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", cv2.IMREAD_GRAYSCALE)
mask = np.zeros(o.shape, np.uint8)
mask[100:200, 100:200] = 255
histMI = cv2.calcHist([o], [0], mask, [256], [0, 255])
histO = cv2.calcHist([o], [0], None, [256], [0, 255])
plt.plot(histO)
plt.plot(histMI)
plt.show()
效果
直方图均衡化
直方图均衡化原理
- 效果
- 算法
- 计算累积直方图
- 将累计直方图进行区间转换
- 在累计直方图中,概率相近的原始值,会被处理维相同的值
- 应用场合
- 医疗图像处理
- 车牌识别
- 人脸识别
使用cv2.equalizeHist()实现直方图均衡化
-
语法:
dst = cv2.equalizeHist(src)
src
:源图像dst
:目标图像,处理结果
-
操作小记
import cv2
import matplotlib.pyplot as plt
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(o)
plt.hist(o.ravel(), 256)
plt.figure()
plt.hist(equ.ravel(), 256)
plt.show()
效果
图像金字塔
理论基础
- 图像金字塔:同一图像的不同分辨率的子图集合——获取:向下(上)取样
- 向下取样
- 原始图像 M*N --> 处理结果 M/2 *N/2
- 每次处理后,结果图像是原来的1/4
- 上述操作被称为:
Octave
- 无法复原
- 向上取样
- 无法复原
pyrUp
函数及使用
-
语法:
dst = cv2.pyrUp(src)
dst
:向上取样结果src
:原始图像
-
操作小记
import cv2
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", cv2.IMREAD_GRAYSCALE)
r = cv2.pyrUp(o)
r1 = cv2.pyrUp(r)
r2 = cv2.pyrUp(r1)
cv2.imshow("ori", o)
cv2.imshow("res1", r)
cv2.imshow("res2", r1)
cv2.imshow("res3", r2)
cv2.waitKey()
cv2.destroyAllWindows()
效果
pyrDown
函数及使用
-
语法:
dst = cv2.pyrDown(src)
dst
:向下取样结果src
:原始图像
-
操作小记
import cv2
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", cv2.IMREAD_GRAYSCALE)
r = cv2.pyrDown(o)
r1 = cv2.pyrDown(r)
r2 = cv2.pyrDown(r1)
cv2.imshow("ori", o)
cv2.imshow("res1", r)
cv2.imshow("res2", r1)
cv2.imshow("res3", r2)
cv2.waitKey()
cv2.destroyAllWindows()
取样可逆性研究
图像大小不变,能否恢复原图像呢?
操作小记
import cv2
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg")
down = cv2.pyrDown(o)
up = cv2.pyrDown(down)
diff = down - o ##查看差异
cv2.imshow("ori", o)
cv2.imshow("down", down)
cv2.imshow("up", up)
cv2.waitKey()
cv2.destroyAllWindows()
拉普拉斯金字塔
公式:Li = Gi - PyrUp(PyrDown(Gi))
- Gi:原始图像
- Li:拉普拉斯金字塔图像
相关资料中说明
- 说明:上箭头:向上取样;下箭头:向下取样
- 说明:图中g是进行高斯运算
操作小记
import cv2
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg")
od = cv2.pyrDown(o)
odu = cv2.pyrUp(od)
lapPyr = o - odu
cv2.imshow("ori", o)
cv2.imshow("lapPyr", lapPyr)
cv2.waitKey()
cv2.destroyAllWindows()
效果
说明:要得到第二层,只需重复操作即可
pyplot模块介绍
subplot
函数的使用
语法:subplot(nrows, ncols, plot_number)
- nrows
:行数
- ncols
:列数
- plot_number
:窗口序号
- 例子
- 若小于10,可以省略,
:subplot(234)
操作小记
import cv2
import matplotlib.pyplot as plt
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", cv2.IMREAD_GRAYSCALE)
equ = cv2.equalizeHist(o)
plt.subplot(1, 2, 1), plt.hist(o.ravel(), 256)
plt.subplot(1, 2, 2), plt.hist(equ.ravel(), 256)
plt.show()
效果
matplotlib.pyplot.imshow
函数的使用
语法:imshow(X, cmap=None)
X
:要绘制的图像cmap
:colormap,颜色图谱,默认为RGB(A)颜色空间- 灰度图像:
cmap=plt.cm.gray
- 彩色图像:如果使用opencv读入的图像,默认空间为BGR,需要调整色彩空间为RGB
- 灰度图像:
操作小记1
import cv2
import matplotlib.pyplot as plt
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg")
g = cv2.cvtColor(o, cv2.COLOR_BGR2GRAY)
plt.subplot(221), plt.imshow(o), plt.axis('off')
plt.subplot(222), plt.imshow(o, cmap=plt.cm.gray), plt.axis('off')
plt.subplot(223), plt.imshow(g), plt.axis('off')
plt.subplot(224), plt.imshow(g, cmap=plt.cm.gray), plt.axis('off') # right
plt.show()
效果
操作小记2
import cv2
import matplotlib.pyplot as plt
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg")
b, g, r = cv2.split(o)
o2 = cv2.merge([r, g, b])
plt.subplot(121), plt.imshow(o), plt.axis('off')
plt.subplot(122), plt.imshow(o2), plt.axis('off')
plt.show()
效果