计算机视觉:基于Numpy的图像处理技术(一):灰度变换、直方图均衡化

计算机视觉:基于Numpy的图像处理技术(一)灰度变换、直方图均衡化(一)️‍

文章目录

  • 计算机视觉:基于Numpy的图像处理技术(一)灰度变换、直方图均衡化(一):rainbow_flag:
    • 一、Numpy操作图像数组:triangular_ruler:
    • 二、灰度变换:ghost:
    • 三、直方图均衡化:link:
      • 1、概念
      • 2、导包
      • 3、图像直方图均衡化(非numpy方法)
      • 4、图像直方图均衡化(numpy方法)

​ 在这里我将以分辨率为590*326的图片hua.jpg来作为演示图片,如下图,是一个拿着战矛的机甲风人物。为了方便下面我将其称为“小花”

计算机视觉:基于Numpy的图像处理技术(一):灰度变换、直方图均衡化_第1张图片

一、Numpy操作图像数组

​ 将图像读入Numpy的数组对象后,可以对其进行数学操作。

​ 首先导入必备的numpy和cv2

import numpy as np
import cv2
#读取图片
pic = cv2.imread('hua.jpg')
#使用numpy中的array方法将图片以数组形式读取
arr = np.array(data)
#读取图片的shape值(为一个元组)
pic_shape = arr.shape
print(arr)
print(pic_shape)

​ 运行后可以看到图片小花的矩阵和它的形状(326, 590, 3),shape为一个数组

其中326为图像的宽度,590为图像的长度,3代表这个图像有三个通道RGB

二、灰度变换

from PIL import Image
import numpy as np
pic_arrL = np.array(Image.open('hua.jpg').convert('L'))
print(pic_arrL)

convert('L') 为灰度图像,每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。

原型
[[[41 23 46]
  [41 23 46]
  [41 23 46]
  ...
  [37 10 30]
  [37 10 30]
  [37 10 30]]

 [[40 22 45]
  [40 22 45]
  [40 22 45]
  ...
灰度处理后
[[32 32 32 ... 19 19 19]
 [31 31 31 ... 19 19 19]
 [31 31 31 ... 19 19 19]
 ...
 [18 18 18 ... 11 11 11]
 [18 18 18 ... 11 11 11]
 [18 18 19 ... 11 11 11]]

​ 设任意函数f,它将0~255映射到自身(输出区间和输入区间相同)那么对载入的图像实现不同级别的灰度变换则可以通过设定函数f来进行实现

from PIL import Image
import numpy as np
from pylab import *

# 灰度图像
# f(x) = 255 - x
pic_arrL = np.array(Image.open('hua.jpg').convert('L'))
# 输出最大最小值以确定图像像素范围
print('对图像进行反向处理:\n', int(pic_arrL.min()),int(pic_arrL.max()))

# f(x) = (100/255)x + 100
im1 = (100.0/255) *pic_arrL +100 # 将图像想阻止控制在100~200
print('将图像像素值变换到100...200区间:\n', int(im1.min()),int(im1.max()))

# f(x) = 255*(x/255)^2
im2 = 255.0 * (pic_arrL/255.0) ** 2 # 对像素值求平方后得到的图像
print('对像素值求平方后得到的图像:\n', int(im2.min()),int(im2.max()))

# 图像展示
# pic_arrL
figure()
gray()
subplot(131)
imshow(pic_arrL)
axis('off')
title(r'$f(x) = 255 - x$')
# im1
subplot(132)
imshow(im1)
axis('off')
title(r'$f(x) = \frac{100}{255}x + 100 $')
# im2
subplot(133)
imshow(im2)
axis('off')
title(r'$f(x) = 255(\frac{x}{255})^2 $')
show()

​ 定义完公式后对图像进行运算,最终通过 pylab 库的方法将图像展示,其中title利用latex语法进行公式的呈现。如下图,将小花不同程度的灰度图展现了出来。

计算机视觉:基于Numpy的图像处理技术(一):灰度变换、直方图均衡化_第2张图片

三、直方图均衡化

1、概念

​ 指将一副图像的灰度直方图变平,使得变换后的图像中每个灰度值的分布概率都相同。

​ 作用:将灰度值归一化;可以增强图像的对比度。

2、导包

​ 首先需要导入的工具包有

  • PIL
  • pylab
  • PCV
  • matplotlib

​ 其中PCV导入时若遇到导入后不能使用的问题,则需进入其github官网进行下载 https://github.com/jesolem/PCV ,如github速度很慢可以使用csdn的gitcode镜像进入。

注意:不使用PCV来进行图像直方图均衡化请往下看

mirrors / jesolem / pcv · GitCode

计算机视觉:基于Numpy的图像处理技术(一):灰度变换、直方图均衡化_第3张图片

在PCV目录下打开终端输入命令:python setup.py install

结果会发现报错,原因在于有很多文件中有着python2版本中的print,需将其改为python3的格式(加一对小括号)

计算机视觉:基于Numpy的图像处理技术(一):灰度变换、直方图均衡化_第4张图片

如图如果在pycharm中运行可以直接点进文件链接进行跳转,并修改。例如此条:

计算机视觉:基于Numpy的图像处理技术(一):灰度变换、直方图均衡化_第5张图片

改为如下

print (imname + "...skipped" )

3、图像直方图均衡化(非numpy方法)

​ 但是由于PCV这个包已经八九年没有更新了,对于python3来说属实不太友好,这里采用自己定义好的直方图均衡化的函数

from PIL import Image
from pylab import *
# 添加中文字体支持
plt.rcParams['font.sans-serif'] = ['SimHei']
hua = array(Image.open('hua.jpg').convert('L'))


def histeq(im,nbr_bins=256):
    """对一副灰度图像进行直方图均衡化"""
    imhist,bins = histogram(im.flatten(),nbr_bins,normed = True)
    # 累计分布函数
    cdf = imhist.cumsum()
    # 归一化(概率分布)
    cdf = 255*cdf/cdf[-1]
    # 线性插值
    im2 =interp(im.flatten(),bins[:-1],cdf)
    return im2.reshape(im.shape),cdf


im2,cdf = histeq(hua,256)
figure()
subplot(2,2,1)
axis('off')
gray()
title(u'原始图像')
imshow(hua)

subplot(2,2,2)
axis('off')
gray()
title(u'直方图均衡化后图像')
imshow(im2)

subplot(2,2,3)
axis('off')
title(u'原始直方图')
hist(hua.flatten(),128,density=True)

subplot(2,2,4)
axis('off')
title(u'均衡化后的直方图')
hist(im2.flatten(),128,density=True)
show()

​ 运行程序效果如下,小花的原始的图像直方图为“左高右低”。均衡化处理过后小花的图像直方图的分布变得平均了

计算机视觉:基于Numpy的图像处理技术(一):灰度变换、直方图均衡化_第6张图片

4、图像直方图均衡化(numpy方法)

import cv2 as cv
import numpy as np

# 图像显示
def picShow(pic_title, pic_data):
    cv.imshow(pic_title, pic_data)
    cv.waitKey(0)
    cv.destroyAllWindows()


def pixGray(img):  # 直方图统计
    h = img.shape[0]
    w = img.shape[1]

    gray_level = np.zeros(256)
    gray_level2 = np.zeros(256)

    for i in range(1, h - 1):
        for j in range(1, w - 1):
            gray_level[img[i, j]] += 1  # 统计灰度级为img_gray[i,j]的个数

    for i in range(1, 256):
        gray_level2[i] = gray_level2[i - 1] + gray_level[i]  # 统计灰度级小于img_gray[i,j]的个数
    return gray_level2


def imgEqualize(img):  # 直方图均衡化
    h, w = img.shape
    gray_level2 = pixGray(img)
    lut = np.zeros(256)
    for i in range(256):
        lut[i] = 255.0 / (h * w) * gray_level2[i]  # 得到新的灰度级
    lut = np.uint8(lut + 0.5)
    out = cv.LUT(img, lut)
    print('图像直方图均衡化 处理完毕')
    return out


if __name__ == "__main__":
    pic = cv.imread('hua.jpg', 0)
    title = 'mulan'
    picture = np.hstack((pic, imgEqualize(pic)))
    picShow(title, picture)

运行结果如图:

计算机视觉:基于Numpy的图像处理技术(一):灰度变换、直方图均衡化_第7张图片

你可能感兴趣的:(Python,计算机视觉,numpy,图像处理)