Where can I find the source codes of built-in functions (INTERPOLATE, GRID_TPS and TRIGRID) of IDL? - built-in

I need to convert my IDL source code, which uses the WARP_TRI function, to MATLAB. WARP_TRI takes two (large) arrays of input/output 2D point coordinates and an input image to warp it using the two coordinate arrays as control points.
Is there a way to realize an equivalent function in MATLAB?

I found that the following example demonstrates equivalent functions in MatLab.
sqsize = 60;
I = checkerboard(sqsize,4,4);
nrows = size(I,1);
ncols = size(I,2);
fill = 0.3;
movingPoints = [0 0; 0 nrows; ncols 0; ncols nrows;];
fixedPoints = [0 0; 0 nrows; ncols 0; ncols*1.8 nrows*1.5];
t_piecewise_linear = fitgeotrans(movingPoints,fixedPoints,'pwl');
I_piecewise_linear = imwarp(I,t_piecewise_linear,'FillValues',fill);
imshow(I_piecewise_linear)
title('Piecewise Linear')

Related

How do I normalize the signal generated from wfbm in matlab?

I am using matlab's wavelet fractional Brownian motion function in order to generate 1D point-like data of a diffusive particle in the physical regimes: sub-diffusion, super-diffusion and normal diffusion.
The problem I encounter with is that the time normalization/variance is weird.
For example for Hurst parameter equals 0.5 (regular Brownian motion) I get standard deviation which isn't unity (1):
>> std(diff(wfbm(0.5,1e6)))
ans =
0.3955
Due to the above, I am not sure how to re-normalize all the 3 trajectories I create for the 3 diffusion cases (sub, super, normal).
I generated trajectories for N pointlike particles of length M:
M=500;
N=200;
nd = zeros(M,N);
sub = zeros(M,N);
sup = zeros(M,N);
Hsub = 0.25;
Hsup = 0.75;
for j=1:N
nd(:,j) = wfbm(0.5, M, 15, 'db10');
sub(:,j) = wfbm(Hsub,M, 10, 'db10');
sup(:,j) = wfbm(Hsup,M, 10, 'db10');
end
Here is how function is implemented in matlab and generates the signal, however I am not sure how to modify it to have a proper brownian motion:
tmp = conv(randn(1,len+nbmax),ckbeta);
tmp = cumsum(tmp);
CA = wkeep(tmp,len,'c');
for j=0:nblev-1
CD = 2^(j/2)*4^(-s)*2^(-j*s)*randn(1,len);
len = 2*len-nbmax;
CA = idwt(CA,CD,fs1,gs1,len);
end
fBm = wkeep(CA,L,'c');
fBm = fBm-fBm(1);
I was trying to understand it from the paper which says it's possible to control the variance of fBm:
This is citation 7 from the snapshot above.

2D Image transformations by pixel

I am trying to do a translation, euclidian, similarity, affine and projective transformation on an image pixel by pixel. the input for my program is the image name and the transformation matrix.
This is my code
function imagetrans(name, m)
Image = imread(name);
[rows, cols] = size(Image);
newImage(1:rows,1:cols) = 1;
for row = 1 : rows
for col = 1 : cols
if(Image(row,col) == 0)
point = [row;col;1];
answer = m * point;
answer = int8(answer);
newx = answer(1,1);
newy = answer(2,1);
newImage(newx,newy) = 0;
end
end
end
imshow(newImage);
end
This is the image
Right now I am testing just a translation matrix.
matrix =
1 0 7
0 1 2
0 0 1
when I pass the image and matrix through the function my result is just a little black line
What am I doing wrong?
Using the matlab debugger, I noticed that that you are casting to int8, which is too small too represent all indices. So, you should use int32/int64 or uint32/uint64 instead, i.e.
answer = uint8(answer);
should be
answer = uint32(answer);
Please try to use the Matlab debugger before asking the question: why does it not work?

How can I change the outer limits of a Circular mask to a different colour

I have the following function that is successful in creating a grey circular mask over the image input, such that the new image is a grey border around a circular image. Example: Grey circular mask.
All I want to do is make the mask a very specific green, but I haven't been successful.
Here is the code:
function [newIm] = myCircularMask(im)
%Setting variables
rad = size(im,1)/2.1; %Radius of the circle window
im = double(im);
[rows, cols, planes]= size(im);
newIm = zeros(rows, cols, planes);
%Generating hard-edged circular mask with 1 inside and 0 outside
M = rows;
[X,Y] = meshgrid(-M/2:1:(M-1)/2, -M/2:1:(M-1)/2);
mask = double(zeros(M,M));
mask(X.^2 + Y.^2 < rad^2) = 1;
% Soften edge of mask
gauss = fspecial('gaussian',[12 12],0.1);
mask = conv2(mask,gauss,'same');
% Multiply image by mask, i.e. x1 inside x0 outside
for k=1:planes
newIm(:,:,k) = im(:,:,k).*mask;
end
% Make mask either 0 inside or -127 outside
mask = (abs(mask-1)*127);
% now add mask to image
for k=1:planes
newIm(:,:,k) = newIm(:,:,k)+mask;
end
newIm = floor(newIm)/255;
The type of green I would like to use is of RGB values [59 178 74].
I'm a beginner with MATLAB, so any help would be greatly appreciated.
Cheers!
Steve
After masking your image, create a color version of your mask:
% test with simple mask
mask = ones(10,10);
mask(5:7,5:7)=0;
% invert mask, multiply with rgb-values, make rgb-matrix:
r_green=59/255; g_green=178/255; b_green=74/255;
invmask=(1-mask); % use mask with ones/zeroes
rgbmask=cat(3,invmask*r_green,invmask*g_green,invmask*b_green);
Add this to your masked image.
Edit:
function [newIm] = myCircularMask(im)
%Setting variables
rad = size(im,1)/2.1; %Radius of the circle window
im = double(im);
[rows, cols, planes]= size(im);
newIm = zeros(rows, cols, planes);
%Generating hard-edged circular mask with 1 inside and 0 outside
M = rows;
[X,Y] = meshgrid(-M/2:1:(M-1)/2, -M/2:1:(M-1)/2);
mask = double(zeros(M,M));
mask(X.^2 + Y.^2 < rad^2) = 1;
% Soften edge of mask
gauss = fspecial('gaussian',[12 12],0.1);
mask = conv2(mask,gauss,'same');
% Multiply image by mask, i.e. x1 inside x0 outside
for k=1:planes
newIm(:,:,k) = im(:,:,k).*mask;
end
% Here follows the new code:
% invert mask, multiply with rgb-values, make rgb-matrix:
r_green=59/255; g_green=178/255; b_green=74/255;
invmask=(1-mask); % use mask with ones/zeroes
rgbmask=cat(3,invmask*r_green,invmask*g_green,invmask*b_green);
newIm=newIm+rgbmask;
Note that I haven't been able to test my suggestion, so there might be errors.

Low pass filter with unit integral

In image processing, specifically in fingerprint recognition, I have to apply a two-dimensional low pass filter with a unit integral.
What does this unit integral mean? Also, if I choose a Gaussian filter, what sigma to use?
Unit integral means that the total area of the mask or kernel should be 1. For example, a 3 x 3 averaging filter means that every coefficient in your mask should be 1/9. When you sum up all of the elements in the mask it adds to 1.
The Gaussian filter inherently has a unit integral / unit area of 1. If you use MATLAB, the fspecial command with the gaussian flag has its mask normalized.
However, if you want to create the Gaussian mask yourself, you can use the following equation:
Bear in mind that (x,y) are the locations inside the mask with respect to the centre. As such, if you have a 5 x 5 mask, then at row = 2, col = 2, x = 0 and y = 0. However, the above equation does not generate a unit area of 1. It is theoretically equal to 1 if you integrate over the entire 2D plane. Because we are truncating the Gaussian function, the area is not 1. As such, once you generate all of your coefficients, you need to make sure that the total area is 1 by summing up every single element in the mask. Then, you take this number and divide every single element in your mask by this number. In fact when you generate the Gaussian mask, it's not important to multiply the exponential term by the scale factor in the equation. By ensuring that the sum of the mask is equal to 1, the scale is effectively removed. You can just use the exponential term instead to shave off some calculations.
In terms of the sigma that is completely up to you. Usually people go with the half width of 3*sigma rule, so the total width spanning from left to right in 1D is 6*sigma + 1 (including the centre). In order to figure out what sigma you want specifically, people figure out how wide the smallest feature is in the image, set that as the width then figure out the sigma from there. For example, if the biggest width is 13, then rearranging for sigma in the equation gives you 2. In other words:
13 = 6*sigma + 1
12 = 6*sigma
sigma = 2
As such, you'd set your sigma to 2 and make the mask 13 x 13. For more information about the 3*sigma rule, check out my post on the topic here: By which measures should I set the size of my Gaussian filter in MATLAB?
Once you create that mask, use any convolution method you wish to Gaussian filter your image.
Here's another post that may help you if you can use MATLAB.
How to make a Gaussian filter in Matlab
If you need to use another language like C or Java, then you could create a Gaussian mask in the following way:
C / C++
#define WIDTH 13
float sigma = ((float)WIDTH - 1.0f) / 6.0f;
int half_width = (int)(WIDTH / 2.0);
float mask[WIDTH][WIDTH];
float scale = 0.0f;
for (int i = -half_width; i <= half_width; i++) {
for(int j = -half_width; j <= half_width; j++) {
mask[i+half_width][j+half_width] = expf( -((float)(i*i + j*j) / (2.0*sigma*sigma)) );
scale += mask[i+half_width][j+half_width];
}
}
for (int i = 0; i < WIDTH; i++)
for (int j = 0; j < WIDTH; j++)
mask[i][j] /= scale;
Java
int WIDTH = 13;
float sigma = ((float)WIDTH - 1.0f) / 6.0f);
int half_width = Math.floor((float)WIDTH / 2.0f);
float[][] mask = new float[WIDTH][WIDTH];
float scale = 0.0f;
for (int i = -half_width; i <= half_width; i++) {
for (int j = -half_width; j <= half_width; j++) {
mask[i+half_width][j+half_width] = (float) Math.exp( -((double)(i*i + j*j) / (2.0*sigma*sigma)) );
scale += mask[i+half_width][j+half_width];
}
}
for (int i = 0; i < WIDTH; i++)
for (int j = 0; j < WIDTH; j++)
mask[i][j] /= scale;
As I noted before, notice that in the code I didn't have to divide by 2*pi*sigma^2. Again, the reason why is because when you normalize the kernel, this constant factor gets cancelled out anyway, so there's no need to add any additional overhead when computing the mask coefficients.

Adaptive Contrast Enhancement(ACE)

How can i separate the image as a three region(dark, mid, bright)?any matlab commands are available for that?
The image processing toolbox has some options for segmenting images based on color. More information here. If you only need to select pixels based on intensity you can use Boolean operators. Here's an example of that approach:
% create an example image with three regions of intensity
im = ones(100,100);
im(1:25, 1:30) = 256;
im(75:end, 7:end) = 128;
% add some random noise
im = im + 10*rand(size(im));
% display image
figure
subplot(2,2,1)
image(im)
colormap gray
% segment image based on intensity
bottomThird = 256/3;
topThird = 2*256/3;
index1 = find(im < bottomThird);
index2 = find(and((im > bottomThird),(im <topThird)));
index3 = find(im > topThird);
%create images for each segmented region
im1 = ones(size(im));
im2 = ones(size(im));
im3 = ones(size(im));
im1(index1) = 0;
im2(index2) = 0;
im3(index3) = 0;
%display sub-regions
subplot(2,2,2)
imagesc(im1)
subplot(2,2,3)
imagesc(im2)
subplot(2,2,4)
imagesc(im3)

Resources