Matlab smoothing - image

How can apply user-defined mask as a vector e.g. [1 1 1].
img=imread('xxx.jpg');
mask=[1,1,1];
f=conv2(img,mask);
"Undefined function 'conv2' for input arguments of type 'double' and attributes 'full 3d real'."

Color images are 3 dimensional arrays (x,y,color). conv2 is only defined for 2-dimensions, so it won't work directly on a 3-dimensional array.
You can use an n-dimensional convolution, convn() instead of conv2(). Another possibility is to take each color separately and do a conv2()

if you want to apply a mask to your image you can try to use the following example:
Im2 =rgb2gray (fr);
fr=Im2.*uint8(mask);

Related

Matlab: Performing operations with 'struct' in image processing

I have two images - one binarized, and one original.
I use the binarized image to segment using bwconncomp and then for every blob/region, I want to sum the pixel-intensities from the original image.
I do that by:
blobMeasurements = regionprops(binarizedImage, originalImage, 'pixelvalues');
Now, I have a struct with a 'p x 1' vector for each blob/region. I need to sum these pixel intensities, such that I have one 'sum' value for each blob/region. How do I perform this operation? Is there a better way of doing this?
Thanks.
Try this:
blobIntensities = arrayfun(#(x) sum(x.pixelvalues(:)), blobMeasurements);
arrayfun runs the given function #(x) sum(x.pixelvalues(:)) on each of the pelement of the structure array blobMeasurements. Hope this helps.

matlab: texture classification

I have a histology image like this:
From the image, we can observe there are two kinds of different cells.
and
Is there any way that I can separate these two types of cells into two groups?
How about using your raw image and previous code to achieve this?
% % % your old code
I=imread(file);
t1=graythresh(I);
k1=im2bw(I,t1);
k1=~k1;
se = strel('disk',1);
k0=imfill(~k1,'holes');
cc = conncomp(k0);
k0(cc.PixelIdxList{1})=0;
k1=imfill(k1,'holes');
mask=k0 | k1;
%%%%%%%%%%%%%%%%%%
This will give you:
I=rgb2hsv(I);
I=double(I);
I1=I(:,:,1); % again, the channel that can maximizing the margin between donut and full circle
Imask=(I1-0.2).*(I1-0.9)<0;
k2=mask-Imask;
k2=bwareaopen(k2,100);
This will give you:
k2=mask-Imask;
I2=zeros(size(I1,1),size(I1,2),3);
I2(:,:,1)=(k2==1)*255;
I2(:,:,3)=((I1-0.2).*(I1-0.9)<0)*255;
imshow(I2)
will finally give you (the two types are stored in two channels in the rgb image):
I would use regionprops
props=regionprops(YourBinaryImage, 'Solidity');
The objects with a high solidity will be the disks, those with a lower solidity will be the circles.
(Edit) More formally:
I=imread('yourimage.jpg');
Bw=~im2bw(I, 0.5);
BWnobord = imclearborder(Bw, 4); % clears the partial objects
Props=regionprops(BWnobord, 'All');
solidity=cell2mat({Props.Solidity});
Images={Props.Image};
Access the elements of Images where the value in solidity is higher than 0.9 and you get your disks. The circles are the other ones.
Hope it helps

Add two images in MATLAB

I am trying to overlay an activation map over a baseline vasculature image but I keep getting the same error below:
X and Y must have the same size and class or Y must be a scalar double.
I resized each to 400x400 so I thought it would work but no dice. Is there something I am missing? It is fairly straight forward for a GUI I am working on. Any help would be appreciated.
a=imread ('Vasculature.tif');
b = imresize (a, [400,400]);
c=imread ('activation.tif');
d= imresize (c, [400,400]);
e=imadd (b,d);
Could it be the bit depth or dpi?
I think one of your images is RGB (size(...,3)==3) and the other is grayscale (size(...,3)==1). Say the vasculature image a is grayscale and the activation image c is RGB. To convert a to RGB to match c, use ind2rgb, then add.
aRGB = ind2rgb(a,gray(256)); % assuming uint8
Alternatively, you could do aRGB = repmat(a,[1 1 3]);.
Or to put the activation image into grayscale:
cGray = rgb2gray(c);
Also, according to the documentation for imadd the two images must be:
nonsparse numeric arrays with the same size and class
To get the uint8 and uint16 images to match use the im2uint8 or im2uint16 functions to convert. Alternatively, just rescale and cast (e.g. b_uint8 = uint8(double(b)*255/65535);).
Note that in some versions of MATLAB there is a bug with displaying 16-bit images. The fix depends on whether the image is RGB or gray scale, and the platform (Windows vs. Linux). If you run into problems displaying 16-bit images, use imshow, which has the fix, or use the following code for integer data type images following image or imagesc:
function fixint16disp(img)
if any(strcmp(class(img),{'int16','uint16'}))
if size(img,3)==1,
colormap(gray(65535)); end
if ispc,
set(gcf,'Renderer','zbuffer'); end
end
chappjc's answers is just fine, I want to add a more general answer to the question how to solve the error message
X and Y must have the same size and class or Y must be a scalar double
General solving strategy
At which line does the error occur
Try to understand the error message
a. "... must have the same size ...":
Check the sizes of the input.
Try to understand the meaning of your code for the given (type of) input parameters. Is the error message reasonable?
What do you want to achieve?
Useful command: size A: returns the size of A
b. "... must have the same class ...":
Check the data types of the input arguments.
Which common data type is reasonable?
Convert it to the chosen data type.
Usefull command: whos A: returns all the meta information of A, i.e. size, data type, ...
Implement the solution: your favorite search engine and the matlab documentation are your best friend.
Be happy: you solved your problem and learned something new.
A simple code :
a=imread ('image1.jpg');
b=imresize (a, [400,400]);
subplot(3,1,1), imshow(b), title('image 1');
c=imread ('image2.jpg');
d= imresize (c, [400,400]);
subplot(3,1,2), imshow(d), title('image 2');
[x1, y1] = size(b) %height and wedth of 1st image
[x2, y2] = size(d) %height and wedth of 2nd image
for i = 1: x1
for j = 1: y1
im3(i, j)= b(i, j)+d(i, j);
end
end
subplot(3,1,3), imshow (im3), title('Resultant Image');

Converting a grayscale image to black and white

I have a grayscale image that only has the values 60 and 117. How can I convert the image to only black and white without graylevels?
I tried the matlab function gray2ind, but didn't get the expected output.
Thanks.
Try im2bw(img, level) with level = 0.5.
This is a matlab function that takes a grayscale image img, applies a threshold of level (a value between [0,1]) and returns a black and white image.
This function is part of the Image Processing Toolbox. Your case is simple enough that you could also try something like:
bwImg = false(size(img));
bwImg(img == 117) = true;
I edited the above to set values equal to false/true to more closely mimic Matlab's im2bw() which returns a matrix of logical values rather than ints.
2nd Edit: Modified the code block to reflect improvements suggested by #Amro

Recomposed matrix from Decomposed matrix doesn't match

This is a Matrix knowledge question, I am talking about XNA but only as a reference
I decomposed a matrix on XNA and got the decomposed values, then just tried to create again
the Matrix from those values and the resultant Matrix does not match the original one
I tried to Normalize the quaternion
I tried to generate a Rotation Matrix from the Quaternion
I tried swaping the order of the Transformation SRT , STR, TRS, TSR, RST, RTS
Why I am doing this? I am creating my own model importer and I am comparing my results
with XNA using the same model, so I am reading almost (some decimal difference) the same source SRT as the XNA's decomposed values, but my resultant Matrix didn't match XNA, so I went back to the basics and tried to decompose/recompose the XNA Matrix but I found it doesn't match either
These are the Original XNA Matrix values
?this.XNAModel.Bones[0].Transform
{{M11:1.331581E-06 M12:-5.551115E-17 M13:1 M14:0}
{M21:1 M22:-4.16881E-11 M23:-1.331581E-06 M24:0}
{M31:4.16881E-11 M32:1 M33:8.15331E-23 M34:0}
{M41:0.03756338 M42:37.46099 M43:2.230549 M44:1} }
Decomposition , lFlag is true
bool lFlag = this.XNAModel.Bones[0].Transform.Decompose(out lDecScale, out lDecRotation, out lDecTranslation);
//decomposed values
?lDecScale
{X:1 Y:1 Z:1}
?lDecRotation //quat
{X:-0.5000003 Y:-0.4999996 Z:-0.4999996 W:0.5000004}
?lDecTranslation
{X:0.03756338 Y:37.46099 Z:2.230549}
Recompose the matrix from the decomposed values , I've tried all the combinations SRT
//lDecRotation.Normalize();
Matrix lRecompose = Matrix.CreateScale(lDecScale) *
Matrix.CreateFromQuaternion(lDecRotation) * Matrix.CreateTranslation(lDecTranslation);
Quaternion not normalized result using SRT , doesnt' match original Matrix
?lRecompose
{{M11:1.430511E-06 M12:-5.960464E-08 M13:0.9999999 M14:0}
{M21:0.9999999 M22:1.192093E-07 M23:-1.370907E-06 M24:0}
{M31:-5.960464E-08 M32:0.9999999 M33:1.192093E-07 M34:0}
{M41:0.03756338 M42:37.46099 M43:2.230549 M44:1} }
Quaternion normalized result using SRT, doesnt' match original Matrix
?lRecompose
{{M11:1.192093E-06 M12:-5.960464E-08 M13:1 M14:0}
{M21:1 M22:-1.192093E-07 M23:-1.370907E-06 M24:0}
{M31:-5.960464E-08 M32:1 M33:-1.192093E-07 M34:0}
{M41:0.03756338 M42:37.46099 M43:2.230549 M44:1} }
This is what my model importer read
?this.ModelNew.Bones[0].Scale
{X:1 Y:1 Z:1}
?this.ModelNew.Bones[0].Rotation
{X:-0.0002303041 Y:-8.604798E-05 Z:-5.438289}
There is a small diference between this result and the Decomposed one from XNA
//My importer, based on the above Rotation Vector, converted to radians
?lQuat {X:-0.4999999 Y:-0.5 Z:-0.5 W:0.4999999}
//XNA
{X:-0.5000003 Y:-0.4999996 Z:-0.4999996 W:0.5000004}
?this.ModelNew.Bones[0 ].Translation
{X:0.03756338 Y:37.46099 Z:2.230549}
Depending on how your graphics API manages matrices, and how your modelling software exports them, you may have to transpose the matrix before decomposing it, and then transpose the result after recomposing it to get the same result as the original matrix.
By the way, the correct order for recomposing is to translate first, then rotate, then scale.

Resources