Finding rank of image using nuclear norm optimization with linear constraints

92 Views Asked by At

I'm trying to follow the theory laid out by the paper Recht, Benjamin; Fazel, Maryam; Parrilo, Pablo A., Guaranteed minimum-rank solutions of linear matrix equations via nuclear norm minimization to find the rank of the image below but it seems like I'm getting stuck with the linear constraint I'm supposed to be defining.

The image

The approach that I'm taking is minimizing $Tr(w_1)+Tr(w_2)$ s.t. $\begin{bmatrix} w_1&-X/2\\-X^{T}/2&w_2\end{bmatrix} \ge 0$ which is basically minimizing $||X||_*$ and adding a constraint $AX=b$ where A is a normal matrix (which according to the paper follows RIP and hence this should guarantee the solution to be the minimum rank).

Here is the MATLAB CVX code I'm running to accomplish the above:

X = imread('Lit Review/MIT_logo.png');
X = imresize(X,0.25); % To reduce computation time
X = imbinarize(X);
X = double(X);

rank(X)

m = size(X,1);
n = size(X,2);

% Creating a low-rank A just to see whether the output is throwing the rank of A
l_rank = 7; 
p = 12;
A = normrnd(0,1/p,p,l_rank)*normrnd(0,1/p,m*n,l_rank)';
b = A*X(:);

cvx_begin
    variable X_test(m,n)
    minimize(norm_nuc(X_test))
    subject to       
        A*X_test(:) == b;
cvx_end

Firstly, the rank MATLAB is giving for this image is 6 (it should be 4, I checked the SVD and it does have 6 non-zero elements, I'm not sure what's the reason behind this)

Secondly, the output comes around 14 to 15 which is nowhere close to the rank of any matrix whatsoever (the reason I created A to be of rank 7 was to see whether the output was due to its rank). Why isn't this working?

EDIT: Someone asked why the image should have a rank of 4. I'm attaching an image with red stripes depicting the distinct rows (at least according to me)

enter image description here

MATLAB is showing the rank of the above image to be 6 and the rank of X_test to be 166:

rank(X)

ans =

     6

rank(X_test)

ans =

   166

s(1:6) % s = svd(X)

ans =

  156.0389
   42.5381
   35.1799
   19.6956
    1.3728
    0.9778

s_test(1) % s_test = svd(X_test)

ans =

   15.9525

I tried sum(svd(X)==0) & sum(svd(X_test)==0) and both of them are giving 0, but after individually printing them out the 7th element of svd(X) is $2.4266e-13$ and the last element is $2.8205e-175$ (which show up in the matrix as 0.000 due to precision loss).

Plot of svd(X)(7:166): enter image description here

Plot of svd(X_test)(2:166): enter image description here