永兴的笔记-OpenCV-7图像直方图 2 直方图均衡化、图像掩膜 、图像归一化、直方图的反向投影

在这里插入图片描述

一、直方图均衡化:

1、什么是直方图均衡化:

直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法。

  • 对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,差异范围越大代表对比越大,差异范围越小代表对比越小,好的对比率120:1就可容易地显示生动、丰富的色彩,当对比率高达300:1时,便可支持各阶的颜色。
    对比度也就是画面黑与白的比值,也就是从黑到白的渐变层次。比值越大,从黑到白的渐变层次就越多,从而色彩表现越丰富。对比度对视觉效果的影响非常关键,一般来说对比度越大,图像越清晰醒目,色彩也越鲜明艳丽;而对比度小,则会让整个画面都灰蒙蒙的。
  • 一般情况下直方图均衡化要做的就是让直方图尽可能地均匀分布在0~255内。

2、直方图均衡化的作用:

  • 这种方法通常用来增加许多图像的全局对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。
  • 这种方法对于背景和前景都太亮或者太暗的图像非常有用,这种方法尤其是可以带来X光图像中更好的骨骼结构显示以及曝光过度或者曝光不足照片中更好的细节。这种方法的一个主要优势是它是一个相当直观的技术并且是可逆操作,如果已知均衡化函数,那么就可以恢复原始的直方图,并且计算量也不大。这种方法的一个缺点是它对处理的数据不加选择,它可能会增加背景噪声的对比度并且降低有用信号的对比度。

3、使用直方图均衡化:
cv2.equalizeHist(src, dst=None)

  • src 原图像
import cv2
img = cv2.imread("equalize.png",0)
equalize = cv2.equalizeHist(img)
cv2.imshow("equalize",equalize)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

二、图像掩膜:

1、什么是图像掩膜?

  • 在半导体制造中,许多芯片工艺步骤采用光刻技术,“底片”称为掩膜(也称作“掩模”),其作用是:在硅片上选定的区域中对一个不透明的图形模板遮盖,继而下面的腐蚀或扩散将只影响选定的区域以外的区域。
  • 图像掩膜与其类似,用选定的图像、图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。

2、图像掩膜有哪些作用?
用选定的图像、图形或物体,对待处理的图像(局部或全部)进行遮挡来控制图像处理的区域或处理过程。掩模本质上为二维矩阵数组,图像掩模主要用于:

  • 提取感兴趣区:用预先制作的感兴趣区掩膜与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0;
  • 屏蔽作用:用掩膜对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计;
  • 结构特征提取:用相似性变量或图像匹配方法检测和提取图像中与掩膜相似的结构特征;
  • 特殊形状图像的制作
  • 掩膜就是两幅图像之间进行的各种位运算操作(简单了解)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

3、如何使用掩膜:
绘制多边形:
cv2.polylines(img, pts, isClosed, color, thickness=None, lineType=None, shift=None)
在这里插入图片描述
任意形状填充:
cv2.fillPoly(img, pts, color, lineType=None, shift=None, offset=None)

  • img : 原图像
  • pts :多维数组
  • color :边框颜色
  • lineType: 线的类型
  • shift :线的类型
  • offset : 所有点的偏移量

获取指定形状和尺寸的结构元素:
cv2.getStructuringElement(shape, ksize, anchor=None)

  • shape:形状
shape 形状
MORPH_RECT 矩形
MORPH_CROSS 十字形
MORPH_ELLIPSE 椭圆形
  • ksize:大小
  • anchor:锚点的位置,默认值Point(-1,-1),表示锚点位于中心点

调整窗口大小:
namedWindow(winname, flags=None)

  • winname : 窗口名
  • flags:模式
flags 模式效果
cv2.WINDOW_NORMAL 窗口大小可改变
cv2.WINDOW_AUTOSIZE 窗口大小不可改变
cv2.WINDOW_FREERATIO 自适应比例
cv2.WINDOW_KEEPRATIO 保持比例

在这里插入图片描述
与操作:
cv2.bitwise_and()是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=1,1&0=0,0&1=0,0&0=0

或操作:
cv2.bitwise_or()是对二进制数据进行“或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1|1=1,1|0=1,0|1=1,0|0=0

#非运算,非0为1, 非1为0
bitwiseNot = cv2.bitwise_not(circle)

#异或运算,不同为1, 相同为0
bitwiseXor = cv2.bitwise_xor(rectangle, circle)

import numpy as np
import cv2
image = cv2.imread("first.jpg")  # 读图
# 输入图像是RGB图像,故构造一个三维数组,四个二维数组是mask四个点的坐标,
site = np.array([[[600, 400], [350, 400], [150, 5], [400, 5]]], dtype=np.int32)
im = np.zeros(image.shape[:2], dtype="uint8")  # 生成image大小的全黑图
cv2.polylines(image, site, 1, 255)  # 在image上画site大小的线,1表示线段闭合,255表示线段颜色
cv2.fillPoly(im, site, 255)  # 在im的site区域,填充颜色为255
mask = im
cv2.namedWindow('Mask', cv2.WINDOW_NORMAL)  # 可调整窗口大小,不加这句不可调整
cv2.imshow("Mask", mask)
masked = cv2.bitwise_and(image, image, mask=mask)  # 在模板mask上,将image和image做“与”操作
cv2.namedWindow('Mask to Image', cv2.WINDOW_NORMAL)  # 同上
cv2.imshow("Mask to Image", masked)
cv2.imshow("Oringinal", image) #显示原图
cv2.waitKey(0)  # 图像一直显示,键盘按任意键即可关闭窗口
cv2.destroyAllWindows()

在这里插入图片描述

三、图像归一化:

1、什么是图像归一化?

  • 图像归一化是指对图像进行了一系列标准的处理变换,使之变换为一固定标准形式的过程,该标准图像称作归一化图像。

2、为什么要图像归一化?

  • 原始图像在经历一些处理或攻击后可以得到多种副本图像,这些图像在经过相同参数的图像归一化处理后能够得到相同形式的标准图像。

3、使用图像归一化:
cv2.normalize(src, dst, alpha=None, beta=None, norm_type=None, dtype=None, mask=None)

  • src: 原图像
  • dst: 输出图像
  • alpha: 较低的范围边界(下边界)
  • bate:较高的范围边界(上边界)不用于norm normalization(范数归一化)模式。
  • norm_type: 归一化类型
type 描述
NORM_MINMAX 数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用
NORM_INF 归一化数组的C-范数(绝对值的最大值)
NORM_L1 归一化数组的L1-范数(绝对值的和)
NORM_L2 归一化数组的(欧几里德)L2-范数
  • dtype: dtype为负数时,输出数组的type与输入数组的type相同 (一般为uint8)
  • mask: 图像掩膜

四、直方图的反向投影:

1、什么是直方图的反向投影?

  • 实际上是将图像的256个灰度值 置为 很少的几个值了,具体有几个值,要看把0~255划分为多少个区间!反向投影中某点的值就是它对应的原图像中的点所在区间的灰度直方图值。所以,一个区间点越多,在反向投影矩阵中就越亮。
  • 反向投影中的“反向”指的是从直方图值到反向投影矩阵映射的过程。

2、反向投影的作用是什么?

  • 通过反向投影,原始的图像被简化了,而这个简化的过程实际上就是提取出图像的某个特征。所以我们就可以用这个特征来对比两幅图,如果两幅图的反向投影矩阵相似或相同,那么我们就可以判定这两幅图这个特征是相同的。
  • 反向投影可以用来做图像分割,或寻找感兴趣区间。它会输出与输入图像大小相同的图像,每一个像素值代表了输入图像上对应点属于目标对象的概率,简言之,输出图像中像素值越高(越白))的点越可能代表想要查找的目标(在输入图像所在的位置)。

3、使用反向投影:
反向投影前一般需要使用一次归一化,以保证反向投影的效果。
cv2.calcBackProject(images, channels, hist, ranges, scale, dst=None)

  • images: 输入的图像
  • channels: 需要计算的通道数
  • hist: 输入的直方图
  • scale:输出反向投影的比例因子(一般为1)
  • dst :输出图像

BGR:

import cv2
import matplotlib.pyplot as plt
imgBack = None
img = cv2.imread("first.jpg")
cv2.normalize(img,img,0,255,cv2.NORM_MINMAX) #归一化
for i in range(img.shape[-1]):
    imgHist = cv2.calcHist([img], [i],None,[256],[0,256]) #计算直方图
    plt.plot(imgHist),plt.title("imgHist")
    imgBack = cv2.calcBackProject([img],[i],imgHist,[0,180,0,256],1)  #计算反向投影
plt.show()
cv2.imshow("Back",imgBack)
cv2.imshow("img",img)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述
HSV:

import cv2
import matplotlib.pyplot as plt
imgBack = None
img = cv2.imread("first.jpg")
SHVImg = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
#cv2.normalize(img,img,0,255,cv2.NORM_MINMAX) #归一化
for i in range(SHVImg.shape[-1]):
    imgHist = cv2.calcHist([SHVImg], [i],None,[256],[0,256]) #计算直方图
    plt.plot(imgHist),plt.title("imgHist")
    imgBack = cv2.calcBackProject([SHVImg],[i],imgHist,[0,180,0,256],1)  #计算反向投影
plt.show()
cv2.imshow("Back",imgBack)
cv2.imshow("img",SHVImg)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

练习题 7.2
利用mask,绘制最喜欢的人物的照片的头部的直方图,并显示原图 和 头部的反向投影

评论出你的答案

发布了45 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/m0_43505377/article/details/103809291