I am new to Matlab, can anyone help me to find the equivalent opencv method for the matlab method "m = size(X,dim)"". It would also be better if i get to know what it does? The online documents are not helpful for my little knowledge. Thanks
Update:
What is the role of Dim "m = size(X,dim)" and how it works. For the image(x) size of 200 * 200 , if i pass dim=1, i get m=1 in matlab and if i pass dim =2 , then i get 40. Can you pl explain.
Code:
image = 'D:\Proposals\others\test_some_title1.jpg'
top=size(image,2)
As to your code:
image = 'D:\Proposals\others\test_some_title1.jpg'
top=size(image,2)
image here is not an image. It is a string containing a file name (which happens to be an image, but the size function doesn't know that). The string is indeed 40 characters long, hence the result. To actually read in an image, use imread.
Also, image itself is a function in MATLAB. If you make a variable called image it will stop you using the function properly (this is the source of a lot of MATLAB errors).
Your title pretty much answers how to access the dimension. You use the size command. I'm not even sure why this question was even asked. http://www.mathworks.com/help/matlab/ref/size.html. Doing a Google search, this was the first link that came up.
Referring to your code
You did not read in the image properly. You are checking the size of the string that contains the filename. You didn't read in the image itself. Call imread first via:
im = imread('D:\Proposals\others\test_some_title1.jpg');
Now do:
top = size(im, 2);
The reason why you get a 1 x 40 size is because your filename string is 40 characters long.
Also, referring to what #nkjt said, you should not shadow over the image command with a variable called image. image is used to take a matrix and display it on the screen as an image. Bear in mind this is not the same as imshow. Suggest you change the variable name to something like im like what I did.
I got your point. Because this function "m = size(X,dim)" finds the size of each dimension of your matrix X, you get answer 1 when you input dim = 1, and 40 when you input dim = 2.
your input message 'D:\Proposals\others\test_some_title1.jpg' is read as a matrix. It has one row and 40 columns. So dimension of X will be 1x40.
To answer your question, what I understood is the matrix X now has dimension 1x40. one row and 40 columns. if you want to know the size of first dimension, you type m = size(X,1). You will get m = 1. For the second dimension which is 40, you type m= size(X,2), you will get 40. Because this matrix X has only two dimension, if you type a number greater than 2, matlab will return default value 1. You don't care about that!
Related
I created binarized images by using the Otsu methode in Matlab and cut out parts of the resulting image using a function. Now i want to take a look at these images with the VolumeViewer command. I know the x,y and z dimensions of the resulting imgages. I currently run this code doing it(excluding the volumeViewerwhich happens after the loop):
files= {'C3\C3_000mal_550_539_527.raw';...
};
for i=1:numel(files)
Image = fopen(files{i},'r');
ImageData{i} = fread(Image,Inf,'uint16=>uint16');
ImageData{i} = reshape(ImageData{i},550,539,[]);
fclose(openedCrystalImage);
end
Using this code runs into the following error using reshape:
Error using reshape
Product of known dimensions, 296450, not divisible into total number of elements, 78114575.
I did the maths and 550*539=296450 and 296450 * 527=156229150: If we divide the last number by the number of elements it equals 2 and thus is divisible into the total number of elements. In my opinion the reshape function is not able to find the size of the last dimension or defines it as 1.
Defining the size of z also results in an error suggesting using the brackets [], so the function can find it.
Error using reshape
Number of elements must not change. Use [] as one of the size inputs to automatically calculate the appropriate size
for that dimension.
Now to the weird part. This code works for another set of images, with diffrent sizes of the x,y and z ranges. So don´t know where the issue lies to be frank. So i would really appreciate and Answer to my question
I figured it out. The error lies here:
ImageData{i} = fread(Image,Inf,'uint16=>uint16');
Apparently by saving them as .raw before it converts the image to an 8 bit file rather than 16 bits it had before. Therefore, my dimension is double the size of the number of elements. With this alteration it works:
ImageData{i} = fread(Image,Inf,'uint8=>uint8');
The reason i was able to look at the other pictures was that the z range was divisble by 2.
So the reshape function was not the problem but size of the integer data while creating the array for the variable ImageData.
P.S. I just started out programming so the accuracy in the answer should be taken with a grain of salt
I have a dataset of n nifti (.nii) images. Ideally, I'd like to be able to get the value of the same voxel/element from each image, and apply a function to the n data points. I'd like to do this for each voxel/element across the whole image, so that I can reconvert the result back into .nii format.
I've used the Tools for NIfTI and ANALYZE image toolbox to load my images:
data(1)=load_nii('C:\file1.nii');
data(2)=load_nii('C:\file2.nii');
...
data(n)=load_nii('C:\filen.nii');
From which I obtain a struct object with each sub-field containing one loaded nifti. Each of these has a subfield 'img' corresponding to the image data I want to work on. The problem comes from trying to select a given xyz within each img field of data(1) to data(n). As I discovered, it isn't possible to select in this way:
data(:).img(x,y,z)
or
data(1:n).img(x,y,z)
because matlab doesn't support it. The contents of the first brackets have to be scalar for the call to work. The solution from googling around seems to be a loop that creates a temporary variable:
for z = 1:nz
for x = 1:nx
for y = 1:ny
for i=1:n;
points(i)=data(i).img(x,y,z);
end
[p1(x,y,z,:),~,p2(x,y,z)] = fit_data(a,points,b);
end
end
end
which works, but takes too long (several days) for a single set of images given the size of nx, ny, nz (several hundred each).
I've been looking for a solution to speed up the code, which I believe depends on removing those loops by vectorisation, preselecting the img fields (via getfield ?)and concatenating them, and applying something like arrayfun/cellfun/structfun, but i'm frankly a bit lost on how to do it. I can only think of ways to pre-select which themselves require loops, which seems to defeat the purpose of the exercise (though a solution with fewer loops, or fewer nested loops at least, might do it), or fun into the same problem that calls like data(:).img(x,y,z) dont work. googling around again is throwing up ways to select and concatenate fields within a struct, or a given field across multiple structs. But I can't find anything for my problem: select an element from a non-scalar sub-field in a sub-struct of a struct object (with the minimum of loops). Finally I need the output to be in the form of a matrix that the toolbox above can turn back into a nifti.
Any and all suggestions, clues, hints and help greatly appreciated!
You can concatenate images as a 4D array and use linear indexes to speed up calculations:
img = cat(4,data.img);
p1 = zeros(nx,ny,nz,n);
p2 = zeros(nx,ny,nz);
sz = ny*nx*nz;
for k = 1 : sz
points = img(k:sz:end);
[p1(k:sz:end),~,p2(k)] = fit_data(a,points,b);
end
I have a matlab script for 8-bit image analysis and I'm trying to enhance objects in the image by subtracting the background with no objects present. What I want to do at a pixel level is:
if B-I>50 then E=I
else E=255-B-I
Where, B is the background, I the image and E my enhanced image. I know I can do this by looping through each element of the image matrix by the following:
diff=imsubtract(B,I);
nrows=1024;
ncols=1360;
for r=1:nrows
for c=1:ncols
if diff(r,c)>50
E=I(r,c);
else
E=255-diff(r,c);
end
end
end
But is this rather slow when going multiple images. I've also tried the follow:
E=255-diff;
E(diff>50)=I;
But receive the following error:
In an assignment A(I) = B, the
number of elements in B and I must
be the same.
Any tips on optimizing this would be greatly apprenticed!
In an assignment A(I) = B, the number of elements in B and I must be
the same.
The reason for this error is that you are trying to assign all the content of I to a subset of E (those pixels where diff>50). You have to specifically tell MATLAB that you want those pixels set to the matching pixels in I.
E(diff>50)=I(diff>50);
Incidentally you should be careful using imsubtract here. For pixels where I has a higher value than B, that will result in zeros (if your values are uint8). It may be okay (not 100% clear if you're looking for the absolute difference or really just where B is larger than I)
What if you use use find()
ind = find(B-I>50)
E(ind) = I(ind)
% And then the ones that are not `B-I>50`
E(~ind) = 255-B(~ind)-I(~ind)
Try this vectorized approach that uses logical indexing. I could not test it out on images though, so would be great if that's taken care of.
Code
diff1=double(imsubtract(B,I));
E = double(I).*(diff1>50) + (255-diff1).*(diff1<=50);
You might be needed to convert the datatype back to unsigned integer formats as used for images.
What is the difference between hist and imhist functions in Matlab? I have a matrix of color levels values loaded from image with imread and need to count entropy value of the image using histogram.
When using imhist the resulting matrix contains zeros in all places except the last one (lower-right) which contains some high value number (few thousands or so).
Because that output seems to be wrong, I have tried to use hist instead of imhist and the resulting values are much better, the matrix is fulfilled with correct-looking values instead of zeros.
However, according to the docs, imhist should be better in this case and hist should give weird results..
Unfortunately I am not good at Matlab, so I can not provide you with better problem description. I can add some other information in the future, though.
So I will try to better explain my problem..I have an image, for which I should count entropy and few other values (how much bytes it will take to save that image,..). I wrote this function and it works pretty well
function [entropy, bytes_image, bytes_coding] = entropy_single_pixels(im)
im = double(im);
histg = hist(im);
histg(histg==0) = [];
nzhist = histg ./ numel(im);
entropy = -sum(nzhist.*log2(nzhist));
bytes_image = (entropy*(numel(im))/8);
bytes_coding = 2*numel(unique(im));
fprintf('ENTROPY_VALUE:%s\n',num2str(entropy));
fprintf('BYTES_IMAGE:%s\n',num2str(bytes_image));
fprintf('BYTES_CODING:%s\n',num2str(bytes_coding));
end
Then I have to count the same, but I have to make "pairs" from pixels which are below each other. So I have only half the rows and the same count of columns. I need to express every unique pixel pair as a different number, so I multiplied the first one by 1000 and added the second one to it... Subsequently I need to actually apply the same function as in the first example, but that is the time, when I am getting weird numbers from the imhist function. When using hist, it seems to be OK, but I really don't think that behavior is correct, so that must be my error somewhere. I actually understand pretty good, to what I want to do, or at least I hope so, but unfortunately Matlab makes all that kind of hard for me :)
hist- compute histogram(count number of occurance of each pixel) in color image.........
imhist- compute histogram in two dimensional image.
Use im2double instead of double if you want to use imhist. The imhist function expects double or single-precision data to be in the [0,1] data range, which is why you see everything in the last bin of the histogram.
Below is part of the code that i tried to edit from, MATLAB's deconvolucy.
it appears to have problem with DAMPAR where the class type does not match.
can anyone help or does anyone know a better way to call in an image that I (as in deconvolucy.m) would tolerate?
[perhaps i should convert the image into array before use? how do i do so?]
// -- code -- //
I = imread('C:\Users\Lem\Desktop\III\TIFF\69_M.000.tif', 'tif');
class(I)
PSF = fspecial('gaussian',7,10);
V = .0001;
BlurredNoisy = imnoise(imfilter(I,PSF),'gaussian',0,V);
WT = zeros(size(I));
WT(5:end-4,5:end-4) = 1;
J1 = deconvlucy(BlurredNoisy,PSF);
J2 = deconvlucy(BlurredNoisy,PSF,20,sqrt(V));
J3 = deconvlucy(BlurredNoisy,PSF,20,sqrt(V),WT);
//.........//
??? Error using ==> deconvlucy>parse_inputs at 316
In function deconvlucy, DAMPAR has to be of the same class as the input image.
Error in ==> deconvlucy at 102
[J,PSF,NUMIT,DAMPAR,READOUT,WEIGHT,SUBSMPL,sizeI,classI,numNSdim]=...
You have read in an image using imread. So it is probably coming in as uint8? The help for imread says the result will be integer of some order for a tiff image. What class was I when it was returned?
You then filtered the image. It appears that imfilter will return an integer image for an integer input image.
Next, you add noise, using imnoise. From the online help for imnoise, it internally converts the image to a [0,1] (double) number, adds the Gaussian noise, then converts back to integer output. So your blurred image should still be integer, probably uint8 elements.
The help for fspecial says it will return a double precision output for PSF.
You called deconvolucy with only two arguments, so it is using the default value for DAMPAR. (I'll argue that this should not fail here. The author of deconvolucy appears not to have supplied a default value that was consistent in type with the inputs.)
Not knowing enough about the IPT or deconvolucy, I might first suggest re-running this code, using two different calls.
J1 = deconvlucy(BlurredNoisy,PSF,[],0);
J1 = deconvlucy(BlurredNoisy,PSF,[],uint8(0));
If one of these calls did not fix the problem, it suggests that deconvolucy expects a double input for the image, BlurredNoisy. The online help for deconvolucy was not specific here. It says only that I may be an N dimensional array or a cell array. Further on in the help, it calls the result a numeric array. So I believe that the image for deconvolucy is expected to be a floating point image. (By my standards, this is a flaw in the help.)
I would then probably try scaling your image to [0,1] as a double. It is just a guess however. So something like:
BlurredNoisy = double(BlurredNoisy)/255;
This assumes your image was uint8 in class originally.