Base coordinate for poly2mask matlab - matlab

I would like to ask that what's the origin pixel in the image coordinate system used in poly2mask function in MATLAB.
It's been asked by others in OpenCV and wonder if it's the same in MATLAB. Let me repeat the person's question:
In general there may be two kinds of such systems, for the first (0,0) is defined as the center of the upper left pixel, which means the upper left corner of the upper left pixel is (-0,5, -0.5) and the center of the image is ((cols - 1) / 2, (rows - 1) / 2).
The other one is that (0,0) is the upper left corner of the upper left pixel, so the center of the upper left pixel is (0.5, 0.5) and the center of the image is (cols / 2, rows / 2).
My question is which system is adopted in poly2mask function in MATLAB?

MATLAB uses 1-based indexing, not 0-based indexing. Consequently, the top-left pixel has the center at (1,1). poly2mask follows the same convention, they're pretty consistent at the MathWorks.
This experiment shows this:
>> poly2mask([0.8,1.2,1.2,0.8],[0.8,0.8,1.2,1.2],3,5)
ans =
3×5 logical array
1 0 0 0 0
0 0 0 0 0
0 0 0 0 0
I drew a polygon closely around the (1,1) point, and the mask shows the top-left pixel marked. If you draw a polygon around the (0.5,0.5) point, no pixel is marked:
>> poly2mask([0.8,1.2,1.2,0.8]-0.5,[0.8,0.8,1.2,1.2]-0.5,3,5)
ans =
3×5 logical array
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
The one thing that is easy to make mistakes with is the order of the axes. The first index is y the second is x. But many functions in the Image Processing Toolbox (and elsewhere) take coordinates as (x,y), rather than as (y,x). For example:
>> poly2mask([0.8,1.2,1.2,0.8]+1,[0.8,0.8,1.2,1.2],3,5)
ans =
3×5 logical array
0 1 0 0 0
0 0 0 0 0
0 0 0 0 0
Here, x = 2 and y = 1, and the pixel ans(1,2) is set!

Related

Passing certain values of a matrix usi a logical mask

Assum I have a matrix of logicals MxN:
mask=[0 0 0 0 0;
0 1 1 0 0;
0 1 1 0 0;
0 0 0 0 0;
0 0 0 0 0];
in this case M=N=5.
A second matrix A with the sizes 'MxNx3' (RGB image). I want to pass a function values of A with respect to the mask. For example all values that are not part of the mask:
foo(A(~mask));
Sure this line of code is useless since mask gives me indices of only one of the RGB colors.
what is the correct way to do this?
Can I get away with a one line?
You can use repmat to repeat your mask 3 times in the third dimension. This will create a nnz(~mask) * 3 element vector. You can reshape the result of the repmat operation such that the rows are the true elements in your mask and the columns are the third dimension
foo(reshape(A(~repmat(mask, [1 1 3])), [], 3))
You could also do something like this answer to accomplish something similar.

How to find centroid of an object in divided image [duplicate]

I have spent all day reading up on the above MATLAB functions. I can't seem to find any good explanations online, even on the MathWorks website!
I would be very grateful if anyone could explain bwlabel, regionprops and centroid. How do they work if applied to a grayscale image?
Specifically, they are being used in this code below. How do the above functions apply to the code below?
fun=#minutie; L = nlfilter(K,[3 3],fun);
%% Termination LTerm=(L==1);
figure; imshow(LTerm)
LTermLab=bwlabel(LTerm);
propTerm=regionprops(LTermLab,'Centroid');
CentroidTerm=round(cat(1,LTerm(:).Centroid));
figure; imshow(~K)
set(gcf,'position',[1 1 600 600]); hold on
plot(CentroidTerm(:,1),CentroidTerm(:,2),'ro')
That's quite a mouthful to explain!... nevertheless, I'd love to explain it to you. However, I'm a bit surprised that you couldn't understand the documentation from MathWorks. It's actually quite good at explaining a lot (if not all...) of their functions.
BTW, bwlabel and regionprops are not defined for grayscale images. You can only apply these to binary images.
Update: bwlabel still has the restriction of accepting a binary image but regionprops no longer has this restriction. It can also take in a label matrix that is usually output from bwlabel as well as binary images.
Assuming binary images is what you want, my explanations for each function is as follows.
bwlabel
bwlabel takes in a binary image. This binary image should contain a bunch of objects that are separated from each other. Pixels that belong to an object are denoted with 1 / true while those pixels that are the background are 0 / false. For example, suppose we have a binary image that looks like this:
0 0 0 0 0 1 1 1 0 0
0 1 0 1 0 0 1 1 0 0
0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 1
0 0 1 1 1 1 0 0 1 1
You can see in this image that there are four objects in this image. The definition of an object are those pixels that are 1 that are connected in a chain by looking at local neighbourhoods. We usually look at 8-pixel neighbourhoods where you look at the North, Northeast, East, Southeast, South, Southwest, West, Northwest directions. Another way of saying this is that the objects are 8-connected. For simplicity, sometimes people look at 4-pixel neighbourhoods, where you just look at the North, East, South and West directions. This woudl mean that the objects are 4-connected.
The output of bwlabel will give you an integer map where each object is assigned a unique ID. As such, the output of bwlabel would look something like this:
0 0 0 0 0 3 3 3 0 0
0 1 0 1 0 0 3 3 0 0
0 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 4
0 0 0 0 0 0 0 0 4 4
0 0 2 2 2 2 0 0 4 4
Because MATLAB processes things in column major, that's why the labelling is how you see above. As such, bwlabel gives you the membership of each pixel. This tells you where each pixel belongs to if it falls on an object. 0 in this map corresponds to the background. To call bwlabel, you can do:
L = bwlabel(img);
img would be the binary image that you supply to the function and L is the integer map I just talked about. Additionally, you can provide 2 outputs to bwlabel, and the second parameter tells you how many objects exist in the image. As such:
[L, num] = bwlabel(img);
With our above example, num would be 4. As another method of invocation, you can specify the connected pixel neighbourhoods you would examine, and so you can do this:
[L, num] = bwlabel(img, N);
N would be the pixel neighbourhood you want to examine (i.e. 4 or 8).
regionprops
regionprops is a very useful function that I use daily. regionprops measures a variety of image quantities and features in a black and white image. Specifically, given a black and white image it automatically determines the properties of each contiguous white region that is 8-connected. One of these particular properties is the centroid. This is also the centre of mass. You can think of this as the "middle" of the object. This would be the (x,y) locations of where the middle of each object is located. As such, the Centroid for regionprops works such that for each object that is seen in your image, this would calculate the centre of mass for the object and the output of regionprops would return a structure where each element of this structure would tell you what the centroid is for each of the objects in your black and white image. Centroid is just one of the properties. There are other useful features as well, but I'm assuming you don't want to do this. To call regionprops, you would do this:
s = regionprops(img, 'Centroid');
The above code will calculate the centroids of each of your objects in the image. You can specify additional flags to regionprops to specify each feature that you want. I do highly encourage that you take a look at all of the possible features that regionprops can calculate, as there are many that are useful in a variety of different applications and situations.
Also, by omitting any flags as input into the function, you would calculate all of the features in your image by default. Therefore, if we were to declare the image that we have seen above in MATLAB, this is what would happen after I run regionprops. After, let's calculate what the centroids are:
img = logical(...
[0 0 0 0 0 1 1 1 0 0;
0 1 0 1 0 0 1 1 0 0;
0 1 1 1 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 1;
0 0 0 0 0 0 0 0 1 1;
0 0 1 1 1 1 0 0 1 1]);
s = regionprops(img, 'Centroid');
... and finally when we display the centroids:
>> disp(cat(1,s.Centroid))
3.0000 2.6000
4.5000 6.0000
7.2000 1.4000
9.6000 5.2000
As such, the first centroid is located at (x,y) = (3, 2.6), the next centroid is located at (x,y) = (4.5, 6) and so on. Take special note that the x co-ordinate is the column while the y co-ordinate is the row.
Hope this is clear!

How can I put margins in an image?

I have a binary image of 18x18 pixels and I want to put margins around this image with the purpose of obtaining an image 20x20 pixels.
The image is binary and it can be represented by a matrix of 1s and 0s. The 0 pixels are in black colour and the 1 pixels are in white colour. I need to put margins of 1 pixel of zeros around the image that I have.
How can I do it?
The padarray function from the image processing toolbox can be used for this purpose:
B=padarray(A,[1,1])
A=ones(18,18);%// your actual image
[M,N] = size(A);
B = zeros(M+2,N+2);%// create matrix
B(2:end-1,2:end-1) = A; %// matrix with zero edge around.
This first gets the size of your image matrix, and creates a zero matrix with two additional columns and rows, after which you can set everything except the outer edges to the image matrix.
Example with a non-square matrix of size [4x6]:
B =
0 0 0 0 0 0 0 0
0 1 1 1 1 1 1 0
0 1 1 1 1 1 1 0
0 1 1 1 1 1 1 0
0 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0
Let's get hackish:
%// Data:
A = magic(3); %// example original image (matrix)
N = 1; %// margin size
%// Add margins:
A(end+N, end+N) = 0; %// "missing" values are implicitly filled with 0
A = A(end:-1:1, end:-1:1); %// now flip the image up-down and left-right ...
A(end+N, end+N) = 0; %// ... do the same for the other half ...
A = A(end:-1:1, end:-1:1); %// ... and flip back
First make a matrix of 20 by 20 zeroes, Zimg, then insert your image matrix into the matrix of zeroes:
Zimg(2:end-1,2:end-1)=img;

assigning coordinate to a matrix in MATLAB

I'm writing a MATLAB code, I encountered a problem: I have a (2N+1)*(2N+1) matrix for example 7*7. I want to assign coordinate system to it such that the matrix center is the origin of coordinate system. I mean I want to assign (0,0) to row 4 and column 4 of matrix, (1,0) to row 4 and column 5 of matrix and so on. please help me
Thank you in advance
I want to generate a line of ones in all possible directions in a square matrix like this:
0 0 0 0 0 0 0
0 0 0 0 0 0 1
0 0 0 0 0 1 0
0 0 0 1 0 0 0
0 1 0 0 0 0 0
1 0 0 0 0 0 0
0 0 0 0 0 0 0
center of matrix is the origin. this line has 30 degree from horizontal axis.
What you want is a simple mapping from the original matrix counting system to a customized one. Here I have built two cell matrices, representing the coordinates of the elements in the matrix.
Here I have done a simple mapping as follows:
for ii = 1:7
for jj=1:7
D{ii,jj} = C{ii,jj} - [4,4];
end
end
Generally, for matrix of size 2*N+1, you will do the following:
for ii = 1:2*N+1
for jj = 1:2*N+1
D{ii,jj} = C{ii,jj} - [N+1,N+1];
end
end
where C is the original matrix and D is the mapped matrix. After you well-understood what I have done here, you can then replace the for-loops with more efficient functions such as bsxfun.

Confusion on Sobel mask

What is the exact mask for Sobel (Gx and Gy)? What I saw is there are two types on how people wrote it such as below,
Style 1
Gx = [-1 -2 -1
0 0 0
1 2 1]
Gy = [-1 0 1
-2 0 2
-1 0 1]
Style 2
Gx = [-1 0 1
-2 0 2
-1 0 1]
Gy = [-1 -2 -1
0 0 0
1 2 1]
Edited
#Aurelis
In Matlab --> (row x col)
In OpenCV --> (col x row)
However, the diagram below is correct for both
-->column
^
|row
|
Probably in Matlab will output Gx == horizontal edge, Gy == vertical edge if Style 1 is used and Gx == horizontal edge, Gy ==vertical edge if Style 2 is used. Both will produce same output (internal operation might be different due to the col-row major order).
#Abhishek You are using style 1 to compute the horizontal and vertical edge? and Gx correspond to horizontal edge while Gy correspond to vertical edge?
Does that mean style 2 is complement of that? For eg. computing Gx will gives vertical edge and Gy gives horizontal edge?
Style 2 is correct. However, using both the styles we will get the same result, as the kernels are convolved with the image
Gx = [-1 -2 -1
0 0 0 <--- will extract features in Y direction and not in X direction.
1 2 1]
Gy = [-1 0 1
-2 0 2 <--- will extract features in X direction and not in Y direction.
-1 0 1]
This can be verified by using a simple 2-D convolution.
original image:
using Style1,Gx:
using style1, Gy:
If you are using mathematical notation, the proper mask is Style 2 (see here).
Your confusion may be arising from the difference between matrices in MATLAB and OpenCV. MATLAB matrices are specified in column-major order, while OpenCV matrices are specified in row-major order.
Style 1 is representing the Sobel mask in a column-major fashion, and Style 2 represents the same mask in row-major order.