Unable to use multiplication with grayscale image matrix - image

I am quite new to matlab/octave. I loaded an image using imread() function of octave. I tried to perform multiplication operation on the matrix but get the following error:
binary operator `*' not implemented for `uint8 matrix' by `matrix' operations
Is there another way to input the image??

I=imread('...');
I=rgb2gray(I);
I=double(I);
% you can perform the multiplication operation now

This usually means that you are trying to multiply arrays of different data types. The easiest thing to do here is to convert the uint8 image into double. You can either use the double() function, which will just cast the values, or us im2double(), which will also normalize the values to be between 0 and 1.

If you're trying to multiple two images (I'm guessing that's what you're trying to do since the error is for multiplying matrices and not a matrix by a scalar), you should use the immultiply function which handles different classes for you.
Simply, use immultiply (imgA, imgB) and never again worry about what class are imgA and imgB. Note that you'll need the image package installed in loaded.

Related

Multiplying matrices across tenor axis with numpy and with GPU

I have a matrix X with shape (F,T,M). I wish to multiply each (T,M) matrix along the F axis so that the answer will be of shape (M,M,F). This code does the job for me but this operation repeats many times and it is very slow:
for f in range(F):
output[:,:,f] = np.matmul(X[f,:,:].T,X[f,:,:])
All I could find is np.tensordot() function. If I understand correctly, this is not a good option for me since I need a matrix multiplication and not a dot product.
How do I implement this efficiently using numpy? Is it possible and beneficial to utilize keras\tf for this purpose?
We can use np.matmul/# opeartor in Python 3.x after extending dimensions -
np.matmul(X.swapaxes(1,2),X).swapaxes(0,2)
(X.swapaxes(1,2)#X).swapaxes(0,2)
Alternatively, with np.einsum with a direct translation off the shape variables used for the string notation -
np.einsum('ftm,ftn->mnf',X,X)

Inpainting in multiple channels

I have a 3d matrix A=[mXnXl], which I want to inpaint, using a mask of mask=[mXn].
So each slice along the "l" is a 2D image (0-255 RGB range). I care about continuity along that axis as also along the 3rd dimenbtison.
I use the inpainting with the two following forms
im1=inpaint.inpaint_biharmonic(np.uint8(A), np.uint8(mask), multichannel=True)
for i in range(0,l):
im2[:,:,i]=inpaint.inpaint_biharmonic(np.uint8(A[:,:,i]), np.uint8(mask), multichannel=False)
How is the 3rd dimension handled in the algorithm? Will they produce the same results?
You can look at the source code of the function here:
https://github.com/scikit-image/scikit-image/blob/c221d982e493a1e39881feb5510bd26659a89a3f/skimage/restoration/inpaint.py#L76
As you can see in the for-loop in that function, the function is just doing the same thing as your for-loop, so the results should be identical.

How to use the placeholders in tensoflow to take an arbitrary matrix?

I am new to using Tensorflow.
I have two matrices that I want to take as input:
and my output matrix is as such:
When I do:
import tensorflow as tf
matrix1 = tf.placeholder();
matrix2 = tf.placeholder();
output_matrix = tf.placeholder();
is that enough? I do not know how I can define the shape of the matrix and the dtype if the matrices are arbitrary?
It's fine to leave the shape unspecified for a placeholder; you'll be able to feed anything that works with the downstream ops. Dtype will default to float32. But you do need to specify a sequence of transformations which go from your inputs (placeholders) to your outputs (not placeholders); see https://www.tensorflow.org/get_started/mnist/mechanics#build_the_graph.
If it's easier, you can also get started with eager execution, then switch to graph building later.

How to change dynamic range of an RGB image?

I have 16-bit raw image (12 effective bits). I convert it to rgb and now I want to change the dynamic range. I created 2 map functions. You can see them visualized below. As you can see the first function maps values 0-500 to 0-100 and the second one maps the rest values to 101-255.
Now I want to apply the map-functions on the rgb image. What I'm doing is iterating through each pixel, find appropriate function for each channel and apply it on the channel. For example, the pixel is RGB=[100 2000 4000]. On R channel I'll apply the first function since 100 is in 0-500 range. But, on G and B channels I'll apply the second function since their values are in 501-4095.
But, in doing this way I'm actually changing the actual color of the pixel since I apply different functions on the channels of the pixel.
Can you suggest how to do it or at least give me a direction or show some articles?
What you're doing is a very straightforward imaging operation, frequently applied in image and video processing. Sometimes it's (imprecisely) called a lookup table (LUT), even though it's not always implemented via an actual lookup table. Examples of this are gamma adjustment or log encoding.
For instance, an example of this kind of encoding is sRGB, which is a gamma encoding from linear light. You can read about it here: http://en.wikipedia.org/wiki/SRGB. You'll see that it has a nonlinear adjustment.
The name LUT implies a good way of doing it. If you can make your image a uint8 or uint16 valued set, you can create a vector of desired output values for any input value. The lookup table has the same number of elements as the possible range of the variable type. If you were using a uint8, you'd have a lookup table of 256 values. Then the lookup is easy, you just use the image value as an index into your LUT to get the resulting value. That computational efficiency is why LUTS are so widely used.
In your case, since you're working in RGB space, it is acceptable to apply the curves in exactly the same way to each of the three color channels. RGB space is nice for that reason. However, for various reasons, sometimes different LUTs are implemented per-channel.
So if you had an image (we'll use one included in MATLAB and pretend it's 12 bit by scaling it):
someimage = uint16(imread('autumn.tif')).*16;
image(someimage.*16); % Need to multiply again to display 16 bit data scaled properly
For your LUT, you would implement this as:
lut = uint8([(0:500).*(1/5), (501:4095).*((255-101)/(4095-501)) + 79.5326]);
plot(lut); %Take a look at the lut
This makes the piecewise calculation you described in your question.
You could make a new image this way:
convertedimage = lut(double(someimage)+1);
image(convertedimage);
Note that because MATLAB indexes with doubles--one based--you need to cast properly and add one. This doesn't slow things down as much as you may think; MATLAB is made to do this. I've been using MATLAB for decades and this still looks odd to me.
This method lets you get fancy with the LUT creation (logs, exp, whatever) and it still runs very fast.
In your case, your LUT only needs 4096 elements since your input data is only 12 bits. You may want to be careful with the bounds, since it's possible a uint16 could have higher values. One clean way to bound this is to use the min and end functions:
convertedimage = lut(min(double(someimage)+1, end));
Now, this has implemented your function, but perhaps you want a slightly different function. For instance, a common function of this type is a simple gamma adjustment. A gamma of 2.2 means that the incoming image values are scaled by taking them to the 1/2.2 power (if scaled between 0 and 1). We can create such a LUT as follows:
lutgamma = uint8(256.*(((0:4095)./4095).^(1/2.2)));
plot(lutgamma);
Again, we apply the LUT with a simple indexing:
convertedimage = lutgamma(min(double(someimage)+1, end));
And we get the following image:
Using a smooth LUT will usually improve overall image quality. A piecewise linear LUT will tend to cause the resulting image to have odd discontinuities in the shaded regions.
These are so common in many imaging systems that LUTs have file formats. To see what I mean, look at this LUT generator from a major camera company. LUTs are a big deal, and it looks like you're on the right track.
I think you are referring to something that Photoshop calls "Enhance Monochromatic Contrast", which is described here - look at "Step 3: Try Out The Different Algorithms".
Basically, I think you find a single min from all the channels and a single max from across all 3 channels and apply the same scaling to all the channels, rather than doing each channel individually with its own min and max.
Alternatively, you can convert to Lab (Lightness plus a and b) mode and apply your function to the Lightness channel (without affecting the a and b channels which hold the colour information) then transform back to RGB, your colour unaffected.

Matrix calculations in rails app

In my rails app I need to do the following:
Create a form for inputting the data for a 4x4 matrix, store this data in a model
Use a ruby matrix for calculating the cholesky decomposition of this matrix, and then displaying the resulting decomposed matrix in a view
From what I understand the form data is stored in a 1-dimensional array, I need the data stored in a 4x4 array but I haven't seen any examples of this. What is the best way to do this?
You may want to look at the following tools:
standard Matrix class
ruby gsl gem
extendmatrix gem

Resources