Python计算机视觉第一章-基本的图像操作和处理

2024-08-26 13:12

本文主要是介绍Python计算机视觉第一章-基本的图像操作和处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1.1 PIL:Python图像处理类库

1.1.1 转换图像格式

1.1.2 创建缩略图

1.1.3 复制和粘贴图像区域

1.1.4 调整尺寸和旋转

1.2 Matplotlib

1.2.1 绘制图像、点和线

1.2.2 图像轮廓和直方图 

1.2.3 交互式标注

1.3 NumPy

1.3.1 图像数组表示

1.3.2 灰度变换

1.3.3 图像缩放

1.3.4 直方图均衡化

1.3.5 图像平均

1.3.6 图像的主成分分析(PCA)

1.3.7 使用pickle模块

1.4 SciPy        

1.4.1 图像模糊

1.4.2 图像导数       

1.4.3 形态学:对象计数

1.5 高级示例:图像去噪


1.1 PILPython图像处理类库

        PILPython Imaging Library Python,图像处理类库)提供了通用的图像处理功能

1.1.1 转换图像格式

      如图所示在运行转化格式代码前,图片格式为bmp

from PIL import Image
import os
filelist = ['1.bmp']for infile in filelist:outfile = os.path.splitext(infile)[0] + ".jpg"if infile != outfile:try:Image.open(infile).save(outfile)except IOError:print("cannot convert", infile)

        紧接着运行次代码发现生成了额外的一个jpg格式的图片:

                

下面将返回目录中所有 JPG 图像的文件名列表,如图1.jpg被返回显示:

import os
def get_imlist(path):""" 返回目录中所有 JPG 图像的文件名列表 """return [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.jpg')]
directory_path = 'C:\\Users\\86156\\PycharmProjects\\pythonProject\\qushuiyin\\python'
jpg_files = get_imlist(directory_path)
print(jpg_files)

1.1.2 创建缩略图

        使用thumbnail() 方法创建缩略图:

from PIL import Image# 打开原始图像
pil_im = Image.open('1.jpg')# 创建最长边为 128 像素的缩略图
pil_im.thumbnail((128, 128))# 保存或显示缩略图
pil_im.save('thumbnail_example.jpg')

        生成缩略图如图所示:

1.1.3 复制和粘贴图像区域

  1. 打开名为1.jpg 的图像。
  2. 裁剪出一个从 (100, 100) 到 (400, 400) 的区域。
  3. 将裁剪出的区域旋转 180 度。
  4. 将旋转后的区域放回原图像的相同位置。
  5. 将修改后的图像保存为 modified_image.jpg
from PIL import Image# 打开图像文件
pil_im = Image.open('1.jpg')# 定义裁剪区域
box = (100, 100, 400, 400)# 裁剪图像区域
region = pil_im.crop(box)# 旋转裁剪出的区域 180 度
region = region.transpose(Image.ROTATE_180)# 将旋转后的区域放回原图像
pil_im.paste(region, box)# 保存修改后的图像
pil_im.save('modified_image.jpg')

得到变换后的图像为:

        

1.1.4 调整尺寸和旋转

        如下是使用 resize()rotate() 方法来调整图像的尺寸和旋转图像:

from PIL import Image# 打开图像文件
pil_im = Image.open('1.jpg')# 调整图像的尺寸
# 将图像大小调整为 128x128 像素
resized_image = pil_im.resize((128, 128))# 保存调整大小后的图像
resized_image.save('resized_image.jpg')# 旋转图像
# 将图像逆时针旋转 45 度
rotated_image = pil_im.rotate(45)# 保存旋转后的图像
rotated_image.save('rotated_image.jpg')
'resized_image.jpg'为调整大小后的图像:

rotated_image.jpg为旋转后的图像:

1.2 Matplotlib

        Matplotlib是个很好的类库,具有比 PIL 更强大的绘图功能。

1.2.1 绘制图像点和线

        下面是用几个点和一条线绘制图像的例子:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt# 读取图像到数组中
im = np.array(Image.open('1.jpg'))# 创建一个新的图形窗口
plt.figure()# 绘制图像
plt.imshow(im)# 定义一些点的坐标
x = [100, 100, 400, 400]
y = [200, 500, 200, 500]# 使用红色星状标记绘制点
plt.plot(x, y, 'r*', markersize=10, label='Points')# 绘制连接前两个点的线
plt.plot(x[:2], y[:2], 'b-', label='Line between first two points')# 添加标题
plt.title('Plotting: "empire.jpg"')# 添加图例
plt.legend()# 显示绘制的图像和点
plt.show()

绘制后的图像为:

1.2.2 图像轮廓和直方图 

        绘制图像的轮廓(或者其他 二维函数的等轮廓线。因为绘制轮廓需要对每个坐标 [x, y] 的像素值施加同一个阈值,所以首先需要将图像灰度化:

from PIL import Image
from pylab import *# 读取图像并转换为灰度图像
im = array(Image.open('1.jpg').convert('L'))# 创建图像窗口并绘制轮廓图像
figure()
gray()
contour(im, origin='image')
axis('equal')
axis('off')# 显示图像
show()
figure()
hist(im.flatten(),128)
show()

 轮廓化后的图片:

直方图:

1.2.3 交互式标注

        有时用户需要和某些应用交互,例如在一幅图像中标记一些点,或者标注一些训练 数据。PyLab 库中的 ginput() 函数就可以实现交互式标注。

from PIL import Image
from matplotlib import pyplot as plt# 读取图像
im = Image.open('empire.jpg')# 创建图像窗口并显示图像
plt.imshow(im)
plt.title('Please click 3 points')# 交互式标注
points = plt.ginput(3)# 显示点击的坐标
print('You clicked:', points)# 显示图像窗口
plt.show()

生成图像为:

1.3 NumPy

        NumPy是非常有名的 Python 科学计算工具包,其中 包含了大量有用的思想,比如数组对象(用来表示向量、矩阵、图像等)以及线性 代数函数。

1.3.1 图像数组表示

        当载入图像时,我们通过调用 array() 方法将图像转换成 NumPy 的数组对象。

from PIL import Image
import numpy as np# 读取图像并转换为NumPy数组
im = np.array(Image.open('empire.jpg'))
print('Original image shape:', im.shape, 'Data type:', im.dtype)# 将图像转换为灰度并设置数据类型为float32
im_gray = np.array(Image.open('empire.jpg').convert('L'), dtype='float32')
print('Grayscale image shape:', im_gray.shape, 'Data type:', im_gray.dtype)

结果:

1.3.2 灰度变换

        将图像读入 NumPy 数组对象后,我们可以对它们执行任意数学操作。一个简单的例子就是图像的灰度变换。

        

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt# 读取图像并转换为灰度图像的NumPy数组
im = np.array(Image.open('empire.jpg').convert('L'))# 反相处理
im2 = 255 - im# 将图像像素值变换到 100 到 200 区间
im3 = (100.0/255) * im + 100# 对图像像素值进行平方变换
im4 = 255.0 * (im / 255.0) ** 2# 显示原始图像及其变换结果
plt.figure(figsize=(12, 8))plt.subplot(2, 2, 1)
plt.imshow(im, cmap='gray')
plt.title('Original Image')
plt.axis('off')plt.subplot(2, 2, 2)
plt.imshow(im2, cmap='gray')
plt.title('Inverted Image')
plt.axis('off')plt.subplot(2, 2, 3)
plt.imshow(im3, cmap='gray')
plt.title('Scaled Image (100 to 200)')
plt.axis('off')plt.subplot(2, 2, 4)
plt.imshow(im4, cmap='gray')
plt.title('Squared Image')
plt.axis('off')plt.tight_layout()
plt.show()

结果:

1.3.3 图像缩放

        写一个简单的用于图像缩放的函数。把下面的函数添加到 imtool.py 文件里:

def imresize(im,sz):
        """ 使用 PIL 对象重新定义图像数组的大小 """
        pil_im = Image.fromarray(uint8(im))
        return array(pil_im.resize(sz))

1.3.4 直方图均衡化

        图像灰度变换中一个非常有用的例子就是直方图均衡化。直方图均衡化的变换函数是图像中像素值的累积分布函数。

首先定义累积分布函数cdf:

import numpy as npdef histeq(im, nbr_bins=256):"""对一幅灰度图像进行直方图均衡化:param im: 输入的灰度图像(二维NumPy数组):param nbr_bins: 直方图中的小区间数目,默认为256:return: 直方图均衡化后的图像和累积分布函数"""# 计算图像的直方图imhist, bins = np.histogram(im.flatten(), nbr_bins, density=True)cdf = imhist.cumsum()  # 累积分布函数cdf = 255 * cdf / cdf[-1]  # 归一化到0-255范围# 使用累积分布函数的线性插值,计算新的像素值im2 = np.interp(im.flatten(), bins[:-1], cdf)return im2.reshape(im.shape), cdf

随后引用函数对图像进行直方图均衡化:

from PIL import Image
import numpy as np
import imtools  # 确保该模块在Python路径中# 加载图像并转换为灰度图像的NumPy数组
im = np.array(Image.open('AquaTermi_lowcontrast.jpg').convert('L'))# 使用直方图均衡化函数
im2, cdf = imtools.histeq(im)# 可以使用matplotlib显示结果
import matplotlib.pyplot as pltplt.figure(figsize=(12, 6))plt.subplot(1, 2, 1)
plt.imshow(im, cmap='gray')
plt.title('Original Image')
plt.axis('off')plt.subplot(1, 2, 2)
plt.imshow(im2, cmap='gray')
plt.title('Equalized Image')
plt.axis('off')plt.show()

结果:

1.3.5 图像平均

        图像平均操作是减少图像噪声的一种简单方式,通常用于艺术特效。下面的函数可以用于计算平均图像,将其添加到 imtool.py 文件里:

def compute_average(imlist):"""计算图像列表的平均图像:param imlist: 包含图像文件路径的列表:return: 平均图像的 NumPy 数组,类型为 uint8"""# 确保列表非空if not imlist:raise ValueError("Image list is empty")# 打开第一幅图像,将其存储在浮点型数组中averageim = np.array(Image.open(imlist[0]), dtype=np.float32)# 累加所有图像for imname in imlist[1:]:try:im = np.array(Image.open(imname), dtype=np.float32)averageim += imexcept Exception as e:print(f"{imname}...skipped. Error: {e}")# 计算平均值averageim /= len(imlist)# 返回 uint8 类型的平均图像return np.array(averageim, dtype=np.uint8)

再引用该函数:

# main.py
from imtools import compute_average
import matplotlib.pyplot as plt# 图像文件路径的列表(根据实际情况修改)
image_files = ['1.jpg', ]# 计算平均图像
average_image = compute_average(image_files)# 使用matplotlib显示结果
plt.figure(figsize=(8, 8))
plt.imshow(average_image, cmap='gray')
plt.title('Average Image')
plt.axis('off')
plt.show()

得到图像平均后的结果:

1.3.6 图像的主成分分析PCA

        PCA是一个非常有用的降维技巧。 为了对图像数据进行 PCA 变换,图像需要转换成一维向量表示。我们可以使用 NumPy 类库中的 flatten() 方法进行变换。
import numpy as np
import matplotlib.pyplot as plt# PCA 函数的实现(从之前的代码中)
def pca(X):""" 主成分分析:输入:矩阵X,其中该矩阵中存储训练数据,每一行为一条训练数据返回:投影矩阵(按照维度的重要性排序)、方差和均值"""num_data, dim = X.shape# 数据中心化mean_X = X.mean(axis=0)X = X - mean_Xif dim > num_data:# PCA- 使用紧致技巧M = np.dot(X, X.T)  # 协方差矩阵e, EV = np.linalg.eigh(M)  # 特征值和特征向量tmp = np.dot(X.T, EV).T  # 这就是紧致技巧V = tmp[::-1]  # 由于最后的特征向量是我们所需要的,所以需要将其逆转S = np.sqrt(e)[::-1]  # 由于特征值是按照递增顺序排列的,所以需要将其逆转for i in range(V.shape[1]):V[:, i] /= Selse:# PCA- 使用 SVD 方法U, S, Vt = np.linalg.svd(X, full_matrices=False)V = Vt.T  # SVD 的 V 是转置的,所以我们需要转置回来S = np.sqrt(S)  # 对奇异值取平方根来得到标准差# 返回投影矩阵、方差和均值return V, S, mean_X# 示例数据
np.random.seed(0)
num_samples = 100
num_features = 5
X = np.random.rand(num_samples, num_features)# 执行 PCA
V, S, mean_X = pca(X)# 输出结果
print("投影矩阵 (主成分):")
print(V)
print("\n方差(主成分的标准差):")
print(S)
print("\n均值:")
print(mean_X)# 可视化结果(对于 2D 数据)
if num_features == 2:plt.figure(figsize=(8, 6))plt.scatter(X[:, 0], X[:, 1], alpha=0.5)plt.title('Original Data')plt.xlabel('Feature 1')plt.ylabel('Feature 2')plt.grid(True)plt.show()# 投影后的数据X_pca = np.dot(X, V)plt.figure(figsize=(8, 6))plt.scatter(X_pca[:, 0], X_pca[:, 1], alpha=0.5)plt.title('PCA Projected Data')plt.xlabel('Principal Component 1')plt.ylabel('Principal Component 2')plt.grid(True)plt.show()

结果:

1.3.7 使用pickle模块

        如果想要保存一些结果或者数据以方便后续使用,Python 中的 pickle 模块非常有用。

import pickle# 定义一个示例字典
data = {'name': 'Alice', 'age': 30, 'city': 'New York'}# 将对象序列化到文件
with open('data.pkl', 'wb') as file:pickle.dump(data, file)# 从文件反序列化对象
with open('data.pkl', 'rb') as file:loaded_data = pickle.load(file)print(loaded_data)

这个代码片段将一个字典对象 data 序列化到一个文件 data.pkl 中,然后再从文件中读取并反序列化成原始对象。运行时会输出 { 'name': 'Alice', 'age': 30, 'city': 'New York' }

结果:

1.4 SciPy        

        SciPy是建立在 NumPy 基础上,用于数值运算的开源工具包。 SciPy 提供很多高效的操作,可以实现数值积分、优化、统计、信号处理,以及对我们来说最重要的图像处理功能。

1.4.1 图像模糊

        SciPy 有用来做滤波操作的 scipy.ndimage.filters 模块。该模块使用快速一维分离 的方式来计算卷积。

from PIL import Image
from numpy import array, zeros, uint8
from scipy.ndimage import gaussian_filter# 加载图像并转换为 NumPy 数组
im = array(Image.open('1.jpg'))# 创建一个与输入图像相同大小的零数组,用于存储处理后的图像
im2 = zeros(im.shape)# 对每个颜色通道应用高斯模糊
for i in range(3):im2[:,:,i] = gaussian_filter(im[:,:,i], sigma=5)# 将处理后的图像转换为 uint8 类型(像素值范围从 0 到 255)
im2 = uint8(im2)# 将处理后的图像保存到文件
Image.fromarray(im2).save('1_blurred.jpg')

结果:

 

1.4.2 图像导数       

       使用 Sobel 滤波器来计算 x y 的方向导数,以及梯度大小。sobel() 函数的第二个参数表示选择 x 或者 y 方向导数,第三个参数保存输出的变量。

from PIL import Image
from numpy import array, zeros, sqrt, uint8
from scipy.ndimage import sobel# 加载图像并转换为灰度图
im = array(Image.open('empire.jpg').convert('L'))# 计算 x 和 y 方向的 Sobel 导数
imx = zeros(im.shape)
sobel(im, axis=1, output=imx)imy = zeros(im.shape)
sobel(im, axis=0, output=imy)# 计算梯度大小
magnitude = sqrt(imx**2 + imy**2)# 将梯度大小转换为 uint8 类型(像素值范围从 0 到 255)
magnitude = uint8(255 * (magnitude / magnitude.max()))# 保存梯度大小图像
Image.fromarray(magnitude).save('gradient_magnitude.jpg')

结果:

1.4.3 形态学对象计数

        形态学(或 数学形态学 )是度量和分析基本形状的图像处理方法的基本框架与集合。
形态学通常用于处理二值图像,但是也能够用于灰度图像。 scipy.ndimage 中 的 morphology 模 块 可 以 实 现 形 态 学 操 作。 你 可 以 使 用 scipy. ndimage 中的 measurements 模块来实现二值图像的计数和度量功能。
from scipy.ndimage import measurements, morphology
from PIL import Image
import numpy as np# 载入图像并转换为灰度图像
im = np.array(Image.open('1.jpg').convert('L'))# 进行二值化操作:假设阈值为128,小于该值的像素为1,大于该值的像素为0
im_binary = (im < 128).astype(int)# 使用 label() 函数标记不同的对象
labels, nbr_objects = measurements.label(im_binary)# 输出原始图像中的对象个数
print("Number of objects (before opening):", nbr_objects)# 形态学开操作:用结构元素对图像进行开运算
# 结构元素大小为9x5的矩形
structure = np.ones((9, 5), dtype=np.int32)
im_open = morphology.binary_opening(im_binary, structure=structure, iterations=2)# 使用 label() 函数重新标记经过开运算处理后的图像中的对象
labels_open, nbr_objects_open = measurements.label(im_open)# 输出经过开运算处理后的对象个数
print("Number of objects (after opening):", nbr_objects_open)

结果:

1.5 高级示例图像去噪

        图像去噪是在去除图像噪声的同时,尽可能地保留图像细节和结构的处理技术。我们这里使用 ROF(Rudin-Osher-Fatemi去噪模型

        

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import rof# Load and convert the image to grayscale
im = np.array(Image.open('empire.jpg').convert('L'))# Apply ROF denoising
U, T = rof.denoise(im, im)# Plot the denoised image
plt.figure()
plt.imshow(U, cmap='gray')
plt.axis('equal')
plt.axis('off')
plt.title('ROF Denoised Image')
plt.show()

结果:

这篇关于Python计算机视觉第一章-基本的图像操作和处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1108655

相关文章

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B