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

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

Python 3.7:多處理具有共享變量的 for 循環

Python 3.7:多處理具有共享變量的 for 循環

RISEBY 2021-11-16 16:42:02
首先是一些上下文:我正在嘗試寫下一個 python 腳本,將灰度 (.tif) 中的圖像轉換為具有所謂“jet”顏色圖的 .jpeg。我設法用 for 循環來做到這一點,但對于一張圖像(處理數百萬像素?。﹣碚f有點長,所以我想使用多處理。我的問題是,要將每個灰色像素轉換為彩色像素,我必須使用兩個變量(光強度的最小值“min_img”和向量“dx_cm”從初始灰度到 256比例,對應于 jet 顏色圖)。因此,為了將“min_img”和“dx_cm”的信息傳遞給進程,我嘗試使用 multiprocessing.Value() 但作為回報,我得到了錯誤:RuntimeError: Synchronized objects should only be shared between processes through inheritance我嘗試了來自不同來源的許多不同的東西,無論我的代碼版本如何,我都在為該錯誤而苦苦掙扎。因此,如果我的代碼不干凈,我很抱歉,如果有人可以幫助我,我將不勝感激。我的非工作代碼:import multiprocessingfrom PIL import Imagefrom matplotlib import cmdef fun(gr_list,dx,minp):    dx_cmp = dx.value    min_imgp = minp.value    rgb_res=list()    for i in range(len(gr_list)):        rgb_res.extend(cm.jet(round(((gr_list[i]-min_imgp)/dx_cmp)-1))[0:-1])    return rgb_resif __name__ == '__main__':    RGB_list=list()    n = multiprocessing.cpu_count()    img = Image.open(r'some_path_to_a.tif')    Img_grey=list(img.getdata())    dx_cm = multiprocessing.Value('d',(max(Img_grey)-min(Img_grey))/256)    min_img = multiprocessing.Value('d',min(Img_grey))    with multiprocessing.Pool(n) as p:        RGB_list = list(p.map(fun, (Img_grey,dx_cm,min_img)))    res = Image.frombytes("RGB", (img.size[0], img.size[1]), bytes([int(0.5 + 255*i) for i in RGB_list]))        res.save('rgb_file.jpg')PS:這是我想要并行化的初始 for 循環的示例:from PIL import Imagefrom matplotlib import cmif __name__ == '__main__':    img = Image.open(r'some_path_to_a.tif')    Img_grey = list(img.getdata())    dx_cm = (max(Img_grey)-min(Img_grey))/256    min_img = min(Img_grey)    Img_rgb = list()    for i in range(len(Img_grey)):        Img_rgb.extend(cm.jet(round(((Img_grey[i]-min_img)/dx_cm)-1))[0:-1])    res = Image.frombytes("RGB", (img.size[0], img.size[1]), bytes([int(0.5 + 255*i) for i in Img_rgb]))        res.save('rgb_file.jpg')
查看完整描述

2 回答

?
梵蒂岡之花

TA貢獻1900條經驗 獲得超5個贊

您的fun方法正在遍歷某個列表,但在這種情況下,它將接收一個“部分”,即您列表中的一個項目,因此它應該只返回其處理結果。


我已將工作代碼更改為與多處理一起運行。


由于該fun方法返回一個列表,因此p.map將返回一個列表列表(結果列表)并且需要展平,extends之前使用 list方法完成。


嘗試使用進程池和線程池多處理,在我的場景中沒有任何性能提升。


進程多處理:

from PIL import Image

from matplotlib import cm

import multiprocessing



def fun(d):

    part, dx_cm, min_img = d

    return cm.jet(round(((part-min_img)/dx_cm)-1))[0:-1]


if __name__ == '__main__':

    img = Image.open(r'a.tif')

    Img_grey = list(img.getdata())


    def Gen(img_data):

        dx_cm = (max(img_data)-min(img_data))/256

        min_img = min(img_data)

        for part in img_data:

            yield part, dx_cm, min_img


    n = multiprocessing.cpu_count()

    with multiprocessing.Pool(n) as p:

        Img_rgb = [item for sublist in p.map(fun, Gen(Img_grey)) for item in sublist]


    res = Image.frombytes("RGB", (img.size[0], img.size[1]), bytes([int(0.5 + 255*i) for i in Img_rgb]))    

    res.save('b.jpg')

線程多處理:

from PIL import Image

from matplotlib import cm

import multiprocessing

from multiprocessing.pool import ThreadPool


if __name__ == '__main__':

    img = Image.open(r'a.tif')

    Img_grey = list(img.getdata())

    dx_cm = (max(Img_grey)-min(Img_grey))/256

    min_img = min(Img_grey)


    def fun(part):

        return cm.jet(round(((part-min_img)/dx_cm)-1))[0:-1]


    n = multiprocessing.cpu_count()

    with ThreadPool(n) as p:

        Img_rgb = [item for sublist in p.map(fun, Img_grey) for item in sublist]


    res = Image.frombytes("RGB", (img.size[0], img.size[1]), bytes([int(0.5 + 255*i) for i in Img_rgb]))    

    res.save('b.jpg')


查看完整回答
反對 回復 2021-11-16
?
心有法竹

TA貢獻1866條經驗 獲得超5個贊

因此,對于多處理而言,計算負擔似乎還不夠大。


盡管如此,對于那些對我的問題的圖像處理部分感興趣的主題的人,我發現了另一種更快的方法(比以前的方法快 15 到 20 倍)在沒有 for 循環的情況下做同樣的事情:


from matplotlib import cm

import matplotlib.pyplot as plt

from mpl_toolkits.axes_grid1 import make_axes_locatable

import numpy as np

from PIL import Image


cm_jet = cm.get_cmap('jet')

img_src = Image.open(r'path to your grey image')

img_src.mode='I'


Img_grey = list(img_src.getdata())

max_img = max(Img_grey)

min_img = min(Img_grey)


rgb_array=np.uint8(cm_jet(((np.array(img_src)-min_img)/(max_img-min_img)))*255)


ax = plt.subplot(111)

im = ax.imshow(rgb_array, cmap='jet')


divider = make_axes_locatable(ax)

cax_plot = divider.append_axes("right", size="5%", pad=0.05)


cbar=plt.colorbar(im, cax=cax_plot, ticks=[0,63.75,127.5,191.25,255])

dx_plot=(max_img-min_img)/255

cbar.ax.set_yticklabels([str(min_img),str(round(min_img+63.75*dx_plot)),str(round(min_img+127.5*dx_plot)),str(round(min_img+191.25*dx_plot)), str(max_img)])


ax.axes.get_xaxis().set_visible(False)

ax.axes.get_yaxis().set_visible(False)


plt.savefig('test_jet.jpg', quality=95, dpi=1000)


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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