亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Cython 循環遍歷像素仍然很慢

使用 Cython 循環遍歷像素仍然很慢

海綿寶寶撒 2021-09-14 09:54:09
我在常規 python 代碼之間沒有速度差異。它說瓶頸是 html 文件中的最后兩行代碼。有沒有辦法解決?我想要做的是遍歷像素并將 rgb 值低于 210 的坐標添加到列表中。from PIL import Imageimport numpy as npimport timeimport cythonimport cv2filename = "/home/user/PycharmProjects/Testing/files/file001.png"image = Image.open(filename)size = width, height = image.sizeimage_data = np.asarray(image)cdef list list_text = []@cython.boundscheck(False)cpdef get_image_data():    cdef int y, x    for y in range(1683):        for x in range(1240):            if image_data[y, x] < 210:                list_text.append([x, y])
查看完整描述

2 回答

?
白板的微信

TA貢獻1883條經驗 獲得超3個贊

循環沒有任何問題,但將列表附加到列表非常慢。為了避免這種情況,您可以為數據分配一個足夠大的數組并在之后縮小它(或將數據復制到具有您需要的確切大小的數組中),或者您可以使用std:vector.


在這個答案中我使用,Numba因為我在高性能 Cython 編碼方面沒有經驗,但 Cython 實現應該是直接的。Numba 也有一個有限的列表和元組內部表示,但我不知道 Cython 中是否可用。


例子


import numpy as np

import numba as nb


@nb.njit()

def get_image_data_arr(image_data):

  array_text = np.empty((image_data.shape[0]*image_data.shape[1],2),dtype=np.int64)

  ii=0

  for y in range(image_data.shape[0]):

    for x in range(image_data.shape[1]):

      if image_data[y, x] < 210:

        array_text[ii,0]=x

        array_text[ii,1]=y

        ii+=1

  return array_text[:ii,:]


@nb.njit()

def get_image_data(image_data):

  list_text = []

  for y in range(image_data.shape[0]):

    for x in range(image_data.shape[1]):

      if image_data[y, x] < 210:

         #appending lists

         list_text.append([x, y])

         #appending tuples

         #list_text.append((x, y))

  return list_text

時間安排


所有時間都沒有編譯開銷(第一次調用函數被排除在時間之外)。


#Create some data

image_data=np.random.rand(1683*1240).reshape(1683,1240)*255

image_data=image_data.astype(np.uint8)



get_image_data (Pure Python)                   : 3.4s

get_image_data (naive Numba, appending lists)  : 1.1s

get_image_data (naive Numba, appending tuples) : 0.3s

get_image_data_arr:                            : 0.012s

np.argwhere(image_data<210)                    : 0.035s


查看完整回答
反對 回復 2021-09-14
?
HUWWW

TA貢獻1874條經驗 獲得超12個贊

我建議使用 Numpy 的argwhere()函數如下:


import numpy as np


# Create a starting image

im = np.arange(0,255,16).reshape(4,4)                                                      

看起來像這樣:


array([[  0,  16,  32,  48],

       [ 64,  80,  96, 112],

       [128, 144, 160, 176],

       [192, 208, 224, 240]])

現在找到所有小于 210 的元素的坐標:


np.argwhere(im<210)  

看起來像這樣:


array([[0, 0],

       [0, 1],

       [0, 2],

       [0, 3],

       [1, 0],

       [1, 1],

       [1, 2],

       [1, 3],

       [2, 0],

       [2, 1],

       [2, 2],

       [2, 3],

       [3, 0],

       [3, 1]])


查看完整回答
反對 回復 2021-09-14
  • 2 回答
  • 0 關注
  • 233 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號