图像运算和图像增强四

图像运算和图像增强四

1.图像直方图理论知识和绘制实现

(1)图像直方图理论知识
灰度直方图是灰度级的函数,描述的是图像中每种灰度级像素的个数,反映图像中每种灰度出现的频率,可以通过归一化化为到(0,1)之间。
在这里插入图片描述
(2)OpenCV绘制直方图
使用calcHist()函数计算直方图,计算完成之后采用OpenCV中的绘制函数,如绘制矩形的rectangle()函数,绘制线段的line()函数来完成。

  • hist = cv2.calcHist(images, channels, mask, istSize,ranges, accumulate)
  • channels 表示指定通道,通道编号需要使用中括号,输入图像是灰度图像时,它的值为[0],彩色图像则为[0]、[1]、[2],分别表示蓝色(B)、绿色(G)、红色(R)
  • mask 表示可选的操作掩码。如果要统计整幅图像的直方图,则该值为 None;如果要统计图像的某一部分直方图时,需要掩码来计算
  • histSize 表示灰度级的个数,需要使用中括号,比如[256]
  • ranges 表示像素值范围,比如[0, 255]
  • accumulate 表示累计叠加标识,默认为 false,如果被设置为true,则直方图在开始分配时不会被清零,该参数允许从多个对象中计算单个直方图,或者用于实时更新直方图;多个直方图的累积结果用于对一组图像的直方图计算
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
#读取图像
src=cv2.imread('lena-hd.png')


#计算256灰度级的图像直方图
hist = cv2.calcHist([src], [0], None, [256], [0,255])


#输出直方图大小、形状、数量
print(hist.size)
print(hist.shape)
print(hist)
#设置字体
matplotlib.rcParams['font.sans-serif']=['SimHei']

#显示原始图像和绘制的直方图
plt.subplot(121)
plt.imshow(src, 'gray')
plt.axis('off')
plt.title("(a)Lena 灰度图像")

plt.subplot(122)
plt.plot(hist, color='r')
plt.xlabel("x")
plt.ylabel("y")
plt.title("(b)直方图曲线")
plt.show()
# 彩色图像绘制直方图
#读取图像
src = cv2.imread('lena.png')
#转换为 RGB 图像
img_rgb = cv2.cvtColor(src, cv2.COLOR_BGR2RGB)
#计算直方图
histb = cv2.calcHist([src], [0], None, [256], [0,255])
histg = cv2.calcHist([src], [1], None, [256], [0,255])
histr = cv2.calcHist([src], [2], None, [256], [0,255])
#设置字体
matplotlib.rcParams['font.sans-serif']=['SimHei']
#显示原始图像和绘制的直方图
plt.subplot(121)
plt.imshow(img_rgb, 'gray')
plt.axis('off')
plt.title("(a)Lena 原始图像")
plt.subplot(122)
plt.plot(histb, color='b')
plt.plot(histg, color='g')
plt.plot(histr, color='r')
plt.xlabel("x")
plt.ylabel("y")
plt.title("(b)直方图曲线")
plt.show()

在这里插入图片描述
(3)Matplotlib绘制直方图
Python 绘制直方图主要调用 matplotlib.pyplot 库中 hist()函数实现,它会根据数据源和像素级绘制直方图,通常需要通过
函数 ravel()拉直图像将图片转为一维

  • n, bins, patches = plt.hist(arr, bins=50, normed=1,
    facecolor=‘green’, alpha=0.75)
  • arr 表示需要计算直方图的一维数组
  • bins 表示直方图显示的柱数,可选项,默认值为 10
  • normed 表示是否将得到的直方图进行向量归一化处理,默认值为0
  • facecolor 表示直方图颜色
  • alpha 表示透明度
  • n 为返回值,表示直方图向量
  • bins 为返回值,表示各个 bin 的区间范围
  • patches 为返回值,表示返回每个 bin 里面包含的数据,是一个列表
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图像
src=cv2.imread('lena-hd.png')
#绘制直方图
plt.hist(src.ravel(),256)
plt.xlabel('x')
plt.ylable('y')
plt.show()

在这里插入图片描述

plt.hist(src.ravel(), bins=256, density=1, facecolor='green', alpha=0.75)

在这里插入图片描述

# 绘制彩色图像的彩色直方图(三维)
import cv2
import numpy as np
import matplotlib.pyplot as plt
src=cv2.imread('lena.png')
b,g,r=cv2.split(src)
#绘制直方图
plt.figure('lena')
#蓝色分量
plt.hist(b.ravel(),bins=256,density=1,facecolor='b',edgecolor='b',alpha=0.75)
#绿色分量
plt.hist(g.ravel(), bins=256, density=1, facecolor='g', edgecolor='g', alpha=0.75)
#红色分量
plt.hist(r.ravel(), bins=256, density=1, facecolor='r', edgecolor='r', alpha=0.75)
plt.xlable('x')
plt.ylable('y')

在这里插入图片描述

#绘制多张图片
import cv2 
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
src=cv2.imread('lena.png')
img_rgb=cv2.cvtColor(src,cv2.COLOR_BGR2RGB)
b,g,r=cv2.split(src)

plt.figure(figsize=(8,6))
matplotlib.rcParams['font.sans-serif']=['SimHei']

#原始图像
plt.subplot(221)
plt.imshow(img_rgb)
plt.axis('off')
plt.title('(a)原图像‘)
#绘制蓝色分量直方图
plt.subplot(222)
plt.hist(b.ravel(), bins=256, density=1, facecolor='b', edgecolor='b', alpha=0.75)
plt.xlabel("x")
plt.ylabel("y")
plt.title("(b)蓝色分量直方图")
#绘制绿色分量直方图
plt.subplot(223)
plt.hist(g.ravel(), bins=256, density=1, facecolor='g', edgecolor='g',alpha=0.75)
plt.xlabel("x")
plt.ylabel("y")
plt.title("(c)绿色分量直方图")
#绘制红色分量直方图
plt.subplot(224)
plt.hist(r.ravel(), bins=256, density=1, facecolor='r', edgecolor='r', alpha=0.75)
plt.xlabel("x")
plt.ylabel("y")
plt.title("(d)红色分量直方图")
plt.show()

在这里插入图片描述

2.图像灰度直方图对比分析

(1)灰度增强直方图对比
通过灰度值上移,提升图像的亮度

import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图像
img=cv2.imread('lena-hd.png')
#图像灰度转换
grayimage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#获取图像高度和宽度
height=grayimage.shape[0]
width=grayimage.shape[1]
result=np.zeros((height,width),np.uint8)
#图像灰度上移变换 DB=DA+50
for i in range(height):
	for j in range(width):
		if(int(grayimage[i,j]+50>255):
			gray=255
		else:
			gray=int(grayimage[i,j]+50)
		result[i,j]=np.uint8(gray)
#计算原图的直方图
hist=cv2.calcHist([img],[0],None,[256],[0,255])
#计算灰度变换的直方图
hist_res=cv2.calcHist([result],[0],None,[256],[0,255])

#原始图像
plt.figure(figsize=(8,6))
plt.subplot(221),plt.imshow(img,'gray'),plt.title('(a)),plt.axis('off')
#绘制掩膜
plt.subplot(222),plt.plot(hist),plt.title('(b)'),plt.xlable('x'),plt.ylable('y')
#绘制掩膜设置后的图像
plt.subplot(223),plt.imshow(result,'gray'),plt.title('(c)'),plt.axis('off')
#绘制直方图
plt.subplot(224),plt.plot(hist_res),plt.title('(d)'),plt.xlable('x'),plt.ylable('y')
plt.show()

在这里插入图片描述
(2)灰度减弱直方图对比DB=DA x 0.8

#核心代码展示
for i in range(height):
	for j in range(width):
		gray=int(grayimage[i,j]*0.8)
		result[i,j]=np.uint8(gray)

(3) 图像反色直方图对比DB=255-DA

#核心代码展示
for i in range(height):
	for j in range(width):
		gray=255-grayimage[i,j]
		result[i,j]=np.uint8(gray)

(4) 图像对数变换直方图对比
该算法将增加低灰度区域的对比度,从而增强暗部的细节,使用的表达式为:
DB = c x log(1+DA)

for i in range(height):
	for j in range(width):
		gray=42*np.log(1.0+grayimage[i,j])
		result[i,j]=np.uint8(gray)

(5)图像阈值化处理直方图对比
该算法原型为threshold(Gray,127,255,cv2.THRESH_BINARY),当前像素点的灰度值大于 thresh 阈值时(如 127),其像素点的灰度值设定为最大值(如 9 位灰度值最大为 255);否则,像素点的灰度值设置为 0。二进制阈值化处理及直方图对比的 Python 代码如下所示。

import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图片
img=cv2.imread('lena-hd.png')
#图像灰度转换
grayimage=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#二进制阈值化处理
r,result=cv2.threshold(grayimage,127,255,cv2.THRESH_BINARY)
#计算原图的直方图
hist=cv2.calcHist([img],[0],None,[256],[0,256])
#计算阈值化处理的直方图
hist_res=cv2.calcHist([result],[0],None,[256],[0,256])
#原始图像
plt.figure(figsize=(8,6))
plt.subplot(221),plt.imshow(img,'gray'),plt.title('(a)'),plt.axis('off')
#绘制原始图像直方图
plt.subplot(222),plt.plot(hist),plt.title('(b)'),plt.xlable('x'),plt.ylable('y')
#阈值化处理后的图像
plt.subplot(223),plt.imshow(result,'gray'),plt.title('(c)'),plt.axis('off')
#阈值化处理图像的直方图
plt.subplot(224),plt.plot(hist_res),plt.title('(d)'),plt.xlable('x'),plt.ylable('y')

plt.show()

在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值