Transforming an image using a known displacement field with imwarp in matlab - image

I wish to transform an image using a known displacement field but am having issues using the imwarp function for this. Any help would be very very appreciated
I use a grid in order to project an image onto a known plane. By detecting the location of the grid points in the image and comparing them to the location in "real" space I am able to come up with a matrix, D_OH, of size [m, n, 2] which represents the x and y displacements required.
I use the line:
OH_grid_avg_mapped = imwarp(OH_grid_avg_post, D_OH)
but get the following errors:
Error using imwarp
Expected tform to be one of these types:
images.geotrans.internal.GeometricTransformation
Instead its type was double.
Error in imwarp>validateTform (line 367)
validateattributes(t,{'images.geotrans.internal.GeometricTransformation'},{'scalar','nonempty'},'imwarp','tform');
Error in imwarp>preparseSpatialReferencingObjects (line 384)
validateTform(tform);
Error in imwarp (line 136)
[R_A, varargin] = preparseSpatialReferencingObjects(varargin{:});
Error in VizExpt_SchlierenOHAlign_v7 (line 261)
OH_grid_avg_mapped = imwarp(OH_grid_avg_post, D_OH);"

Related

Error trying to plot 2 images with different size using matlab

I have 2 images that I need to plot in one figure then display the points of interest found with SURF on both images:
Image 1 : size [6113x5693x3]
Image 2 : size [4896x3744x3]
when trying to plot both of images in one figure with this code:
I = zeros([size(I1,1) size(I1,2)*2 size(I1,3)]);
I(:,1:size(I1,2),:)=I1;
I(:,size(I1,2)+1:size(I1,2)+size(I2,2),:)=I2;
figure, imshow(I); hold on;
and to display the points of interest of each one of them with :
plot([Pos1(:,2) Pos2(:,2)+size(I1,2)]',[Pos1(:,1) Pos2(:,1)]','-');
plot([Pos1(:,2) Pos2(:,2)+size(I1,2)]',[Pos1(:,1) Pos2(:,1)]','o');
I get this error and I dont know how to fixed :
Subscripted assignment dimension mismatch.
Any suggestion will be welcome!
Walk through this line by line. The error occurs on line 3. You are trying to assign I2 (with dimension 4896x3744x3) to a select part of I that has an incorrect first dimension (since the first dimension of I is the same as I1, not I2).
size(I(:,size(I1,2)+1:size(I1,2)+size(I2,2),:)) = [ 6113 3744 3 ]
size(I2) = [4896 3744 3]

Matlab smoothing

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);

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');

Matlab: Coding with arrays and writing data to excel sheet

I have obtained blood vessels of an eye in an image variable ves. I found the number of connected components(8-connectivity) as blobs. For each blob I need to calculate the Area, Major axis length and Centroid and store these values in a matrix testfv (each row corresponding to each property).For a single blob, Area returns a 1x1 struct, Centroid returns a 1x2 struct, and MajorAxisLength returns a 1x1 struct. So ,I guess depending on the number of blobs the number of cells required to store the values of Areas, Centroids and MajorAxisLength's vary, so using just one testfv to store these values as I have done would be wrong.
Is it possible? This is the code I tried(i assumed that testfv has 25 columns which allows me to store upto 8 blobs info)
[labeledImage numberOfBlobs] = bwlabel(ves, 8);
col=numberOfBlobs*2;
testfv = zeros(3,col);
for i=1:col
blobMeasurements = regionprops(labeledImage, 'Area');
testfv(1,col) = [blobMeasurements.Area];
blobMeasurements = regionprops(labeledImage, 'MajorAxisLength');
testfv(2,col)= [blobMeasurements.MajorAxisLength];
blobMeasurements = regionprops(labeledImage, 'Centroid');
testfv(3,col) = [blobMeasurements.Centroid];
end
I am getting the following error....
??? Subscripted assignment dimension mismatch.
Error in ==> alpha1 at 191 <br/>
testfv(1,col) = [blobMeasurements.Area];
Also, I need to write the data of the testfv matrix to an excel sheet file. How do I that ?
Would really appreciate the help as I am new to Matlab.

d3.js: why is d3.geo.path() giving NaN?

I am trying to do some online mapping with d3, but running into a problem when I try to plot a line between two points.
I have calculated the centroid of two polygons (source and target)
In the code:
var projection = d3.geo.mercator()
.scale(width)
.translate([0, 0]);
var path = d3.geo.path()
.projection(projection);
From the JS console:
> path({type: "LineString",
coordinates: [path.centroid(source_country), path.centroid(target_country)]});
"M277.05056877663407,121.67976219138909L-694.1792414247936,NaN"
Yet, the centroid calculations seem to be working fine (plotting those points shows them on the map)
> [path.centroid(source_country), path.centroid(target_country)]
[
Array[2]
0: 103.89396329123777
1: -41.453727169465765
length: 2
__proto__: Array[0]
,
Array[2]
0: -260.3172155342976
1: -245.57309459883245
length: 2
__proto__: Array[0]
Any ideas why that NaN is appearing at the end of the path generated for my LineString?
The problem here is that you're projecting the lat/lon coordinates twice. The path() operator expects to take lat/lon and project to pixels; the path.centroid() method also expects a lat/lon geometry, and also produces a pixel-based projection.
So when you call path on [path.centroid(...), path.centroid(...)], you're trying to project already-projected coordinates. You get at NaN because the y-position of the pixel coordinates, -245, is out of bounds for a longitude value.
The easiest way to fix this is probably to use d3.svg.line to create the centroid-centroid path. I haven't tested this, but I think it would look like:
var line = d3.svg.line();
line([path.centroid(source_country), path.centroid(target_country)]);
OK just now I met the same error,
for anyone who meet NAN problem:
the format of coordinate must be correct. e.g. for type Polygon, the coordinate must have a 3-level nested array. e.g. [[[1,2],[2,3]]]
coordinates must be float/integer, but not string (e.g. 1 correct, "1" error )
you can inspect the detailed content of the error result, e.g. M...L...Z... and find out where the error is.

Resources