ojAlgo - Multiply 2x2 matrix by 1x1 vector? - ojalgo

I'm new to ojAlgo. What is the best way to multiply a 2x2 matrix by a 2x1 vector? Can I use the PrimitiveMatrix class or does this require using Arrays? Please provide an example.

Related

Why do we normalize homography or fundamental matrix?

I want to know about why do we normalize the homography or fundamental matrix? Here is the code in particular.
H = H * (1.0 / H[2, 2]) # Normalization step. H is [3, 3] matrix.
I can understand that we have to normalize the data before computing SVD because of instability caused by linear least squares but why do we normalize it in end?
A homography in 3D space has 8 degrees of freedom by definition, mapping from one plane to another using perspective. Such a homography can be defined by giving four points, which makes eight coordinates (scalars).
A 3x3 matrix has 9 elements, so it has 9 degrees of freedom. That is one degree more than needed for a homography.
The homography doesn't change when the matrix is scaled (multiplied by a scalar). All the math works the same. You don't need to normalize your homography matrix.
It is a good idea to normalize.
For one, it makes the arithmetic somewhat tamer. Have some wikipedia links to fields of study because weaving all these into a coherent sentence... doesn't add anything:
Numerical analysis, Condition number, Floating-point arithmetic, Numerical error, Numerical stability, ...
Also, normalization makes the matrix easier for humans to interpret. The most common normalization is to scale the matrix such that the last element becomes 1. That is convenient because this whole math happens in a projective space, where the projection causes points to be mapped to the w=1 plane, making vectors have a 1 for the last element.
How is the homography matrix provided to you?
For example, in the scene that some library function calculates and provides the homography matrix to you,
if the function specification doesn't mention about the scale...
In an extreme case, the function can be implemented as:
Matrix3x3 CalculateHomographyMatrix( some arguments )
{
Matrix3x3 H = ...; //Homogoraphy Calculation
return Non_Zero_Random_Value * H; //Wow!
}
Element values may become very large or very small and using such values to your process may cause problems (floating point computation errors).

Are Wavelet Coefficients simply the pixel values of decomposed image in 2D Discrete Wavelet Transform

I've been working with Discrete Wavelet Transform, I'm new to this theory. I want to access and modify the wavelet coefficients of the decomposed image, Are those wavelet coefficients simply the pixel values of the decomposed image in 2D DWT?
This is for example the result of DWT Decomposition:
So, when I want to access and modify the Wavelet Coefficients, can I just iterate through the pixel values of above image? Thank you for your help.
No. The image is merely illustrative.
The image you are looking on does not exactly correspond to original coefficients. The original wavelet coefficients are real numbers. Unlike them, you are looking on their absolute values quantized into a range from 0 to 255.
It is not true that the coefficients were calculated as pairwise sums and differences of the input samples. The coefficients were calculated using two complementary filters. See the description here. However, it is essential that these coefficients were adjusted and it is no longer possible to synthesize the original image. If you need to synthesize the image, you cannot access the pixels of the referenced image.

How can I use the output 3x3 matrix from getPerspectiveTransform in OpenCV?

I'm now trying to analyze the perspective transform/homography matrix between two images capturing the same object (e.g., a rectangle) but at different perspectives/shooting angles. The perspective transform can be derived by using the function getPerspectiveTransform in OpenCV 2.3.1. I want to find the corresponding rotation and translation matrices.
The output of getPerspectiveTransform is a 3x3 matrix which I can directly use it to warp the source image into the target image. But my question is that how I can find the rotation and translation matrices based on the obtained 3x3 matrix?
I was looking into the funciton decomposeProjectionMatrix for the corresponding rotation and translation matrices. But the input is required to be a 3x4 projection matrix. How can I relate the perspective transformation (i.e., a 3x3 matrix) to the 3x4 projection matrix? Am I on the right track?
Thank you very much.
The information contained in the homography matrix (returned from getPerspectiveTransform) is not enough to extract rotation/translation. The missing column is key to correctly find the angles.
The good news is that in some scenarios, you can use the solvePnP() function to extract the desired parameters from two sets of points.
Also, this question is about the same thing you are asking for. It should help
Analyze camera movement with OpenCV

Dilate/erode modify kernel option

I want to smooth the contour of binarized images and think that erode is the best way to do it. I know that normal way of work is use cvDilate(src, dst, 0, iter); where 0 is a 3x3 matrix.
Problem is 3x3 matrix makes a deep erode in my images. How can I do a erode with a 2x2 matrix or anything smaller than the default 3x3 matrix.
Here you have for your reference the results of using different kernels:
Saludos!
If your goals is to have a binarized image with smooth edges then, if you have the original, it is better to use something like a gaussian blur with cvSmooth() on that before performing the binarization.
That said, you are not restricted to 3x3 kernels. cvDilate() takes an IplConvKernel produced by CreateStructuringElementEx and you can make a structuring element with any (rectangular) shape with that function.
However, a structuring element works relative to an anchor point that must have integer coordinates, so if you use a 2x2 matrix the matrix can not be centered around the pixel. so in most cases it is best to use structuring elements with an odd number of rows and collumns.
What you could do is create a 3x3 structuring element where only the center value and the values directly above, below, left and to the right of that are 1 like such:
0 1 0
1 1 1
0 1 0
rather than the default:
1 1 1
1 1 1
1 1 1
The first kernel will make for some slightly smoother edges.
Here's a quick and dirty approach to tell you whether dilation/erosion will work for you:
Upsample your image.
Erode (dilate, open, close, whatever) with the smallest filter you can use (typically 3x3)
Downsample back to the original image size
With the C API, you can create a dedicated IplConvKernel object of any kind and size with the function CreateStructuringElementEx(). If you to use the C++ API (function dilate()), the structuring element used for dilation is any matrix (Mat) you want.
A kernel with all 1's is a low pass convolution filter. A dilation filter replaces each pixel in the 3X3 region with the darkest pixel in that 3x3 region. An erosion filter replaces each pixel in the 3X3 region with the lightest pixel in that 3x3 region. That is if your background is light and your foreground object is dark. If you flip your background and foreground, then you would also flip your dilation and erosion filter.
Also if you want to perform an 'open' operation, you perform an erosion followed by a dilation. Conversely a 'close' operation is a dilation followed by an erosion. Open tends to remove isolated clumps of pixels and close tends to fill in holes.
Errosion and dilation matrices should be odd order
-- a 2*2 matrix cannot be used
convolution matrices should be of the order 1*1 3*3 5*5 7*7 ... but ODD
try to apply close - Erode then dilate the image operation - use the cvMorpologyEx() function

gaussian blur with FFT

im trying to implement a gaussian blur with the use of FFT and could find here the following recipe.
This means that you can take the
Fourier transform of the image and the
filter, multiply the (complex)
results, and then take the inverse
Fourier transform.
I've got a kernel K, a 7x7 Matrix
and a Image I, a 512x512 Matrix.
I do not understand how to multiply K by I.
Is the only way to do that by making K as big as I (512x512) ?
Yes, you do need to make K as big as I by padding it with zeros. Also, after padding, but before you take the FFT of the kernel, you need to translate it with wraparound, such that the center of the kernel (the peak of the Gaussian) is at (0,0). Otherwise, your filtered image will be translated. Alternatively, you can translate the resulting filtered image once you are done.
Another point: for small kernels not using the FFT may actually be faster. A 2D Gaussian kernel is separable, meaning that you can separate it into two 1D kernels for x and y. Then instead of a 2D convolution, you can do two 1D convolutions in x and y directions in the spatial domain. For smaller kernels that may end up being faster than doing the convolution in the frequency domain using the FFT.
If you are comfortable with pixel shader and if FFT is not your main goal here, but convolution with gaussian blur kernel IS,- then i can recommend my tutorial on what convolution is
regards.

Resources