一文了解 Python 图像处理

推荐学习图像处理的入门书:《Python图像处理实战》 当然,现在的技术真的是日新月异,作为一本2020年出版的技术书,到2024年的时候,里面的一些代码和库早就升级了,但它并不妨碍我们对其中基础知识的理解,并且,更因为新的库的出现,在掌握了基础概念后,能更好地利用新的库和新的代码,做出更符合我们需要的程序。就我个人的经验来看,在学习完对应章节的代码练习后,我会去网上进一步学习更新的代码编写技巧,并尝试着将这些代码整合起来,最终做出一个自己的Python图片编辑程序(如下图)。于是,就这么边学边玩,我对图像处理的技巧的认知也一天天加深。 阅读详情

Part1

1. 图像读取

网上各种图像读取方法,我这里只根据目的划分为二进制和数组读取,两种方式——前者用于网络传输,后者用于广义上的图像处理。

1.1 二进制读取

使用ope() 以及 read()即可,其中使用'rb'指定以二进制的方式读取,用read而不是readline或者readlines,是读取全部的数据。

with open(data_path, 'rb') as f: 
    img = f.read()
    print(f"type(img): {type(img)}") # <class 'bytes'>
    print()
#     print(f"img: {img}")

1.2 数组读取

在这里就有很多库可以实现了,比如PIL、matplotlib、opencv、keras 等。
其中,opencv 使用最为广泛。

import cv2 

img = cv2.imread(data_path)
print(f"type(img): {type(img)}") # <class 'numpy.ndarray'>
print()
print(f"img:\n{img}")

需要注意的是,若 opencv 读取的是彩色图片,则其格式为 BGR 格式,而不是 matplotlib 的 RGB。

2. 图像处理

2.1 图像缩放

可以使用 opencv 的 resize()函数来完成。

注意 cv2.resize() 的一个坑:其第二个参数的 shape 为(width, height),而不是cv2.read()后 img 的形状:(height, width)

介绍两种思路:等比缩放和固定比例缩放

# 图像缩放
height = img.shape[0]
width = img.shape[1]
# ① 长、宽等比缩放
ratio = 0.8  # 每次缩放 0.8
height = int(height * ratio)
width = int(width * ratio)

# # ② 以长边为基准 (16:9)
# ratio = 9/16
# if height > width:
#     width = int(ratio * height)
# else:
#     height = int(ratio * width)
img = cv2.resize(img, (width, height), interpolation=cv2.INTER_AREA)  # interpolation:指定插值的方式

2.2 图像裁剪

暂略

2.3 像素级操作

暂略

完整代码

def img_processing(face_path):
    '''
    图像处理 (注册的时候使用)
    :param: face_path: 完整图片路径(人脸图片位于相应姓名的文件下,注意图像取名的格式-包含下划线"_")
    :return: dic —— {"user_name":user_name , "pic_type": pic_type, "pic": pic} ,即图像名称、图像格式、图像数据
    '''
    ENCODING = 'utf-8'

    face_name = os.path.split(face_path)[1]   # 获取带后缀的图片名 (os.path.split返回路径和文件名两部分)
    end_with = str(face_name.split('.')[-1])
    end_with = "." + end_with       # 获取文件后缀(带上".")
    # print(f"end_with: {end_with}")

    # 防止命名不合规
    if "_" in face_name:
        user_name = face_name.split('_')[0]       # 根据图片名获得人名 (此处有很多 bug 需要注意:①不包含"_" ②包含多个"_"等)
    else:
        print(f"格式错误:文件命名没有发现下划线")
        user_name = "Unknown"

    # 确定图片类型
    if end_with.lower() == '.bmp':
        pic_type = 3
    elif end_with.lower() =='.png':
        pic_type = 2
    else:
        pic_type = 1     # jpg 和 jpeg 是相同的格式,均归为 1

    # 图像读取和缩放
    img_name = os.path.split(face_path)[1]  # 图片原始名称v1

    img_size = os.path.getsize(face_path) / 1024
    print(f"img_size: {round(img_size, 3)}k")

    # 根据不同的图片大小,使用不同的图片 read 方式
    if img_size < 300:
    # ① 图片小于 300k,则以二进制直接读取图片
    #    过程:open —> b64encode —> decode -> 传输
        with open(face_path, 'rb') as f:
            img = f.read()
    else:
        # ② 图片大于等于 300k,则以opencv 读取图片,便于图片压缩
        #    过程:v2.imread —> 缩放处理—>  cv2.imencode —>  b64encode —> decode -> 传输
        img = cv2.imread(face_path)          # imread:——> np 图片
        print(f"Original Dimensions: {img.shape}")
        # 图片压缩

        # 循环:使用 oepncv 的 resize() 进行等比缩放
        while img_size >= 300:  # 对大于 300k 的图片进行缩处理
            print("Start image compressing...")
            # 图像缩放
            height = img.shape[0]
            width = img.shape[1]
            # ① 长、宽等比缩放
            ratio = 0.8  # 每次缩放 0.8
            height = int(height * ratio)
            width = int(width * ratio)

            # # ② 以长边为基准 (16:9)
            # ratio = 9/16
            # if height > width:
            #     width = int(ratio * height)
            # else:
            #     height = int(ratio * width)
            img = cv2.resize(img, (width, height), interpolation=cv2.INTER_AREA)  # interpolation:指定插值的方式
            # 保存图片
            save_path = "data/save/fixed/" + img_name  # 这里将 resize 后的图片另存,待下次再读取大小
            cv2.imwrite(save_path, img)

            img_size = os.path.getsize(save_path) / 1024

        print(f"Resized Dimensions: {img.shape}")
        print()
        print((f"Resized szie: {round(img_size, 3)} k"))

        # 进行编码(np——>)
        img = cv2.imencode(end_with.lower(), img)[1]   # end_with 即为图片的格式
        # print(f"img_encode: {len(img)}")

    # 按指定编码的数据,编码成 base64 bytes
    base64_bytes = b64encode(img)
    # print(f"base64_bytes: {len(base64_bytes)},{len(base64_bytes) / 1024}k")
    # 将 base64 字节码解码成 utf-8 格式的字符串
    base64_string = base64_bytes.decode(ENCODING)
    # print(f"base64_string: {len(base64_string)}, {len(base64_string)  / 1024}k")

    pic = base64_string

    data = {"user_name":user_name , "pic_type": pic_type, "pic": pic}   # 通过读取文件夹和文件获取 user_name 、pic_type、pic
    return data

Part2

3. 图像显示

3.1 设置画布大小

plt.figure()中使用 figsize 参数即可

plt.figure(figsize=(width * 0.1, height * 0.1), dpi=10)  # 此时图片像素:px, py = a*dpi, b*dpi

3.2 设置画布位置

    # 设置/固定画布在屏幕上的位置
    mngr = plt.get_current_fig_manager()  # 获取当前figure manager
    mngr.window.wm_geometry("+400+310")  # 调整窗口在屏幕上弹出的位置 其中+380 指窗口左上角顶点的横坐标向X轴正方向移动400,+310 指窗口左上角顶点的纵坐标向Y轴正方向移动310。对

调整图片在画布中的位置

plt.subplots_adjust(top = 0.9, bottom = 0.25, left = 0.1, right = 0.9, hspace = 0 , wspace = 0) # 取值为 0-1 之间(调整图片在画布中的位置)

3.4 设置图像分辨率

plt.figure()中使用 dpi 参数即可

plt.figure(figsize=(width * 0.1, height * 0.1), dpi=10)  # 此时图片像素:px, py = a*dpi, b*dpi

完整代码

# play image
def img_playing(face_path, playing_time):
    '''
    图片轮播 (认证的时候使用)
    :param image_data: 读取后的 img 数据
    :param num_img_all: 测试的图片数量 (影响到while循环)
    :return:
    '''
    global num_initial_compare_lst
    global num_compared

    face_name = os.path.split(face_path)[1]   # 获取带后缀的图片名 (os.path.split返回路径和文件名两部分)
    end_with = str(face_name.split('.')[-1])
    end_with = "." + end_with       # 获取文件后缀(带上".")
    # print(f"end_with: {end_with}")

    # 防止命名不合规
    if "_" in face_name:
        user_name = face_name.split('_')[0]       # 根据图片名获得人名 (此处有很多 bug 需要注意:①不包含"_" ②包含多个"_"等)
    else:
        print(f"格式错误:文件命名没有发现下划线")
        user_name = "Unknown"

    # # 确定图片类型
    # if end_with.lower() == '.bmp':
    #     pic_type = 3
    # elif end_with.lower() =='.png':
    #     pic_type = 2
    # else:
    #     pic_type = 1     # jpg 和 jpeg 是相同的格式,均归为 1

    # 图像读取和缩放
    # img_name = os.path.split(face_path)[1]  # 图片原始名称v1

    # 读取图片
    # 使用 oepncv 的 resize() 进行等比缩放
    img = cv2.imread(face_path)
    print(f"Original Dimensions: {img.shape}")
    #
    # # 图像缩放
    # height = img.shape[0]
    # width = img.shape[1]
    # # # ① 长、宽等比缩放
    # # ratio = 0.6
    # # height = int(height * ratio)
    # # width = int(width * ratio)
    #
    # # ② 以长边为基准 (16:9)
    # ratio = 9/16
    # if height > width:
    #     width = int(ratio * height)
    # else:
    #     height = int(ratio * width)
    # img = cv2.resize(img, (width, height), interpolation=cv2.INTER_AREA)  # interpolation:指定插值的方式
    # print(f"Resized Dimensions: {img.shape}")

    # 显示图片
    height = img.shape[0]
    width = img.shape[1]

    max_size =  (2560, 1600)  # mac 分辨率
    max_height = max_size[1] * 0.6   # 图片最大高度

    ratio = 9/16
    if height > width:
        height = max_height
        width = int(ratio * height)
    else:
        height = max_height
        width = int(1/ratio * height)
    print(f"Resized Dimensions: {img.shape}")

    plt.figure(figsize=(width * 0.1, height * 0.1), dpi=10)  # 此时图片像素:px, py = a*dpi, b*dpi
    # plt.subplots_adjust(top = 0.9, bottom = 0.25, left = 0.1, right = 0.9, hspace = 0 , wspace = 0) # 取值为 0-1 之间(调整图片在画布中的位置)
    plt.margins(0, 0)

    # 设置/固定画布在屏幕上的位置
    mngr = plt.get_current_fig_manager()  # 获取当前figure manager
    mngr.window.wm_geometry("+400+310")  # 调整窗口在屏幕上弹出的位置 其中+380 指窗口左上角顶点的横坐标向X轴正方向移动400,+310 指窗口左上角顶点的纵坐标向Y轴正方向移动310。对


    # 使用plt 显示图片之前进行转换:BGR -> RGB
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)   # BGR -> RGB
    # gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # RGB -> 灰度
    # # 需要添加colormap 颜色映射函数为gray
    # plt.imshow(gray, cmap="gray")
    fontsize = int(width / 5)
    plt.title(user_name, fontsize=fontsize, color='r')  # 不显示标题可能是字体大小的问题
    plt.imshow(img)
    # # 暂停或者播放下一张
    print("-----------继续采集照片中----------")
    plt.pause(playing_time)   #
    plt.clf()         # clear the current figure
    plt.close('all')  # 关闭所有图:避免重叠
Python图像处理项目:从基础到实战,打造你的图像处理技能! 🏆本文收录于「编程与技术实战」专栏,此专栏涵盖了C/C++编程、人工智能、数据结构、机器学习等技术领域的内容,助你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!! 阅读详情

相关推荐

Python图像处理【3】Python图像处理库应用

和多数编程任务类似,在编写图像处理应用程序时,我们无需重复“造轮子”的过程,利用 Python 强大且丰富的第三方库能够大量缩减应用程序的编写时间,达到事半功倍的效果。在本节中,我们将学习使用不同的 Python 库实现一些常见的图像处理、变换和可视化技术,这些技术通常可以用作更复杂的图像处理任务的基本预处理/后处理步骤。

qq_30167691的博客 15万+

Python图像处理的三种方法

Pyqt界面,图像处理,机器视觉,缺陷检测

m0_61456316的博客 4775

Python图像处理【2】探索Python图像处理库

和多数编程任务类似,在编写图像处理应用程序时,我们无需重复“造轮子”的过程,利用 Python 强大且丰富的第三方库能够大量缩减应用程序的编写时间,达到事半功倍的效果。在本节中,我们将学习使用不同的 Python 库实现一些常见的图像处理、变换和可视化技术,这些技术通常可以用作更复杂的图像处理任务的基本预处理/后处理步骤。

qq_30167691的博客 14万+

Python图像处理

python图像处理

Code搬运工 2万+

[Python从零到壹] 三十三.图像处理基础篇之什么是图像处理和OpenCV配置

欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍。该系列文章主要讲解Python OpenCV图像处理和图像识别知识,第一篇文章作为整个系列的引子,将介绍什么是图像处理,图像处理的基础知识,Python语言的优势和OpenCV基础概述。希望文章对您有所帮助,如果有不足之处,还请海涵。接下来,让我们开启整个系列的学习吧!

杨秀璋的专栏 8227

Python图像处理【23】分布式图像处理

分布式处理可以将位于不同地点的、或具有不同功能的、或拥有不同数据的多台计算机通过通信网络连接起来,在控制系统的统一管理控制下,协调地完成大规模信息处理任务,利用分布式处理可以提高信息处理速度。在本节中,我们学习了如何使用 Dask 完成分布式图像处理,从而提高图像处理速度。

qq_30167691的博客 4229

python进行基本的图像处理

转自 http://www.ituring.com.cn/tupubarticle/2024 第 1 章 基本的图像操作和处理 本章讲解操作和处理图像的基础知识,将通过大量示例介绍处理图像所需的 Python 工具包,并介绍用于读取图像、图像转换和缩放、计算导数、画图和保存结果等的基本工具。这些工具的使用将贯穿本书的剩余章节。 1.1 PIL:Python图像处理

xiao_lxl的专栏 2万+

让 AI 变聪明的 20 条指令:如何让大模型回答得更精准、更专业、更实事求是

让 AI 变聪明,本质上不是写几句神奇咒语,而是把你的任务表达得更清楚,把事实标准设得更严格,把输出格式规定得更明确,把不确定性管理得更认真,把历史对话利用得更充分。大模型的强项是语言生成、信息组织、模式归纳和方案扩展;弱项是事实核验、实时更新、责任判断和对模糊意图的准确猜测。好的指令,就是在用人的判断弥补模型的弱点,让模型把强项发挥在正确的地方。

Sumarua的博客 1494

python图片处理常用操作笔记

python图片处理常用操作笔记1. 静态图片操作笔记安装库导入库读写静态图片从磁盘读取图片将图片写入磁盘用cv2显示图片将彩色图转换为灰度图过滤图片中的噪点缩放图片的长宽图片截取颜色通道拆分与合并直方图均衡化图片翻转高维矩阵转置tensor中的用法,需要导入torch包。2. 动态图片操作笔记安装库导入库读取gif图片写出gif图片3. 一些简单功能实现笔记3.1 单色背景照片背景色替换3.2 为图片增加透明度图层并自定义透明度 萌新方便自己查询的笔记,记录一些常用的方法,不定时更新~ 1. 静态图片操作

starvapour的博客 5784

OCR模型轻量化新思路:用ONNX Runtime加速PP-OCRv4推理(附性能对比测试)

本文详细介绍了如何利用ONNX Runtime对PP-OCRv4模型进行轻量化部署与推理加速。通过模型导出优化、动态量化、线程绑定及内存复用等技巧,在树莓派、RK3588等边缘设备上实现了超过50%的性能提升,并显著降低了内存占用,为移动端OCR部署提供了完整的优化方案和实测数据对比。

weixin_29063979的博客 496

逆向淘宝x-mini-wua:从加密算法到设备指纹的生成逻辑

本文深入剖析了淘宝风控核心参数x-mini-wua的生成逻辑与加密算法。通过逆向分析,揭示了其作为设备“身份证”的作用,详细拆解了从硬件信息采集、SG_INNER_DATA文件解密、关键参数提取到最终长wua合成的完整技术链条,并探讨了模拟生成与绕过风控的实战思路及注意事项。

year5的博客 1076

6个最好用的Python图像处理库!

与其他编程语言不同,Python有非常独特的优势,那就是它拥有非常非常多的第三方库,拿来即用,可为我们的工作带来很大的帮助。而今天的这篇文章,小编要为大家介绍6个最好用的Python图像处理库,快来认识一下吧。

Python栈 3821

173、NPU的编译器开发:开源社区贡献指南

本文分享了在NPU编译器开源社区贡献的经验心得。作者通过实际案例(如卷积维度错误、NaN输出等)阐述了NPU编译器开发的特殊性:硬件迭代快、边界条件复杂、厂商代码不可全信。提出有价值的贡献应聚焦硬件适配测试、性能剖析工具和反模式文档三类内容。强调用实测数据沟通、主动承担维护责任、保持代码通用性等社区协作技巧,并建议通过RFC提前沟通、附硬件实测数据等方式提高PR通过率。最后指出,NPU编译器开发是与聪明人共同填坑的过程,鼓励开发者提交"有诚意的代码"而非完美代码。

m0_50546716的博客 35

python图像处理:PIL与Pillow区别

在学习python图像处理时,傻傻的分不清PIL和Pillow,于是简单整理一下二者区别。 一、PIL PIL全称是:Python Imaging Library。 PIL是一个强大的、方便的python图像处理库,功能非常强大,曾经一度被认为是python平台事实上的图像处理标准库,不过Python 2.7以后不再支持。 PIL官方网站: http://pythonware.com/products/pil/ 二、Pillow Pillow是基于PIL模块fork的一个派生分支,但如今已经发展成为比.

程序员的一天 1万+

高通平台开发系列讲解(USB篇)MBIM协议详解

📢本文主要介绍高通平台USB网卡MBIM协议。

内核笔记 5438

AIoT 在线工程实训平台案例——智能家居

AIoT 在线工程实训平台案例——智能家居的操作步骤

m0_53608652的博客 1431

干货!如何用Python处理图像,一文带你了解!

大家好,我是菜鸟哥!用Python玩图像处理还是很有意思的,我们以前写过很多这样的文章:学Python真香!我用100行代码做了个网站,帮人PS旅行图片,赚个鸡腿吃!十行代码,我用Python做一个迷你版的美图秀秀!十行Python代码替换证件照背景颜色今天来细细讲讲,也许对大家有帮助。入门知识颜色。如果你有使用颜料画画的经历,那么一定知道混合红、黄、蓝三种颜料可以得到其他的颜色,事实上这三种颜色...

cainiao_python的博客 3881

华为OD机考真题 新系统 - 小菊的寻宝之旅(Java/Py/C/C++/Js/Go)

华为OD机试真题 新系统【小菊的寻宝之旅】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【小菊的寻宝之旅】多语言题解。

qq_45776114的博客 621

python图像处理的书籍推荐_推荐:10个Python图像处理工具

概述了一些常用的Python库,它们提供了一种简单直观的图像转换方法。介绍在我们今天的世界中有很多的数据,而图像是这些数据中的重要组成部分。但是,要使用这些图像,需要对它们进行处理。因此,图像处理是分析和操纵数字图像的过程,主要目的是提高数字图像的质量或从中提取一些信息,然后可以将其用于某种用途。图像处理中常见的任务包括显示图像,基本操作,如裁剪、翻转、旋转等、图像分割、分类和特征提取、图像恢复和...

weixin_39805924的博客 2518

【智能流体力学】使用ANSYS Fluent + SpaceClaim + SCDM制作流体力学前处理的几何模型

生成来源.scdoc文件来自前处理工具生成的模型数据,或在 FLUENT 中创建和保存的模型。生成方式: 通过前处理工具导出网格数据,或在 FLUENT 中设置并保存模型。作用: 用于储存模型的结构信息和设置,确保在 FLUENT 中的正确导入和使用。.x_t文件是 Parasolid 文件格式的扩展名,用于存储三维模型数据。在 ANSYS Fluent 中,这种格式通常用于在前处理工具之间交换几何数据。要创建.x_t。

源代码杀手的博客 3265

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

10个Python图像处理工具,非常全了!

概述了一些常用的Python库,它们提供了一种简单直观的图像转换方法。 介绍 在我们今天的世界中有很多的数据,而图像是这些数据中的重要组成部分。但是,要使用这些图像,需要对它们进行处理。因此,图像处理是分析和操纵数字图像的过程,主要目的是提高数字图像的质量或从中提取一些信息,然后可以将其用于某种用途。 图像处理中常见的任务包括显示图像,基本操作,如裁剪、翻转、旋转等、图像分割、分类...

ctrigger的专栏 2283

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Python图像处理全面总结与案例解析

本章介绍了Python图像处理的基础知识,包括环境搭建、图像读取与显示、图像基本操作、图像滤波和图像增强等。通过这些内容的学习,读者应该能够掌握Python图像处理的基本技巧,并为后续的学习和实践打下坚实的基础。在下一章中,我们将深入探讨Python图像处理的高级应用,包括图像分割、特征提取和图像合成等。在第一章中,我们学习了如何使用Python进行图像处理操作。通过本章的学习,你将能够理解并执行基本的图像操作,包括调整大小、翻转、滤波和增强等。

极客代码 9020

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Python图像处理基础

Python图像处理基础 对我个人而言使用Python图像处理意在取代matlab,集中化使用Python环境保证之后在机器学习和OpenCV的使用上具有一致性,虽然从实验室师兄师姐的口中得知Python的图像处理较之matlab相对复杂(应该只是代码量的问题),但我依然觉得学习python环境比较实用和高效。在进行Python图像处理之前,Pillow是不可或缺的实用性工具,pillow是Py

章子雎的博客 5082

十个Python图像处理工具

这些Python库提供了一种简单直观的方法来转换图像并理解底层数据。 今天的世界充满了数据,图像是这些数据的重要组成部分。但是,在使用它们之前,必须对这些数字图像进行处理 - 分析和操作,以提高其质量或提取一些可以使用的信息。 常见的图像处理任务包括显示; 基本操作如裁剪,翻转,旋转等;;图像分割,分类和特征提取;图像恢复;图像识别。Python是这些图像处理任务的绝佳选择,因为它作为一种科学...

python学习者的博客 3583

一文了解python中pip的使用

Python是一种广泛使用的解释型、高级和通用的编程语言。

大虾好吃吗 4480
上一篇: Numpy:numpy.append 以及与 numpy.concatente 的区别
下一篇: 2021-09-08 优快云 MarkDown 编辑汇总
Robin_Pi
博客等级 码龄9年 2万+粉丝 632原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值