Python 多元优化-scipy.optimize输入解析错误
我将上面的rgb图像保存为Python 多元优化-scipy.optimize输入解析错误,python,image,numpy,math,least-squares,Python,Image,Numpy,Math,Least Squares,我将上面的rgb图像保存为tux.jpg。现在我想得到这个图像最接近的近似值,它是两个向量的外积,即A·BT形式 这是我的密码- #load image to memory import Image im = Image.open('tux.jpg','r') #save image to numpy array import numpy as np mat = np.asfarray(im.convert(mode='L')) # mat is a numpy array of dimensi
tux.jpg
。现在我想得到这个图像最接近的近似值,它是两个向量的外积,即A·BT形式
这是我的密码-
#load image to memory
import Image
im = Image.open('tux.jpg','r')
#save image to numpy array
import numpy as np
mat = np.asfarray(im.convert(mode='L')) # mat is a numpy array of dimension 354*300
msizex,msizey = mat.shape
x0 = np.sum(mat,axis=1)/msizex
y0 = np.sum(mat,axis=0)/msizey
X0 = np.concatenate((x0,y0)) # X0.shape is (654,)
# define error of outer product with respect to original image
def sumsquares(X):
""" sum of squares -
calculates the difference between original and outer product
input X is a 1D numpy array with the first 354 elements
representing vector A and the rest 300 representing vector B.
The error is obtained by subtracting the trial $A\cdot B^T$
from the original and then adding the square of all entries in
the matrix.
"""
assert X.shape[0] == msizex+msizey
x = X0[:msizex]
y = X0[msizex:]
return np.sum(
(
np.outer(x,y) - mat
)**2
)
#import minimize
from scipy.optimize import minimize
res = minimize(sumsquares, X0,
method='nelder-mead',
options={'disp':True}
)
xout = res.x[:msizex]
yout = res.x[msizex:]
mout = np.outer(xout,yout)
imout= Image.fromarray(mout,mode='L')
imout.show()
结果是
我觉得这个不够好。有什么办法可以改进这一点吗?输出中的噪声甚至与原始图片中的结构长度不同。我的猜测是算法没有通过。如何调试或改进此功能
编辑1:我用代码创建了下面的图像
size = 256
mat0 = np.zeros((size,size))
mat0[size/4:3*size/4,size/4:3*size/4] = 1000
#mat0[size/4:3*size/4,] = 1000
#mat0[:3*size/4,size/4:] = 1000
im0 = Image.fromarray(mat0)
im0.show()
注释掉的两行将生成另外两个图像。这是我的实验结果-
在正方形中间。
输入-输出-相同 在中间带。 输入-
输出-
输出-
minimize
函数的参数是我认为它们的意思 1)在从numpy数组到图像的转换过程中,第一个图像的渲染问题似乎是一个问题。我通过运行以下命令获得正确的渲染:
imout = Image.fromarray(mout/np.max(mout)*255)
(即,将图像规格化为最大值255,并让其自动确定模式)
通常,要检查Image.fromarray是否正常工作,比较imout.show()的输出与
你应该得到同样的结果。顺便说一句,通过这样做,我得到了所有其他3个案例的正确答案
2) 其次,tux.png的主要问题是,仅用两个一维向量的外积无法重建具有如此详细结构的图像
(这通常适用于简单的图像,如上面所示的块状图像,但不适用于对称性少、细节多的图像)
为了证明这一点:
- 存在允许将矩阵重构为两个低秩矩阵M=AB的乘积的矩阵分解技术,例如
- 在这种情况下,将A和B的秩设置为1相当于您的问题(使用不同的优化技术)
- 使用下面的代码,您可以很容易地看到,如果n_分量=1(相当于两个1-D向量的外积),生成的重构矩阵看起来与方法输出的矩阵非常相似,并且n_分量越大,重构效果越好
import matplotlib.pyplot as plt
from sklearn.decomposition import NMF
nmf = NMF(n_components=20)
prj = nmf.fit_transform(mat)
out = prj.dot(nmf.components_)
out = np.asarray(out, dtype=float)
imout = Image.fromarray(out)
imout.show()
为了便于说明,这是一个分量的NMF重建(这正是两个一维向量之间的外积):
由两部分组成:
这是由20个部件组成的NMF重建
这清楚地表明,一个单一的1-D外部产品是不够的图像。但是,它适用于块状图像
如果你不局限于向量的外积,那么矩阵分解可以是一种替代方法。顺便说一句,存在大量的矩阵分解技术。sklearn中的另一个选择是
3) 最后,x0和y0中可能存在缩放问题。注意,np.outer(x0,y0)的元素比mat的元素高几个数量级
虽然我仍然使用提供的代码对3个块状示例获得了很好的结果,但一般来说,在计算平方差时使用可比较的尺度是一个很好的实践。例如,您可能希望缩放x0和y0,以便np.outer的范数与mat的范数相当 1)在从numpy数组到图像的转换过程中,第一个图像的渲染问题似乎是一个问题。我通过运行以下命令获得正确的渲染:
imout = Image.fromarray(mout/np.max(mout)*255)
(即,将图像规格化为最大值255,并让其自动确定模式)
通常,要检查Image.fromarray是否正常工作,比较imout.show()的输出与
你应该得到同样的结果。顺便说一句,通过这样做,我得到了所有其他3个案例的正确答案
2) 其次,tux.png的主要问题是,仅用两个一维向量的外积无法重建具有如此详细结构的图像
(这通常适用于简单的图像,如上面所示的块状图像,但不适用于对称性少、细节多的图像)
为了证明这一点:
- 存在允许将矩阵重构为两个低秩矩阵M=AB的乘积的矩阵分解技术,例如
- 在这种情况下,将A和B的秩设置为1相当于您的问题(使用不同的优化技术)
- 使用下面的代码,您可以很容易地看到,如果n_分量=1(相当于两个1-D向量的外积),生成的重构矩阵看起来与方法输出的矩阵非常相似,并且n_分量越大,重构效果越好
import matplotlib.pyplot as plt
from sklearn.decomposition import NMF
nmf = NMF(n_components=20)
prj = nmf.fit_transform(mat)
out = prj.dot(nmf.components_)
out = np.asarray(out, dtype=float)
imout = Image.fromarray(out)
imout.show()
为了便于说明,这是一个分量的NMF重建(这正是两个一维向量之间的外积):
由两部分组成:
这是由20个部件组成的NMF重建
这清楚地表明,一个单一的1-D外部产品是不够的图像。但是,它适用于块状图像
如果你不局限于向量的外积,那么矩阵分解可以是一种替代方法。顺便说一句,存在大量的矩阵分解技术。sklearn中的另一个选择是
3) 最后,x0和y0中可能存在缩放问题。注意,np.outer(x0,y0)的元素比mat的元素高几个数量级
虽然我仍然得到了3块示例的好结果