Python中的直方图绘图和拉伸(不使用内置函数)
先决条件:使用直方图分析图像的 OpenCV Python程序
强度水平在 0 到 L-1 范围内的数字图像的直方图是一个离散函数-
h(rk) = nk
where rk = kth intensity value
and no = number of pixels in the image with rk intensity value.
如果图像有 M 行 N 列,则图像中的像素总数为 MN。得到归一化直方图如下:
p(rk) = nk/MN
有时,如果图像是深色、浅色或低对比度,则该图像的直方图可能没有分别具有最小强度 (0) 或最大强度 (255) 或两者的像素。在这种情况下,可以通过应用以下变换来拉伸该图像的直方图。
Let a= maximum intensity level in the image
Let b= minimum intensity level in the image
Let rk= pixel value in the original image
Let sk= pixel value in the stretched image
constant= (255-0)/(a-b)
Then
sk= constant*rk
直方图绘制算法
- 阅读图片
- 获取图像的大小。让 m=rows 和 n=columns
- 对于所有强度级别 rk= 0 到 255
- 遍历所有行'm'和列'n'
- 计算每个强度级别的像素数
- 绘制强度值与每个强度值中像素数的关系图
拉伸直方图的算法
- 找到图像中的最小强度值说'a'和最大强度值说'b'
- 获得一个常数 c= (255-0)/(ab)
- 将此常数与图像中的每个像素相乘以获得直方图拉伸。
观察
可以观察到,在对比度拉伸后,暗输入图像得到改善。
下面是实现。
输入图像:
# import cv2, numpy, matplotlib
import cv2
import numpy as np
import matplotlib.pyplot as plt
# function to obtain histogram of an image
def hist_plot(img):
# empty list to store the count
# of each intensity value
count =[]
# empty list to store intensity
# value
r = []
# loop to traverse each intensity
# value
for k in range(0, 256):
r.append(k)
count1 = 0
# loops to traverse each pixel in
# the image
for i in range(m):
for j in range(n):
if img[i, j]== k:
count1+= 1
count.append(count1)
return (r, count)
img = cv2.imread('food.jpeg', 0)
# To ascertain total numbers of rows and
# columns of the image, size of the image
m, n = img.shape
r1, count1 = hist_plot(img)
# plotting the histogram
plt.stem(r1, count1)
plt.xlabel('intensity value')
plt.ylabel('number of pixels')
plt.title('Histogram of the original image')
# Transformation to obtain stretching
constant = (255-0)/(img.max()-img.min())
img_stretch = img * constant
r, count = hist_plot(img_stretch)
# plotting the histogram
plt.stem(r, count)
plt.xlabel('intensity value')
plt.ylabel('number of pixels')
plt.title('Histogram of the stretched image')
# Storing stretched Image
cv2.imwrite('Stretched Image 4.png', img_stretch)
输出: