我的目标是并行一组一维高斯适合于一组列在一个图像。我使用的是模块多进程,而不是多进程,因为我无法找到将数组作为函数参数传递的方法。现在一切都好了。
但是,一旦我在被腌制的函数中使用了curve_fit (或者,在本例中是the .),我就有问题了。如果我注释掉curve_fit部分,只返回初始的猜测参数,这一切都很好。但是,当我在for循环中处理数据时,我无法处理curve_fit RuntimeError,如下所示:
try:
params, _ = curve_fit(gauss1d,x,a,p0=guess)
params[3]=np.abs(params[3])+0.5
except RuntimeError:
params = [1,1,1,1]
相反,如果fit不收敛,池将抛出此错误:
文件"blablabla\lib\site-packages\multiprocess\pool.py",第771行,在get raise self._value中
错误:函数调用的结果不是一个正确的浮点数数组。
ValueError:对象太深,无法满足所需数组的要求
这要归功于这个小家伙:文件"blablabla\lib\site-packages\scipy\optimize\minpack.py",第423行,在最少的function = _minpack._lmdif(func,x0,args,full_output,ftol,xtol,minpack.error)中:函数调用的结果不是一个正确的浮动数组。
我相信我是达到最大值函数的水平和获得ValueError,但我的例外是不再处理池内的原因,无论什么原因。也有可能我在追一条红鲱鱼。
下面是完整代码。添加额外的异常(如ValueError)不会改变任何事情。所有的输入都很感谢。
def processframe(framey):
import numpy as np
import scipy.ndimage as nd
from scipy.optimize import curve_fit
sizey = framey.shape
paramsy = np.zeros([sizey[1],4])
columnsy = np.split(framey,sizey[1],axis=1)
if __name__ == '__main__':
import numpy as np
def thefit(k):
def gfit1d(a): #simple 1d gaussian fit. Fast. Effective. Uses 1d gauss stats to set initial parameters
def gguess1d(a): #This assumes a single gaussian 1d distribution on approximately the scale of a bright image (0 to 255), and returns stats for a 1d distribution, using physics rules (width is 1/e^2 radius)
x=np.linspace(1,np.amax(a.shape),np.amax(a.shape),endpoint=True)
fata = nd.gaussian_filter1d(a,2)
GuessY0 = np.amin(a)
GuessA = np.amax(a)-GuessY0
X0A = np.amax(fata)
X0Y0 = np.amin(fata)
X0form = np.multiply(fata+X0Y0,(fata+X0Y0>(X0A+X0Y0)/3))
GuessX0 = np.sum(np.multiply(X0form,x))/(1+np.sum(X0form))
GuessSigma = np.sqrt(np.sum(np.square(np.multiply(x-GuessX0,np.multiply(a-GuessY0,a-GuessY0>2))))/(1+np.sum(np.multiply(a-GuessY0,a-GuessY0>2))))/4
solution=np.asarray([GuessY0, GuessA, GuessX0, GuessSigma])
return np.nan_to_num(np.real(solution.flatten()))
therange = np.amax(a)-np.amin(a)
size = np.amax(a.shape)
x=np.linspace(1,size,size,endpoint=True)
guess =np.nan_to_num(np.real( gguess1d(a))).flatten()
def gauss1d(x,aa,bb,cc,dd):
return aa+bb*np.exp(-2*(x-cc)**2/(np.abs(dd)+0.5)**2)+2000*(cc<1)*(1-cc)**2+2000*(cc>size)*(cc-size)**2+2000*(np.abs(aa-bb)>3*therange)*(np.abs(aa-bb)-3*(therange)**2)
try:
params, _ = curve_fit(gauss1d,x,a,p0=guess)
params[3]=np.abs(params[3])+0.5
except RuntimeError:
params = [1,1,1,1]
return np.nan_to_num(np.real(np.asarray(params.flatten())))
"""
return guess
"""
global paramsyk
class paramsyk: pass
try:
paramsyk=gfit1d(k)
except RuntimeError:
#print(curse())
paramsyk=np.array([1,1,1,1])
return np.asarray(paramsyk.flatten())
# multiprocessing.set_start_method('spawn')
# q=multiprocess.Queue(columnsy)
pool=multiprocess.Pool(2)
paramsy = pool.map(lambda x: np.asarray(thefit(columnsy[x])).flatten(), range(sizey[1]))
pool.close
pool.join
return np.transpose(np.stack(paramsy,axis=1))
发布于 2022-06-24 17:31:55
中编译任何东西时
paramsy = pool.map(lambda x: np.asarray(thefit(columnsy[x])).flatten(), range(sizey[1]))
成功的编译本身就是一个错误。所有的东西都需要在兰博达内定义,
def processframefitmulti(framey):
t=time.time()
import numpy as np
import scipy.ndimage as nd
from scipy.optimize import curve_fit
sizey = framey.shape
if __name__ == '__main__':
def thefit(k):
import warnings
warnings.filterwarnings("ignore")
import numpy as np
import scipy.ndimage as nd
kk=np.array(k).flatten() #This step is critical to this implementation, as it turns the object from a list back into an np array
#do some stuff
columnsy = np.split(framey,sizey[1],axis=1)
pool=multiprocess.Pool(3)
mange=multiprocess.Manager()
dataset=mange.list(columnsy)
paramsy=pool.map(thefit,dataset)
pool.close
pool.join
return np.stack(paramsy)
的形式在多处理池中处理。
try:
params, _ = curve_fit(gauss1d,x,a,p0=guess)
params[3]=np.abs(params[3])+0.5
except Exception as e:
params = [1,1,1,1]
除了e:在多线程应用程序中非常关键,可以防止整个事件停止运行。
https://stackoverflow.com/questions/72695011
复制相似问题