当前位置: 首页 > 面试题库 >

在python中仅加载图像的一部分

暴骏奇
2023-03-14
问题内容

这可能是一个愚蠢的问题,但是…

我有几千张图像要加载到Python中,然后转换为numpy数组。显然,这进行得有点慢。但是,我实际上只对每个图像的一小部分感兴趣。(同一部分,图像中心仅100x100像素。)

有什么方法可以只加载图像的一部分以使处理速度更快吗?

这是一些示例代码,在这些代码中,我生成了一些示例图像,将其保存,然后将它们加载回。

import numpy as np
import matplotlib.pyplot as plt
import Image, time

#Generate sample images
num_images = 5

for i in range(0,num_images):
    Z = np.random.rand(2000,2000)
    print 'saving %i'%i
    plt.imsave('%03i.png'%i,Z)

%load the images
for i in range(0,num_images):
    t = time.time()

    im = Image.open('%03i.png'%i)
    w,h = im.size
    imc = im.crop((w-50,h-50,w+50,h+50))

    print 'Time to open: %.4f seconds'%(time.time()-t)

    #convert them to numpy arrays
    data = np.array(imc)

问题答案:

将文件另存为未压缩的24位BMP。这些以非常规则的方式存储像素数据。从Wikipedia中检出此图的“图像数据”部分。请注意,图中的大多数复杂性仅来自标题:

例如,假设您正在存储此图像(此处显示为放大):

如果将其存储为24位未压缩的BMP,则像素数据部分的外观将是这样。请注意,由于某种原因,数据是以自下而上的方式存储的,并且以BGR格式而不是RGB格式存储,因此文件中的第一行是图像的最底行,第二行是倒数第二行,等等:

00 00 FF    FF FF FF    00 00
FF 00 00    00 FF 00    00 00

该数据的解释如下:

           |  First column  |  Second Column  |  Padding
-----------+----------------+-----------------+-----------
Second Row |  00 00 FF      |  FF FF FF       |  00 00
-----------+----------------+-----------------+-----------
First Row  |  FF 00 00      |  00 FF 00       |  00 00
-----------+----------------+-----------------+-----------

要么:

           |  First column  |  Second Column  |  Padding
-----------+----------------+-----------------+-----------
Second Row |  red           |  white          |  00 00
-----------+----------------+-----------------+-----------
First Row  |  blue          |  green          |  00 00
-----------+----------------+-----------------+-----------

在那里填充可以将行大小填充为4字节的倍数。

因此,您要做的就是为这种特定的文件格式实现阅读器,然后计算必须开始和停止读取每一行的字节偏移量:

def calc_bytes_per_row(width, bytes_per_pixel):
    res = width * bytes_per_pixel
    if res % 4 != 0:
        res += 4 - res % 4
    return res

def calc_row_offsets(pixel_array_offset, bmp_width, bmp_height, x, y, row_width):
    if x + row_width > bmp_width:
        raise ValueError("This is only for calculating offsets within a row")

    bytes_per_row = calc_bytes_per_row(bmp_width, 3)
    whole_row_offset = pixel_array_offset + bytes_per_row * (bmp_height - y - 1)
    start_row_offset = whole_row_offset + x * 3
    end_row_offset = start_row_offset + row_width * 3
    return (start_row_offset, end_row_offset)

然后,您只需要处理适当的字节偏移即可。例如,假设您要读取10000x10000位图中从位置500x500开始的400x400块:

def process_row_bytes(row_bytes):
    ... some efficient way to process the bytes ...

bmpf = open(..., "rb")
pixel_array_offset = ... extract from bmp header ...
bmp_width = 10000
bmp_height = 10000
start_x = 500
start_y = 500
end_x = 500 + 400
end_y = 500 + 400

for cur_y in xrange(start_y, end_y):
    start, end = calc_row_offsets(pixel_array_offset, 
                                  bmp_width, bmp_height, 
                                  start_x, cur_y, 
                                  end_x - start_x)
    bmpf.seek(start)
    cur_row_bytes = bmpf.read(end - start)
    process_row_bytes(cur_row_bytes)

请注意,处理字节非常重要。您可能可以使用PIL做一些聪明的事情,然后将像素数据转储到其中,但是我不确定。如果您以低效的方式进行操作,则可能不值得。如果速度是一个非常大的问题,您可以考虑使用pyrex编写它,或在C中实现以上内容,然后从Python调用它。



 类似资料:
  • Picasso只在我的RecolyerView中的最后一个项目上加载缩略图。我使用了firebase RecolyerAdapter;这就是它看起来的样子 如我的代码所示,我将用户名文本设置为图像url以检查真正发生了什么,令我惊讶的是,图像url被正确地检索到了每个ItemView。 这是日志 @覆盖公共视图onCreateView(LayoutInflater inflater,ViewGro

  • 问题内容: 假设我想要一种只显示HTML中250x250像素的图像的中心50x50像素的方法。我怎样才能做到这一点。另外,有没有办法对css:url()引用执行此操作? 我知道CSS中的 clip ,但这似乎仅在与绝对定位一起使用时才起作用。 问题答案: 一种方法是在容器(td,div,span等)中将要显示的图像设置为背景,然后调整背景位置以获取所需的精灵。

  • 下面是我的代码: 只是一个加载图像的文件。 我得到以下错误: 以下是完整的代码:

  • 我正在尝试制作一款包含来自存储或网络的无限图像的应用程序。但问题是,recyclerview的滚动速度非常慢 我如何在我的应用程序中创建图像列表,如gallery、whats应用程序、instagram等 我想让我的应用程序运行得非常平稳 请帮帮我! 适配器代码 :

  • 所以我是python的初学者,正在尝试制作仪表板。 我有一个文件夹,上面有我上传的照片。 结构: 我应该如何设置,以便我可以加载图片并将其放入

  • 问题内容: 当我尝试在applet浏览器中运行applet时,无法找到资源(图像)。我尝试像这样加载资源: 但是当我在appet查看器中运行它时,路径是这样的:imgPath:file:D:/Work/app/build/classes/com/blah/Images/a.png 虽然此路径中有图像,但前缀文件是:导致问题,我该如何测试此代码? 当部署在服务器中并且代码库返回服务器URL时,此代码