feature extraction using vl_feat toolbox - matlab

imshow(imread(a));
img = single(imread(a));
[f,d] = vl_phow(img);
perm = randperm(size(f,2)) ;
s = perm(1:50)
h1= vl_plotframe(f(:,s));
h2= vl_plotframe(f(:,s));
set(h1,'color','k','linewidth',3) ;
set(h2,'color','y','linewidth',2) ;
h3 = vl_plotsiftdescriptor(f(:,s),d(:,s)) ;
set(h3,'color','g') ;
But when I try to plot them using vl_plotsiftdescriptors, it gives an error.
whos
d 128x3692 uint8
f 4x3692 double
The error is:
The number of rows of D does not match the geometry of the descriptor
Could someone please help me with this?
Am I doing it the right way?
Thanks in advance.

The problem is in the line
h3 = vl_plotsiftdescriptor(f(:,s),d(:,s)) ;
with f(:,s) and d(:,s), you are loading the s-th row of f and s, while the VLFeat documentation states, that
Each column of D is the descriptor of the corresponding frame in F.
So to extract the descriptors at index s, you'll instead have to call
h3 = vl_plotsiftdescriptor(f(s,:),d(s,:)) ;
--
Additional comment: By using the second parameter (k) of randperm, you can replace
perm = randperm(size(f,2)) ;
s = perm(1:50);
by
s = randperm(size(f,2), 50);
which should be faster, as you only generate 50 random numbers, instead of generating size(f,2) numbers and discarding most of them.

Related

How to take transpose of N-D array in matlab?

I am using the following code to get all the possible combinations of the rows of a matrix.
function rComb(matrix)
rows = size(matrix,1)
for n = 1:rows
rowsCell = num2cell(matrix,2);
r = nchoosek(1:size(matrix,1),n);
out = cell2mat(reshape(rowsCell(r.',:).',n,1,[]))
end
end
Now I want to take the transpose of the out variable, and I am using this code.
function rComb(matrix)
rows = size(matrix,1)
for n = 1:rows
rowsCell = num2cell(matrix,2);
r = nchoosek(1:size(matrix,1),n);
out = cell2mat(reshape(rowsCell(r.',:).',n,1,[]))
transp = out'
end
end
And I am facing this error...!!
"Error using '
Transpose on ND array is not defined. Use PERMUTE
instead."
Can you solve this issue?
One more thing can a function give us multiple outputs like all the possible combinations of output? Like in the above code if I place ';' after out variable statement this function won't display anything :/.

How to save a numeric value in a specified location of a CSV file inside for loops in MATLAB?

I want to do this because otherwise I run out of memory to save the values in a matrix, as the dimensions of the matrix increases.
For example,
for a=1:10000
for b=1:10000
M(a,b)=rand;
end
end
Here, the system runs out of memory as it can't store a 10000x10000 matrix.
So, I want to keep writing the (a,b)'th value inside the for loops into the (a,b)'th cell of a csv file (or an xls file, whatever). How do I do that?
I want something like this:
for a=1:10000
for b=1:10000
xlswrite1('file.xls',a,b,rand); % better if I can get a solution with csvwrite, as I prefer CSVs to work with
end
end
But this obviously doesn't work. The error it gives is:
Error using evalin
Undefined function or variable 'Excel'.
Error in xlswrite1 (line 2)
Excel=evalin('caller','Excel');
Then when I add the following lines according to this article,
Excel = actxserver ('Excel.Application');
File='datafile.xls';
if ~exist(File,'file')
ExcelWorkbook = Excel.workbooks.Add;
ExcelWorkbook.SaveAs(File,1);
ExcelWorkbook.Close(false);
it gives this error:
Error using xlswrite1 (line 82)
Range argument must a string of Excel A1 notation.
Can anyone please suggest a simple solution? I can't find any from my online search so far.
You can do this using dlmwrite. But I suggest you to write row by row instead of element by element.
N = 100 ;
M = zeros(N,N) ;
filename = 'test.csv';
for a=1:N
for b=1:N
M(a,b)=rand;
end
dlmwrite(filename,M(a,:),'-append')
end
If you don't want to make a matrix M, then make rows and write them to your file:
N = 100 ;
M = zeros(1,N) ;
filename = 'test.csv';
for a=1:N
for b=1:N
M(1,b)=rand;
end
dlmwrite(filename,M(1,:),'-append')
end
I suggest using fprintf:
N = 100 ;
M = zeros(1,N) ;
filename1 = 'test1.csv';
t1 = tic ;
for a=1:N
for b=1:N
M(1,b)=rand;
end
dlmwrite(filename1,M,'-append')
end
t1 = toc(t1) ;
filename2 = 'test2.csv';
M = zeros(1,N) ;
t2 = tic ;
fid = fopen(filename2,'w') ;
for a=1:N
for b=1:N
M(1,b)=rand;
end
fprintf(fid, [repmat(' %f ', 1, N) '\n'], M') ;
end
fclose(fid) ;
t2 = toc(t2) ;
fprintf('time taken using dlmwrite:%f\n',t1)
fprintf('time taken using fprintf:%f\n',t2)

matlab vectorization if statement

Can someone please tell me the vectorized implementation of following matlab code. Predicted is an array containing either of the two values "pos" or "neg". I have to copy the values when condition comes true.
p = 1;
box = zeros(size(bbox));
for k = 1: size(predicted)
if predicted(k) == 'pos'
box(p,:) = bbox(k,:);
p = p + 1;
end
end
bbox=rand(100); %demo data
predicted = rand(1,100)>0.5; %logical values
%You want to convert your array of strings into an array of logical values
%predicted=strcmp(predicted,'pos');
box=bbox(predicted,:);

Average filter Matlab

I have written the 3x3 average filter. It works fine but it shows the same output image three times instead of one. How to resolve the problem?
The code is
function [filtr_image] = avgFilter(noisy_image)
[x,y] = size(noisy_image);
filtr_image = zeros(x,y);
for i = 2:x-1
for j =2:y-1
sum = 0;
for k = i-1:i+1
for l = j-1:j+1
sum = sum+noisy_image(k,l);
end
end
filtr_image(i,j) = sum/9.0;
filtr_image = uint8(filtr_image);
end
end
end
thanks in advance
What is most likely happening is the fact that you are supplying a colour image when the code is specifically meant for grayscale. The reason why you see "three" is because when you do this to allocate your output filtered image:
[x,y] = size(noisy_image)
If you have a 3D matrix, the number of columns reported by size will be y = size(noisy_image,2)*size(noisy_image,3);. As such, when you are iterating through each pixel in your image, in column major order each plane would be placed side by side each other. What you should do is either convert your image into grayscale from RGB or filter each plane separately.
Also, you have an unnecessary casting performed in the loop. Just do it once outside of the loop.
Option #1 - Filter per plane
function [filtr_image] = avgFilter(noisy_image)
[x,y,z] = size(noisy_image);
filtr_image = zeros(x,y,z,'uint8');
for a = 1 : z
for i = 2:x-1
for j =2:y-1
sum = 0;
for k = i-1:i+1
for l = j-1:j+1
sum = sum+noisy_image(k,l,a);
end
end
filtr_image(i,j,a) = sum/9.0;
end
end
end
end
Then you'd call it by:
filtr_image = avgFilter(noisy_image);
Option #2 - Convert to grayscale
filtr_image = avgFilter(rgb2gray(noisy_image));
Minor Note
You are using sum as a variable. sum is an actual function in MATLAB and you would be overshadowing this function with your variable. This will have unintended consequences if you have other functions that rely on sum later down the line.
I can't see why your code would repeat the image (unless it's a pattern cause by an integer overflow :/ ) but here are some suggestions:
if you want to use loops, at least drop the inner loops:
[x,y] = size(noisy_image);
filtr_image = zeros(x,y);
for i = 2:x-1
for j =2:y-1
% // you could do this in 1 line if you use mean2(...) instead
sub = noisy_image(i-1:i+1, j-1:j+1);
filtr_image = uint8(mean(sub(:)));
end
end
However do you know about convolution? Matlab has a built in function for this:
filter = ones(3)/9;
filtr_image = uint8(conv2(noisy_image, filter, 'same'));

Multipage Tiff write in MATLAB doesn't work

I'm reading in a Tiff using the below function, which works fine, but when I try to use my write function to write that same Tiff back to a different file, it's all 255's. Does anyone know how to fix this? Thanks, Alex.
function Y = tiff_read(name)
% tiff reader that works
info = imfinfo(name);
T = numel(info);
d1 = info(1).Height;
d2 = info(1).Width;
Y = zeros(d1,d2,T);
for t = 1:T
temp = imread(name, t, 'Info',info);
Y(:,:,t) = temp(1:end,1:end);
end
% Tiff writer that doesn't work
function tiff_write(Y,name)
% Y should be 3D, name should end in .tif
T = size(Y,3);
imwrite(Y(:,:,1),name);
for t = 2:T
imwrite(Y(:,:,t),name,'WriteMode','append');
end
Try using this line :
Y = zeros(d1,d2,T,'uint16');
instead of this one:
Y = zeros(d1,d2,T);
Your data are likely in uint16 format and when you export you clip the maximum value to 255 (uint8), which makes pixel with values greater than 255 (a LOT of them if your data is in uint16) appear white.
Otherwise you might want to use this line:
function tiff_write(Y,name)
% Y should be 3D, name should end in .tif
for t = 2:T
imwrite(Y(:,:,t)/255,name,'WriteMode','append');
end