gpt4 book ai didi

python - 重启后如何在python中更快地执行opencv cv2 imread

转载 作者:太空宇宙 更新时间:2023-11-03 21:18:54 26 4
gpt4 key购买 nike

我有大约 650,000 个图像文件,我使用 cv2 将它们转换为 numpy 数组。图像被安排到子文件夹中,每个子文件夹中有大约 10k 个图像。每个图像都很小;大约 600 字节(2x100 像素 RGB)。

当我全部阅读它们时:

cv2.imread()

每 10k 图像需要半秒,所有 650k 不到一分钟......除非我重新启动机器。然后我在重启后第一次运行我的脚本时,每 10k 个图像需要 20-50 秒;全文阅读半小时左右。

为什么?

我怎样才能让它们在重启后快速访问,而不需要缓慢的初始读取?

历史图像数据库每天都在增长;旧的不会被重写。

代码:

print 'Building historic database...'
elapsed = elapsed2 = time.time()
def get_immediate_subdirectories(a_dir):
return [name for name in os.listdir(a_dir)
if os.path.isdir(os.path.join(a_dir, name))]
compare = get_immediate_subdirectories('images_old')
compare.sort()

images = []
for j in compare:
begin = 1417024800
end = 1500000000
if ASSET == j:
end = int(time.time()-86400*30)
tally = 0
for i in range (begin, end, 7200):
try:
im = cv2.imread("images_old/%s/%s_%s.png" % (j,j,i))
im = np.ndarray.flatten(im)
if im is not None:
images.append([j,i,im])
tally+=1
except: pass
print j.ljust(5), ('cv2 imread elapsed: %.2f items: %s' % ((time.time()-elapsed),tally))
elapsed = time.time()
print '%.2f cv2 imread big data: %s X %s items' % ((time.time()-elapsed2),len(images),len(a1))
elapsed = time.time()

amd fm2+ 16GBLinux 薄荷 17.3 python 2.7

最佳答案

我想提出一个基于 REDIS 的概念,它类似于数据库,但实际上是一个“数据结构服务器”,其中数据结构是您的 600 字节图像。我暂时不建议您将 REDIS 用作永久存储系统,而是继续使用您的 650,000 个文件,但将它们缓存在 REDIS 中,REDIS 是免费的,可用于 Linux、macOS 和 Windows。

因此,基本上,在一天中的任何时候,您都可以将图像复制到 REDIS 中,为下一次重启做好准备。

我不会说 Python,但这里有一个 Perl 脚本,我用它生成了 650,000 张图像,每张图像有 600 个随机字节,并将它们插入到 REDIS 哈希中。相应的 Python 会很容易编写:

#!/usr/bin/perl
################################################################################
# generator <number of images> <image size in bytes>
# Mark Setchell
# Generates and sends "images" of specified size to REDIS
################################################################################
use strict;
use warnings FATAL => 'all';
use Redis;
use Time::HiRes qw(time);

my $Debug=1; # set to 1 for debug messages

my $nargs = $#ARGV + 1;
if ($nargs != 2) {
print "Usage: generator <number of images> <image size in bytes>\n";
exit 1;
}

my $nimages=$ARGV[0];
my $imsize=$ARGV[1];
my @bytes=(q(a)..q(z),q(A)..q(Z),q(0)..q(9));
my $bl = scalar @bytes - 1;

printf "DEBUG: images: $nimages, size: $imsize\n" if $Debug;

# Connection to REDIS
my $redis = Redis->new;
my $start=time;

for(my $i=0;$i<$nimages;$i++){
# Generate our 600 byte "image"
my $image;
for(my $j=0;$j<$imsize;$j++){
$image .= $bytes[rand $bl];
}
# Load it into a REDIS hash called 'im' indexed by an integer number
$redis->hset('im',$i,$image);
print "DEBUG: Sending key:images, field:$i, value:$image\n" if $Debug;
}
my $elapsed=time-$start;
printf "DEBUG: Sent $nimages images of $imsize bytes in %.3f seconds, %d images/s\n",$elapsed,int($nimages/$elapsed)

因此,您可以将每张 600 字节的 650,000 张图像插入到名为“im”的 REDIS 哈希中,该哈希由一个简单的数字 [1..650000] 索引。

现在,如果您停止 REDIS 并检查数据库的大小,它是 376MB:

ls -lhrt dump.rb

-rw-r--r-- 1 mark admin 376M 29 May 20:00 dump.rdb

如果您现在杀死 REDIS,然后重新启动它,启动和加载 650,000 个图像数据库需要 2.862 秒:

redis-server /usr/local/etc/redis.conf

_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 3.2.9 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 33802
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'

33802:M 29 May 20:00:57.698 # Server started, Redis version 3.2.9
33802:M 29 May 20:01:00.560 * DB loaded from disk: 2.862 seconds
33802:M 29 May 20:01:00.560 * The server is now ready to accept connections on port 6379

因此,您可以在重启后 3 秒内启动 REDIS。然后你可以像这样查询和加载 650,000 张图像:

#!/usr/bin/perl
################################################################################
# reader
# Mark Setchell
# Reads specified number of images from Redis
################################################################################
use strict;
use warnings FATAL => 'all';
use Redis;
use Time::HiRes qw(time);

my $Debug=0; # set to 1 for debug messages
my $nargs = $#ARGV + 1;
if ($nargs != 1) {
print "Usage: reader <number of images>\n";
exit 1;
}

my $nimages=$ARGV[0];

# Connection to REDIS
my $redis = Redis->new;
my $start=time;

for(my $i=0;$i<$nimages;$i++){
# Retrive image from hash named "im" with key=$1
my $image = $redis->hget('im',$i);
print "DEBUG: Received image $i\n" if $Debug;
}
my $elapsed=time-$start;
printf "DEBUG: Received $nimages images in %.3f seconds, %d images/s\n",$elapsed,int($nimages/$elapsed)

在我的 Mac 上,这会在 61 秒内读取 650,000 张图像,每张图像 600 字节,因此您的总启动时间为 64 秒。

抱歉,我对 Python 的了解还不够多,无法在 Python 中完成,但我怀疑时间会非常相似。

我主要使用名为“im”的 REDIS 散列,使用 hsethget 并通过一个简单的整数索引图像。但是,REDIS key 是二进制安全的,因此您可以使用文件名而不是整数作为 key 。您还可以在命令行中与 REDIS 交互(无需 Python 或 Perl),因此您可以在命令行中获取 650,000 个键(文件名)的列表:

redis-cli <<< "hkeys im"

或检索单个图像(使用 key/filename="1"):

 redis-cli <<< "hget 'im' 1"

如果你没有bash,你可以这样做:

echo "hget 'im' 1" | redis-cli

echo "hkeys im" | redis-cli

我刚刚阅读了有关持久化/序列化 Numpy 数组的内容,因此这可能是一个比涉及 REDIS 更简单的选择... see here .

关于python - 重启后如何在python中更快地执行opencv cv2 imread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44243974/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com