python多线程读图片

2023-11-01

用 threading 模块多线程读图片加速,flickr25k 和 nuswide 两个数据集的图片准备见 [1-4],图像预处理程序来自 [5]。

为了测试,写了一个叫 LazyImage 的类,和其多线程版本 LazyImage_MT,代码:

import time
import multiprocessing
import threading
import os
import os.path as osp
import numpy as np
from PIL import Image

#
# 普通顺序加载:LazyImage、ImageF25k、ImageNUS
#

class LazyImage:
    """mimics np.ndarray, but uses lazy loading"""

    def __init__(self, image_path, image_size=224):
        """image_size: int"""
        self.image_path = image_path
        self.image_size = image_size
        # used in resizing
        self.lower_half = image_size // 2
        self.upper_half = (image_size + 1) // 2

    def __getitem__(self, index):
        if isinstance(index, int):
            return self._load_image(index)
        elif isinstance(index, (np.ndarray, list, tuple)):
            if isinstance(index, np.ndarray):
                assert 1 == index.ndim, "* index should be vector"
            return np.vstack([np.expand_dims(
                self._load_image(i), 0) for i in index])

        raise NotImplemented

    def _load_image(self, full_index):
        """loads single image & resizes
        Input:
            - full_index: int, the sample ID
        """
        img = Image.open(self._get_image_path(full_index))
        xsize, ysize = img.size
        seldim = min(xsize, ysize)
        rate = float(self.image_size) / seldim
        img = img.resize((int(xsize * rate), int(ysize * rate)))
        nxsize, nysize = img.size
        cx, cy = nxsize / 2.0, nysize / 2.0
        box = (cx - self.lower_half, cy - self.lower_half, cx + self.upper_half, cy + self.upper_half)
        img = img.crop(box)
        img = img.convert("RGB")  # can deal with grey-scale images
        img = img.resize((224, 224))
        img = np.array(img, dtype=np.float32)
        return img  # [H, W, C]

    def _get_image_path(self, full_index):
        """get image path according to sample ID"""
        raise NotImplemented


class ImageF25k(LazyImage):
    def _get_image_path(self, full_index):
        # shift to 1-base
        return osp.join(self.image_path, "im{}.jpg".format(full_index + 1))


class ImageNUS(LazyImage):
    """depends on (github) iTomxy/data/nuswide/make.image.link.py"""
    def _get_image_path(self, full_index):
        # remain 0-base as is
        return osp.join(self.image_path, "{}.jpg".format(full_index))

#
# 多线程加载:LazyImage_MT、ImageF25k_MT、ImageNUS_MT
#

class LazyImage_MT:
    """multi-threading version"""

    def __init__(self, image_path, image_size=224, n_thread=None):
        """image_size: int"""
        self.image_path = image_path
        self.image_size = image_size
        # used in resizing
        self.lower_half = image_size // 2
        self.upper_half = (image_size + 1) // 2
        self._mutex_put = threading.Lock()
        self._buffer = []
        self.n_thread = n_thread if (n_thread is not None) else \
            max(1, multiprocessing.cpu_count() - 2)

    def __getitem__(self, index):
        if isinstance(index, int):
            return self._load_image(index)
        elif isinstance(index, (np.ndarray, list, tuple)):
            if isinstance(index, np.ndarray):
                assert 1 == index.ndim, "* index should be vector"
            if self.n_thread < 2:
                return np.vstack([np.expand_dims(self._load_image(i), 0) for i in index])

            self._buffer = []
            batch_size = (len(index) + self.n_thread - 1) // self.n_thread
            t_list = []
            for tid in range(self.n_thread):
                t = threading.Thread(target=self._load_image_mt, args=(
                    index, range(tid * batch_size, min((tid + 1) * batch_size, len(index)))))
                t_list.append(t)
                t.start()
            for t in t_list:
                t.join()
            del t_list
            assert len(self._buffer) == len(index)
            self._buffer = [t[1] for t in sorted(self._buffer, key=lambda _t: _t[0])]
            return np.vstack(self._buffer)

        raise NotImplemented

    def _load_image_mt(self, indices, seg_meta_indices):
        batch_images = [(mid, np.expand_dims(self._load_image(indices[mid]), 0))
            for mid in seg_meta_indices]
        self._mutex_put.acquire()
        self._buffer.extend(batch_images)
        self._mutex_put.release()

    def _load_image(self, full_index):
        """loads single image & resizes
        Input:
            - full_index: int, the sample ID
        """
        img = Image.open(self._get_image_path(full_index))
        xsize, ysize = img.size
        seldim = min(xsize, ysize)
        rate = float(self.image_size) / seldim
        img = img.resize((int(xsize * rate), int(ysize * rate)))
        nxsize, nysize = img.size
        cx, cy = nxsize / 2.0, nysize / 2.0
        box = (cx - self.lower_half, cy - self.lower_half, cx + self.upper_half, cy + self.upper_half)
        img = img.crop(box)
        img = img.convert("RGB")  # can deal with grey-scale images
        img = img.resize((224, 224))
        img = np.array(img, dtype=np.float32)
        return img  # [H, W, C]

    def _get_image_path(self, full_index):
        """get image path according to sample ID"""
        raise NotImplemented


class ImageF25k_MT(LazyImage_MT):
    def _get_image_path(self, full_index):
        # shift to 1-base
        return osp.join(self.image_path, "im{}.jpg".format(full_index + 1))


class ImageNUS_MT(LazyImage_MT):
    """depends on (github) iTomxy/data/nuswide/make.image.link.py"""
    def _get_image_path(self, full_index):
        # remain 0-base as is
        return osp.join(self.image_path, "{}.jpg".format(full_index))

#
# 测试:速度、一致性
#

if "__main__" == __name__:
    batch_size = 128
    N_F25K = 25000
    N_NUS = 269648
    indices_f25k = np.arange(N_F25K)
    indices_nus = np.arange(N_NUS)

    print("-> flickr25k")
    tic = time.time()
    im_f25k = ImageF25k("data/flickr25k/mirflickr")
    for i in range(0, N_F25K, batch_size):
        _ = im_f25k[indices_f25k[i: i + batch_size]]
    print(time.time() - tic)  # 214.9833734035492
    # del im_f25k

    print("-> flickr25k multi-threading")
    tic = time.time()
    im_f25k_mt = ImageF25k_MT("data/flickr25k/mirflickr")
    for i in range(0, N_F25K, batch_size):
        _ = im_f25k_mt[indices_f25k[i: i + batch_size]]
    print(time.time() - tic)  # 56.653871297836304
    # del im_f25k_mt

    print("-> nuswide")
    tic = time.time()
    im_nus = ImageNUS("data/nuswide-tc21/images")
    for i in range(0, N_NUS, batch_size):
        _ = im_nus[indices_nus[i: i + batch_size]]
    print(time.time() - tic)  # 631.8568336963654
    # del im_nus

    print("-> nuswide multi-threading")
    tic = time.time()
    im_nus_mt = ImageNUS_MT("data/nuswide-tc21/images")
    for i in range(0, N_NUS, batch_size):
        _ = im_nus_mt[indices_nus[i: i + batch_size]]
    print(time.time() - tic)  # 207.77122569084167
    # del im_nus_mt

    print("-> consistency")
    for i in range(0, N_F25K, batch_size):
        i_s = im_f25k[indices_f25k[i: i + batch_size]]
        i_mt = im_f25k_mt[indices_f25k[i: i + batch_size]]
        print("f25k diff:", (i_s != i_mt).sum())  # 0
        i_s = im_nus[indices_nus[i: i + batch_size]]
        i_mt = im_nus_mt[indices_nus[i: i + batch_size]]
        print("nus diff:", (i_s != i_mt).sum())  # 0
        break
  • 输出
-> flickr25k
214.9833734035492
-> flickr25k multi-threading
56.653871297836304
-> nuswide
631.8568336963654
-> nuswide multi-threading
207.77122569084167
-> consistency
f25k diff: 0
nus diff: 0

References

  1. MIR-Flickr25K数据集预处理
  2. iTomxy/data/flickr25k
  3. NUS-WIDE数据集预处理
  4. iTomxy/data/nuswide
  5. DeXie0808/GCH/load_data.py
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python多线程读图片 的相关文章

  • Flask-SocketIO redis 订阅

    我在用着https github com miguelgrinberg Flask SocketIO https github com miguelgrinberg Flask SocketIO实现 WebSocket 服务器 我需要从另一
  • 从所有数据帧列中删除子字符串

    我有一个单词列表 大约 1000 个单词 我称之为负面单词 CAST ARTICLES SANITARY JAN CLAUSES SPECIAL ENDORSEMENT 我很快就会用这个单词列表制作一个数据框 我还有一个数据框 看起来像 F
  • App Engine 上的 Django 与 webapp2 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在 Pandas Python 中按 id 对行进行排名

    我有一个像这样的数据框 id points1 points2 1 44 53 1 76 34 1 63 66 2 23 34 2 44 56 我想要这样的输出 id points1 points2 points1 rank points2
  • 使用 Pandas 从 csv 文件读取标题信息

    我有一个包含 14 行标题的数据文件 在标头中 有经纬度坐标和时间的元数据 我目前正在使用 pandas read csv filename delimiter header 14 读取文件 但这只是获取数据 我似乎无法获取元数据 有人知道
  • 为什么需要设置WORKON_HOME环境变量?

    我已经有一段时间没有使用 python 虚拟环境了 但我也安装了虚拟环境包装器 我的问题是 在文档页面中它说要这样做 export WORKON HOME Envs mkdir p WORKON HOME source usr local
  • 如何知道python运行脚本的路径?

    sys arg 0 给我 python 脚本 例如 python hello py 返回 sys arg 0 的 hello py 但我需要知道 hello py 位于完整路径中的位置 我怎样才能用Python做到这一点 os path a
  • 使用会话在 Django 中将文件从一个视图传递到另一个视图

    我当前的工作项目要求我允许用户上传各种格式的文件 目前仅处理 CSV 格式 然后使用包含的数据来绘制图表Pandas http pandas pydata org 图书馆 我决定将图形渲染到模板的最简单方法是为图形创建特定视图 然后将图像从
  • 使用 python 脚本更改 shell 中的工作目录

    我想实现一个用户态命令 它将采用其参数之一 路径 并将目录更改为该目录 程序完成后 我希望 shell 位于该目录中 所以我想实施cd命令 但需要外部程序 可以在 python 脚本中完成还是我必须编写 bash 包装器 Example t
  • 在 django 中导入设置时出现奇怪的错误

    我有很多项目在 ubuntu 中使用 python2 7 和 virtualenv virtualenvwrapper 工作 在我的工作中 一些开发人员使用 macosx 和 windows 通常我像往常一样创建项目 django admi
  • 使用 ElementTree 在 python 中解析 xml

    我对 python 很陌生 我需要解析一些脏的 xml 文件 这些文件需要先清理 我有以下 python 代码 import arff import xml etree ElementTree import re totstring wit
  • Eclipse/PyDev 中未使用导入警告,尽管已使用

    我正在我的文件中导入一个绘图包 如下所示 import matplotlib pyplot as plt 稍后我会在我的代码中成功使用此导入 fig plt figure figsize 16 10 然而 Eclipse 告诉我 未使用的导
  • 在Python中使用pil读取tif图像时出现值错误?

    我必须读取尺寸的tif图像2200 2200并输入 uint16 我将 PIL 库与 anaconda python 一起使用 如下所示 from PIL import Image img Image open test tif img i
  • 根据标点符号列表替换数据框中的标点符号[重复]

    这个问题在这里已经有答案了 使用 Canopy 和 Pandas 我有数据框 a 其定义如下 a pd read csv text txt df pd DataFrame a df columns test test txt 是一个单列文件
  • 将 Django 中的所有视图限制为经过身份验证的用户

    我是 Django 新手 我正在开发一个项目 该项目有一个登录页面作为其索引和一个注册页面 其余页面都必须仅限于登录用户 如果未经身份验证的用户尝试访问这些页面 则必须将他 她重定向到登录页面 我看到 login required装饰器会将
  • 为什么从 openAI 导入 Universe 模块时出现“无效语法”错误

    当我导入时universe来自 openAI 的模块 我收到以下错误 Traceback most recent call last File
  • SQLAlchemy 与 count、group_by 和 order_by 使用 ORM

    我有几个函数需要使用 count group by 和 order by 进行一对多连接 我使用 sqlalchemy select 函数生成一个查询 该查询将返回一组 id 然后我对其进行迭代以对各个记录执行 ORM 选择 我想知道是否有
  • 如何有效地比较 pandas DataFrame 中的行?

    我有一个 pandas 数据框 其中包含雷击记录以及时间戳和全球位置 格式如下 Index Date Time Lat Lon Good fix 0 1 20160101 00 00 00 9962692 7 1961 60 7604 1
  • 从 Django 运行 shell 命令

    我正在 Django 中开发一个网页 使用 apache 服务器 需要调用 shell 命令来启用 禁用一些守护进程 我尝试这样做 os system service httpd restart 1 gt HOME out 2 gt HOM
  • Tkinter 将鼠标点击绑定到框架

    我一定错过了一些明显的东西 我的 Tkinter 程序中有两个框架 每个框架在网格布局中都有一堆标签 我想将鼠标点击绑定到其中一个而不是另一个 我目前使用 root bind

随机推荐

  • idea简便导入jar包的方法

    idea简便导入jar包的方法 Step1 2021 12 18 15 21 19 复制准备好的jar包 Step 2 2021 12 18 15 21 20 在需要该jar包的项目中创建一个文件夹 一般习惯文件夹的名字为lib Step
  • case when 多个条件 以及case when 权重排序

    1 case when 多个条件 语法 SELECT nickname user name CASE WHEN user rank 5 THEN 经销商 WHEN user rank 6 THEN 代理商 WHEN user rank 7
  • 【计算机视觉这一年】万字长文盘点近百篇代表论文、应用和市场

    新智元导读 The M Tank发布了一份对计算机视觉领域最近一年进展的报告 A Year in Computer Vision 详述了四大部分的内容 包括 分类 定位 目标检测 目标追踪 分割 超分辨率 自动上色 风格迁移 动作识别 3D
  • 头哥作业:统计字母数量

    统计字母数量 输入格式 输出格式 示例 1 任务描述 读取附件是一篇英文短文 请编写程序统计这篇短文前 n 行中每一个英文字母出现的次数 结果按次数降序排列 次数相同时 按字母表顺序输出 若 n 值大于短文行数 输出整篇文章中每一个英文字母
  • windows安装JDK、maven 和 IDEA

    一 JDK安装 Java程序必须运行在JVM之上 或者说java exe就是JVM 所以 使用Java的第一件事情是安装JDK 1 获取安装包 官方网址 https www oracle com java technologies down
  • 距离公式详解

    在做分类时常常需要估算不同样本之间的相似性度量 SimilarityMeasurement 这时通常采用的方法就是计算样本间的 距离 Distance 采用什么样的方法计算距离是很讲究 甚至关系到分类的正确与否 本文的目的就是对常用的相似性
  • 一种通过篡改特定代码数据修复嵌入式产品BUG的方法

    一 前言 在嵌入式产品开发中 难以避免地会因为各种原因导致最后出货的产品存在各种各样的BUG 通常会给产品进行固件升级来解决问题 记得之前在公司维护一款BLE产品的时候 由于前期平台预研不足 OTA参数设置不当 导致少数产品出现不能OTA的
  • Wetab 标签页:内置多种免费实用优雅小组件的浏览器主页和起始页

    Wetab 是什么 Wetab 是一款基于浏览器的新标签页产品 主张辅助用户打造一个兼具效率与美观的主页 nbsp Wetab 的核心特色便是内置了多种实用 优雅的小组件 今天这篇 主要按照分类详细介绍 nbsp Wetab 中的各个小组件
  • c++中的sort函数的头文件及详细用法

    头文件为 include
  • centos7 mysql server_centos7 mysqlserver 安装过程

    官网下载安装mysql server wget http dev mysql com get mysql community release el7 5 noarch rpm rpm ivh mysql community release
  • ​通过VS Code远程访问局域网Linux

    来源 配置vscode远程到Linux环境下 z417 博客园 首先 VS Code安装插件remote SSH 其次 修改C Users xxx ssh config Host JetsonNano HostName 192 168 13
  • Flutter快速入门学习(二)

    目录 Dart介绍 一些Dart的重要概念 Dart语法学习 变量 内建类型 Number String Boolean List Set Map Symbol 函数 参数类型 可选参数 必选参数 函数作为另一个函数的参数 匿名函数 运算符
  • vue使用computed计算属性,监听初始化路由,页面高度

    vue中computed计算属性 页面高度自适应问题 div div
  • 王者S19服务器维护时间表,王者荣耀s19buff刷新时间一览 红蓝BUFF刷新间隔是多久...

    王者荣耀S19赛季加大了打野位对战局的影响 因此熟悉红蓝BUFF的刷新时间非常重要 无论是反BUFF还是拿自家BUFF都应该清楚刷新时间点 今日光耀菌就为大家带来了红蓝BUFF的刷新时间表 快来了解一番吧 王者荣耀s19赛季红蓝BUFF刷新
  • javaScript-----数组使用字符串作为下标

    原文地址 http blog csdn net chenssy article details 7366160 首先Array是从Object那里继承下 它具备Object所有的功能和特性 下面是Object的情况 html view pl
  • TypeScript void 无返回值

    void 表示没有任何类型 当一个函数没有返回值时 通常会返回 void 有值则会返回指定值类型 void 类型 没有返回值 function showMsg void console log 显示消息 不能返回数据 会报错 return
  • Android开发从入门到精通 章节一 : 环境+IDE

    Android开发从入门到精通 章节一 环境 IDE 接下来带领大家踏入Android编程的世界 跟着我的文章一起迈入移动端开发的世界 Android官网 https developer android google cn index ht
  • qt 嵌入web页面_Qt与Web混合开发(一)--简单使用

    目录 放个目录方便预览 目录是从博客复制过来的 点击会跳转到博客 前言 Qt与Web混合开发 系列文章 主要讨论Qt与Web混合开发相关技术 这类技术存在适用场景 例如 Qt项目使用Web大量现成的组件 方案做功能扩展 Qt项目中性能无关
  • 创建型设计模式

    为什么说支持懒加载的双重检测不比饿汉式更优 单例模式 一个类只允许创建一个对象 或实例 即单例模式 为什么使用单例 处理资源访问冲突 表示全局唯一类 从业务概念上 有些数据在系统种只应该保存一份 就比较适合设计为单例类 实现一个单例 构造函
  • python多线程读图片

    用 threading 模块多线程读图片加速 flickr25k 和 nuswide 两个数据集的图片准备见 1 4 图像预处理程序来自 5 为了测试 写了一个叫 LazyImage 的类 和其多线程版本 LazyImage MT 代码 i