我将上面的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 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()
{a2}结果是^。在
^{pr2}$我觉得这还不够好。有什么办法可以改进吗?输出中的噪声甚至与原始图像中的结构长度不一样。我的猜测是算法无法通过。我如何调试或改进它?在
编辑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()
这两条注释掉的行产生了另外两幅图像。这是我的实验结果-
虽然这比我预期的要好得多,但案例2和3最终还是错了。我希望minimize
函数的参数能像我想的那样。在
1)第一个图像的渲染问题似乎是从numpy数组到图像的转换中的一个问题。我通过运行:
(即,将图像规格化为最大值255,并让它自动确定模式)。在
一般来说,检查一下图像.fromarray正在工作,比较imout.show公司()与
^{pr2}$你应该得到同样的结果。顺便说一句,这么做,我就把其他3个案子都搞错了。在
2)第二,主要问题是晚礼服.png是不可能用两个一维向量的外积来重建具有如此详细结构的图像。在
(这通常适用于简单的图像,如上面所示的块状图像,但对于对称性较少、细节较多的图像则不适用)。在
为了证明这一点:
现有的矩阵分解技术允许将矩阵重构为两个低秩矩阵M=AB的乘积,例如sklearn.decomposition.NMF。
在这种情况下,将A和B的等级设置为1相当于您的问题(使用不同的优化技术)。
使用下面的代码,您可以很容易地看到,当n_分量=1时(相当于两个一维向量的外积),得到的重建矩阵看起来与您的方法输出的矩阵非常相似,并且n_分量越大,重建效果越好。
再现性:
举例来说,这是具有1个分量的NMF重建(这正是两个一维向量之间的外积):
有两个组件:
这是由20个组件组成的NMF重建。在
这清楚地表明,一个单一的1-D外部产品是不够的,为这个图像。但是它对块状图像有效。在
如果你不局限于向量的外积,那么矩阵因子分解是一种替代方法。顺便说一句,存在着大量的矩阵分解技术。sklearn的另一个选择是SVD。在
3)最后,x0和y0中可能存在缩放问题。注意np.外部(x0,y0)比mat元素高一个数量级。在
虽然我在提供的代码中仍然得到了3个块状示例的良好结果,但一般来说,在计算平方差时,使用可比较的比例是一个很好的实践。例如,您可能需要缩放x0和y0,以便np.外部可与mat相提并论。在
相关问题 更多 >
编程相关推荐