Efficient Blending of Non-Nan-Sparse Transformed Mosaic Images in Matlab - matlab

I'm currently working on improving the blending part of the image mosaic sample application on VLfeat's homepage. In this final blending stage I want to combine two non-nan-sparse images, both being the output from two images interpolations using interp2 with nan-flag. Specifically, given two image matrices A and B and blended matrix C all of same dimension M-by-N, I want for each matrix position (i,j) in A and B want to check whehter
both A and B have a defined value in (i,j) so make C(i,j) the average of them or,
either A or B have a defined (~isnan()) value in (i,j) so put that in C(i,j) or,
neither A nor B have a defined value in (i,j) thereby leaving C(i,j) as is
assuming C is initialized to all nan values.
I haven't find a simple nor elegant way of doing this without having to
reshape A and B into vectors
find non-nan vector indexes AI=find(~isnan(A)) and BI=find(~isnan(B))
find intersection II of AI and BI
use II, AI and BI to modify a vector C of same length as A and B as mentioned in three steps above
reshape C back to M-by-N to finally get result wanted
I have tried to express the same steps using matrices and matrix indexes without success. Is this the only way of doing this in MATLAB? It seems kind of cumbersome.

Maybe I'm missing something (I do not understand why you need to reshape matrix to vectors, for example).
Anyway, here is a try:
% Unconditionnaly compute the average into temp D matrix
D=(A+B)/2;
% Restore A and B values where B and A are NaN
D(isnan(A))=B(isnan(A));
D(isnan(B))=A(isnan(B));
% Only modify C wherever the final result is not NaN
C(~isnan(D))=D(~isnan(D));

Related

swapping elements of a given symbolic matrices

So, the problem is simple to understand. Given any symbolic matrix of any dimmension I want to swap the elements in order to obtain one matrix of the same size, same elements but distributed differently.
For instance
syms a b c
A=[a b c;0 0 c]
swapping A we can get:
A=[b a c;0 c 0];
Using randperm(numel(A)) you can generate a random permutation of the numbers 1:numel(A), which are the indices in your matrix.
A(:)=A(randperm(numel(A)));
The A(:) on the left side is required to preserve the shape, otherwise you end up with a vector of the elements. If you wish to keep your matrix A unchanged:
B=A; %just to get a matrix of same size and datatype
B(:)=A(randperm(numel(A)));

MATLAB: element-wise multiplication of two matrices over one index?

I'm trying to figure out if there's a native way of obtaining a certain kind of element-wise product of two matrices in Matlab.
The product that I'm looking for takes two matrices, A and B say, and returns there product C, whose elements are given by
C(i,j,k) = A(i,j)*B(j,k)
Naturally, the number of columns of A is assumed be the same as the number of rows of B.
Right now, I'm using the following for-loop (assuming size(A,2)==size(B,1) is true). First, I initialize C:
C = zeros(size(A,1), size(A,2), size(B,2));
And then I perform element-wise multiplication via:
for i=1:size(A,2)
C(:,i,:) = A(:,i)*B(i,:);
end
So, my question is: Is there a native way to this sort of thing in Matlab?
You need to "shift" the first two dimensions of B into second and third dimensions respectively with permute and then use bsxfun with #times option to operate on A and the shifted dimension version of B -
C = bsxfun(#times,A,permute(B,[3 1 2]))

Ignore real value of imfilter in matlab

I am using imfilter in matlab to calculate convolution between two matrix A and H. My code is
B=imfilter(A,H,'replicate');
But the result B appears some complex value (Ex: 1+3i). And I want to remove complex values from matrix B (but dimemsion of B is not changed). So, my question is how to remove complex value of matrix B in matlab or similar way how to ignore them when I calculate B+C where C is input real matrix (I only want to calculate sum of real values in two matrix B and C)
You can take the real value of B using real(B).
If you want the magnitude of the entries (rather than just the real part) you can use abs(B).
To get the imaginary part you can use imag(B).
So for a complex matrix B you can decompose it using either
B = real(B) + j*imag(B);
or
B = abs(B).*exp( j*angle(B) );

How to transpose a matrix without MATLAB's transpose tool

I have an image, which I have listed as a matrix. I want to take the transpose of that image and then display that image on the screen.
I would like to know how to do this the "hard" way, ie without using MATLAB's transpose function.
function [B] = trans(A)
[r c] = size(A);
B = zeros(c,r);
for i = 1:r
for j = 1:c
B(j,i) = A(i,j)
end
end
end
As this is for a class, I won't give you an exact answer, but I will nudge you in the right direction. I'm assuming that you are looking for a method that involves manually transposing the information, rather than using builtin functions.
Matlab stores values in a matrix in the form of a vector and a "size" - for instance, a 2x3 matrix would be stored with six values in a vector, and then [2,3] (internally) to tell it that it's 2x3 and not 6x1.
For the 2x3 matrix, this is the order of the values in the vector:
1 3 5
2 4 6
To reference the value in (2,2), you can reference it as A(2,2), or as A(4). The value in (1,3) can be referenced as A(5).
As such, if you can construct a vector referencing the values in the transposed order, then you can assign the new values into the appropriate order and store them in a matrix of appropriate size. To make the point, consider the transpose of the above matrix:
1 2
3 4
5 6
This would be represented as (1,3,5,2,4,6) with size (3,2). If you can construct the vector (1,3,5,2,4,6), then you can use that vector to assign the values appropriately.
Here's hint toward a solution: The transpose transforms the element A(1,2) from the normal array A into the element B(2,1) from the transposed array B (B=A'), and vice versa. Thus, you can iterate through all the rows and column, and apply the transformation element-by-element.
Are you allowed to use flipud and fliplr ?
In this case you can represent the transposition as a sequence of flips (I'll leave it to you to figure out the exact sequence).
You can use rot90 with flipud/fliplr for this.

Converting 'labels' of matrices to matrices in Matlab

I'm trying to write a short Matlab code to perform a certain mathematical function. The code generates a vector H which has entries of either 1, 2 or 3 (and size dependent on other factors). (In my mind), the numbers 1, 2 and 3 correspond to three particular matrices. Once my program has calculated H, I would like it to be able to multiply together all the matrices represented by its entries. To clarify, if H = [1 2 3 2], I'd like my code to calculate A*B*C*B. What is the simplest way of doing this? I thought about creating a vector with entries that are matrices, and using a function that gives the product of the entries of the vector, but I couldn't get that to work (and don't know if it can work - I'm very new to Matlab).
Ideally I'd rather not rewrite the rest of my code - if there's a way to get this to work with what I've done so far then that'd be great. I'm looking for functionality as opposed to slick coding - it doesn't matter if it's clumsy, as long as it works.
#zuloos answer might be problematic if the sizes of matrices are not the same - especially if number of rows are different. Should work if you put the matrices in cells.
matrices = {A,B,C,D};
result = matrices{H(1)};
for i=2:numel(H)
result = result * matrices{H(i)};
end
put all your matrices in another matice then you can use values of H as a the key to choose the right matrice matices = [A, B, C, D]. you would then go throug H one by one and multiply it with the result of the last operation. you will start with a diagonal matrice of the same dimensions as the other matrices and multiply this in each round of the loop with the matrice in matrices coreesponding to the value of H
matrices = [A, B, C, D]
// d is dimension of your matrices (i guess they are square)
erg = diag(d)
for i=length(H):1
// supposed your matices are 2d
erg = matrices(H(i),:,:)*init
end
i dont know if it makes sense here to multiply each step from left (like you would do in openGL) but i thought this allows you split up the operation in steps (like its done in openGL)