這個算法是Lee和Seung在1999年發表在nature雜志上的。具體論文看這里:http://www.seas.upenn.edu/~ddlee/Papers/nmf.pdf。
看不懂英文沒關系,可以看這個中文的介紹:http://wenku.baidu.com/view/94c8af0bf78a6529647d5331.html。
原理上面兩篇文章已經很清楚了,我在按自己的理解介紹一下吧。
通常矩陣分解如svd或其他什么的分解都會把矩陣分解為有正有負的矩陣,而他的這種分解方法就把矩陣完全分解成只有正數的矩陣,因為現實世界中如圖像,負數是沒什么意義的,所以這種只分解為正數矩陣的分解方法就很有意義了,要不也不會發在nature這樣牛B的雜志上。
這里是分解的公式:
這里r是分解矩陣的秩,V是原矩陣的一個近似,W與H就是分解而成的兩個矩陣。
下面是W和H的求法,是一個迭代算法,初始的W與H是隨機的就行了:
關於代碼,我借鑒了這個博客的:http://fxy1211.blog.163.com/blog/static/68255322007826111015905/,真是太感謝這位博主了。
下面是代碼:
clear all; close all; clc; V=double(imread('lena.jpg')); imshow(mat2gray(V)); [i u]=size(V); %計算V的規格 r=100; %設置分解矩陣的秩 W=rand(i,r); %初始化WH,為非負數 H=rand(r,u); maviter=100; %最大迭代次數 for iter=1:maviter W=W.*((V./(W*H))*H'); %注意這里的三個公式和文中的是對應的 W=W./(ones(i,1)*sum(W)); H=H.*(W'*(V./(W*H))); end img_V=W*H; figure; imshow(mat2gray(img_V));
下面是原圖和重構后的效果,如果秩和迭代次數越大,那么重構后的圖越接近原圖:
原圖
重構圖
因為這個是看自己相關方向論文偶然在一篇論文的引用中看到了這個算法,所以就稍微了解了一下,肯定有不妥的地方,就這樣吧。