I am trying to implement compressed-sensing technique using matlab to reconstruct an image from fewer measurements.
What I've done so far is dividing the image into 8-by-8 blocks, then multiply each block by sensing matrix PHI which is Gaussian random matrix, after that decode the compressed blocks using CVX or L1 Magic.
The problem is that I don't get good results, so can someone help me please ?
example code
x=imread('greyscale_image.tiff');
x=im2double(x);
x_1blk=x(1:8,1:8);
xdct=dct2(x_1blk);
xq=xdct/quanMTX;
xq=reshape(xq,[],1);
y=phi*xq;
x0=phi.'*y;
tic
s1=l1eq_pd(x0, phi, [], y,1e-3);
toc
s1=reshape(s1,8,8);
s1=s1*quantMTX;
s1=idct2(s1);
I get around 25.000 for psnr, while I am expecting to get around 29.000
Related
I have some FID data that i can convert to FFT and can have some NMR signal. But my signal's are not that high compare to my noise in the data. I know that using SVD can solve the problem in Matlab but i need more insight how to do it. My every single NMR is a 1024x1 matrix.
I tried the SVD and didnt really found any good solution.
I took 200 projections at a step angle of 1.8 degrees using LabVIEW software. The size of the image is 2748 x 2748 pixels, uint16. Then using Matlab, I load the projection images, do the flat field correction, resize the image by 1/3 and save the images as .mat file. Then I run the code below for the filtered backprojection.
interp='linear'; %set interpolation: nearest, linear, spline, pchip, v5cubic
filter='Hann'; %set filter: Ram-Lak, Shepp-Logan, Cosine, Hamming, Hann, None
for s=1:916
for i=1:200
a(i,:)=proj065(:,s,i);
end
a=a';
%figure(3), imagesc(a)
b=iradon(a,1.8,interp,filter);
imagesc(b);
recon(:,:,s)=b;
s
clear a
end
If I used a filter in this code, I will get negative pixel values.
But, if I run the code without the filter, I will get positive pixel values.
Any idea why iradon returns negative pixel values in filtered back projection?
Thank you.
Nurul
Yes, the FBP (filtered back-projection) algorithm will do that. It can wrongly reconstruct voxels as having negative values, due to noise and discretization on the data. Nothing you can do about it than just crop those values generally.
As my PhD is about tomography reconstruction algorithms I feel contractually obligated (joking) to suggest the use of iterative algorithms to possibly obtain better images (never worse, often considerably better). Check SART/SIRT or CGLS for this problem.
However, you are calling your function wrong! In tomography, the step size is not enough to reconstruct an image, you generally need the exact angles, thus iradon doesnt accept a step size as an input, it accepts an array of angles.
in your case, theta should be theta=linspace(0,360-200/360,200), and you should call iradon(a,theta,...)
I have an image that I converted to a vector and plotted:
img = imread(image.png');
grayImage = rgb2gray(img);
grayImage(2:2:end,:)=fliplr(grayImage(2:2:end,:));
B = rot90(grayImage);
C = flipud(B);
[x,y]=size(C);
vector = reshape(C ,1,x*y);
plot(vector);
The problem is that although I can visually see a wave pattern, there is a lot of noise that occurs. By noise I mean the signals rapidly go up and down eventually forming a sinusoidal wave but I want to be able to just connect the crest of each spike to one another in order to create a continuous wave pattern. If anyone understands what I am trying to do, help would be appreciated.
Thank you in advance.
Not 100% sure about what you're asking, but the medfilt1 median filter function might be what you're looking for, it's a 1D smoothing filter. Example usage would be:
vector_filt = medfilt1(vector);
Check out the documentation and example at http://www.mathworks.com/help/signal/ref/medfilt1.html.
I think performing a gaussian convolution on the vector should solve your problem. Here is a link to a stack overflow question that has a very nice answer on how to do a gaussian convolution in matlab: Gaussian Filter on a vector in Matlab
I am trying to re-grid non-uniform data onto a uniform grid defined in a 4-D space. The data measurement is given by a function d = f(xp,yp,zp,wp), where xp, yp, zp, and wp are the 4-D coordinates. I would like to re-grid the non-uniformaly spaced xp, yp, zp, and wp onto a uniformly spaced grid of x, y , z, and w.
For ease of conversation, let's define the gridding kernel to be the product of separable Hanning kernels:
1/a(1+cos(2*pi*x/a))
1/b(1+cos(2*pi*y/b))
1/c(1+cos(2*pi*z/c))
1/d(1+cos(2*pi*w/d))
Then, I believe to re-grid what I need to do is perform a 4-D convolution and resample onto the uniform grid. However, I'm not sure how to implement this using discrete data. My questions are as follows:
1) How should I sample each of the gridding kernels? For example, should I use the non-uniform xp, yp, zp, and wp values when calculating my discrete convolution values? Or should I use the uniformly spaced values, x, y, z, and w? Or are neither of those ideas correct?
2) How can I then implement the 4-D convolutions? I think I may need to use four for loops but am not exactly sure how to organize my data, i.e., a 4-D data structure or simply a matrix with 4 columns?
I'm not interested in the fastest approach but more so in finding the most intuitive or straight forward approach.
I believe I understand the basics of sinc interpolation and gridding algorithms. I have read multiple papers including such classics by J.D. O'Sullivan and J.I. Jackson, discussing the properties and differences in different gridding kernels. I've also read some papers from MRI reconstruction that use gridding but most of these methods assume a 2-D grid.
I am at a loss of how to actually implement the method, preferably in Matlab, or else C++, in a discrete manner and even more confused how to implement such a thing in four dimensions.
I've looked at several threads and my problem is somewhat similar to these, however I want to use convolution with a general kernel, not linear interpolation, and neither of these really suggest how to organize the 4-D data or perform the convolution:
Python 4D linear interpolation on a rectangular grid
Python 4D linear interpolation on a rectangular grid
Thanks for any advice, insight, or suggestions!
Can you use the interpn function?
[X Y Z W]=ndgrid(x,y,z,w); % unequally spaced
[XR YR ZR WR]=ndgrid(x_regular,y_regular,z_regular,w_regular); % equally spaced
volume=interpn(X,Y,Z,W,d,XR,YR,ZR,WR);
The documentation for interpn and ndgrid give more details; their usage would give you a framework for how to construct d.
EDIT: Oh sorry sorry, I saw your comment about not wanting to use interpolation after posting this.
Well, you could use interpolation as above to position your values onto the grid linearly, and then use
volume=convn(volume,general_kernel);
To convolve the values with your kernel?
I was given this task, I am a noob and need some pointers to get started with centroid calculation in Matlab:
Instead of an image first I was asked to simulate a Gaussian distribution(2 dimensional), add noise(random noise) and plot the intensities, now the position of the centroid changes due to noise and I need to bring it back to its original position by
-clipping level to get rid of the noise, noise reduction by clipping or smoothing, sliding average (lpf) (averaging filter 3-5 samples ), calculating the means or using Convolution filter kernel - which does matrix operations which represent the 2-D images
Since you are a noob, even if we wrote down the answer verbatim you probably won't understand how it works. So instead I'll do what you asked, give you pointers and you'll have to read the related documentation :
a) to produce a 2-d Gaussian use meshgrid or ndgrid
b) to add noise to the image look into rand ,randn or randi, depending what exactly you need.
c) to plot the intensities use imagesc
d) to find the centroid there are several ways, try to further search SO, you'll find many discussions. Also you can check TMW File exchange for different implementations for that.