一、问题与解决思路
图像实质上就是一个包含了许多像素点的矩阵。
具体计算过程如下:
- 通过min()函数以及max()函数分别求出处理前原图像的灰度级最小值与最大值;
- 对原图像进行归一化处理,即用【图像矩阵元素-处理前灰度级最小值】除以【处理前灰度级最大值-处理前灰度级最小值】;
- 将图像灰度级放缩至我们指定的预期期间,即用【处理后的灰度级最小值】加上“ 【步骤3中归一化处理后的结果】乘以【处理后的灰度级最大值-处理后的灰度级最小值】 ”;
- 将处理后的图像转为uint8类型以便于正确显示。
二、Python 实现代码
1) 核心函数:
from PIL import Image
from pylab import *
# 自定义图像对比度拉伸函数 myGrayScaleTransformJ
def myGrayScaleTransformJ(img1, para):
# 若输入不合法,返回原图像
if (para[0] < 0 or para[1] > 255 or para[0] > para[1]):
img2 = Image.fromarray(uint8(img1))
return img2
# min_after,max_after 分别表示拉伸后灰度级区间的最小值与最大值
min_after = para[0]
max_after = para[1]
# min_before,max_before 分别表示处理前灰度级区间的最小值与最大值
min_before = img1.min()
max_before = img1.max()
# 1、将处理前的图像灰度级进行归一化处理
temp = (img1 - min_before) / (max_before - min_before)
# 2、将图像的灰度级放缩至我们指定的预期区间
img2 = min_after + (temp * (max_after - min_after))
# 3、转成uint8 类型以便正确显示
img2 = Image.fromarray(uint8(img2))
return img2
2) 主函数:
from PIL import Image
from pylab import *
import matplotlib.pyplot as plt
import MyModule
# 以下两行代码解决图片标题中文乱码问题
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
img = Image.open("EXP1A.tif").convert("RGB") # 读入图像 .convert("RGB")解决灰度图像失真问题
plt.subplot(121) # 划分为1行2列,先画左边第一个
plt.axis('off')
plt.title('原图像')
plt.imshow(img) # 画出原图像
imgArr = array(Image.open("EXP1A.tif").convert("RGB")) # 读入图像并转为数组
# 读入para数组,即预期拉伸的灰度级区间范围,para1为最小值,para2为最大值
print ("请分别输入预期拉伸的灰度级区间范围的最小值与最大值(空格隔开):")
arr = input("")
para = [int(n) for n in arr.split()]
enhancedImg = MyModule.myGrayScaleTransformJ(imgArr, para) # 调用自定义函数进行线性拉伸
plt.subplot(122)
plt.axis('off')
plt.title('处理后')
plt.imshow(enhancedImg) # 画出处理后的图像
plt.show()
注意点:
使用 Python 进行图像处理需导入第三方依赖,而 Matlab 则可以直接调用官方的工具包
from PIL import Image
上方语句中的 PIL 用于完成图像的基本处理,如读取图像到程序中,默认为 uint8 类型
from pylab import *
需导入上方依赖才能将图像转换为数组
三、Matlab 实现代码
1) 核心函数
% img1:处理前的灰度图像;img2:处理后的灰度图像
% para(1)表示拉伸后灰度级区间的最小值
% para(2)表示拉伸后灰度级区间的最大值
function img2 = myGrayScaleTransformJ(img1,para)
% 若输入不合法,则返回原图像
if (para(1)<0 || para(2)>255 || para(1)>para(2))
img2 = img1;
return;
end
img1 = double(img1);
% min_after,max_after分别表示拉伸后灰度级区间的最小值与最大值
min_after = para(1);
max_after = para(2);
% min_before,max_before分别表示处理前灰度级区间的最小值与最大值
min_before = min(img1(:));
max_before = max(img1(:));
% 1、将处理前的图像灰度级进行归一化处理
temp = (img1 - min_before) ./ (max_before - min_before);
% 2、将图像的灰度级放缩至我们指定的预期区间
img2 = min_after + temp .* (max_after - min_after);
% 转成uint8类型以便正确显示
img2 = uint8(img2);
end
2) 主函数:
clc;
clear all;
img1 = imread('EXP1A.tif');
% 画出原来的图像
subplot(2,2,1);
imshow(img1);
title('A:raw img');
% 输入数据并调用函数
min = input('请输入拉伸后的灰度级最小值:');
max = input('请输入拉伸后的灰度级最大值:');
para = [min, max];
img2 = myGrayScaleTransformJ(img1, para);
% 画出将对比度线性拉伸后的图像
subplot(2,2,2);
imshow(img2);
title('A:enhanced img');
3) 运行效果: