How to divide image into block and add zero border for each block - matlab

I've a problem I need to divide image into blocks and add zero border for each blocks, one or two zeros is enough, I added border for all image but I want to add border for each block of image.
note::: no of block any size for ex: 4X4 blocks
img=round(100*rand(4,4));
[n,m]=size(img);
x=zeros(n+2,m+2);
%%%%%Applying zero padding to the image
for i=1:n+2
for j=1:m+2
if i==1 || i==n+2 || j==1 || j==m+2
x(i,j)=0;
else
x(i,j)=img(i-1,j-1);
end
end
end
x
I need to get output like this around each block one or two zero
0 0 0 0 0 0 0 0
0 84 80 0 0 65 85 0
0 29 19 0 0 23 77 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 84 80 0 0 66 74 0
0 29 19 0 0 36 80 0
0 0 0 0 0 0 0 0

%n: Size of original matrix
n=size(img,1)
%prealloc new matrix
img2=zeros(n+3,n+3)
%p indicates indices to store img at
p=[(2:n/2+1),(n/2+3:n+2)]
%Copy img to the correct positions
img2(p,p)=img

Related

How to exclud rows and columns of a square array from calculations in MATLAB?

I have a 10*10 array for a domain
TT =
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
, but I need to exclude a square centered in the domain, so the new domain would be :
TT_new =
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
I will create a for loop for the domain TT_new, how can I do this operation in MATLAB?
Clarification: I need the for loop to go through the "i,j" of the new domain "TT_new".
For example, I have the following mesh plot for steady heat conduction problem for a U-shaped plate:
2D plot
3D plot
I need to exclude the purple rectangular from the plot because it is not within the computational domain.
Have you thought about using a mask?
You can't have matrices with holes in them, but if you element-wise multiply your original array with a matrix containing ones everywhere and zeros in the places you want to remove, your result will be an array containing the original numbers everywhere but zeros where you have zeros in your mask. For example:
my_arr = reshape(1:30, 5, 6);
my_mask = ones(5, 6);
my_mask(1:3, 3:4) = 0;
masked_arr = my_arr .* my_mask;
This gives:
my_arr =
1 6 11 16 21 26
2 7 12 17 22 27
3 8 13 18 23 28
4 9 14 19 24 29
5 10 15 20 25 30
my_mask =
1 1 0 0 1 1
1 1 0 0 1 1
1 1 0 0 1 1
1 1 1 1 1 1
1 1 1 1 1 1
masked_arr =
1 6 0 0 21 26
2 7 0 0 22 27
3 8 0 0 23 28
4 9 14 19 24 29
5 10 15 20 25 30
Whether this is applicable to your situation depends on how you use the boundaries of your computational domain in your computation. Multiplying by a mask containing NaN will change unwanted elements to NaN.
Then, you could apply your mask before (or after, or both) every iteration to ensure that the unwanted elements are set to zero (or NaN, but that can cause problems if you add / subtract / multiply those elements with anything).
domain_mask = ones(size(T));
domain_mask(7:16, 12:31) = 0;
domain_mask_small = domain_mask(2:end-1, 2:end-1);
zero_row = zeros(1, size(T, 2));
zero_col = zeros(size(T, 1), 1);
while error > tol
% Perform operations on the entire array
T_iplus1 = [T(2:end, :); zero_row];
T_iminus1 = [zero_row; T(1:end-1, :)];
T_jplus1 = [T(:, 2:end), zero_col];
T_jminus1 = [zero_col, T(:, 1:end-1)];
T_temp = 0.25 * (T_iplus1 + T_iminus1 + T_jplus1 + T_jminus1);
T(2:end-1, 2:end-1) = T_temp(2:end-1, 2:end-1) .* domain_mask_small;
% Do whatever else
end

How do you trace all connected nonzero elements in a matrix in MATLAB?

Suppose I define the following simple matrix in MATLAB:
myImage3 = zeros(10,10);
for i=1:10
for j=i:2:10
myImage3(i,j) = 20;
end
end
Then myImage is a 10x10 matrix that looks like:
myImage3 =
20 0 20 0 20 0 20 0 20 0
0 20 0 20 0 20 0 20 0 20
0 0 20 0 20 0 20 0 20 0
0 0 0 20 0 20 0 20 0 20
0 0 0 0 20 0 20 0 20 0
0 0 0 0 0 20 0 20 0 20
0 0 0 0 0 0 20 0 20 0
0 0 0 0 0 0 0 20 0 20
0 0 0 0 0 0 0 0 20 0
0 0 0 0 0 0 0 0 0 20
How do I write a function that tracks or traces through all connected nonzero elements of the matrix? For example, if I start at (1,1), we have the following trace:
(1,1) --> (2,2) --> (3,3) ---> ... --> (10,10).
But if I start at (1,3), we have the following trace:
(1,3) --> (2,4) -> (3,5) ---> ... --> (8,10).
Similarly, if I start at (1,5), we have the following trace:
(1,5) --> (2,6) --> (3,7) ---> ... --> (6,10).
The elements do not need to be "20", but rather could be any non-zero number. Also, the elements do not have to be perfectly diagonal. They could be a zig zag like shown below:
myImage2 =
10 0 0 0 0 0 0 0 0 0
0 5 0 0 0 0 0 0 0 0
0 0 20 0 0 0 0 0 0 0
0 0 21 0 0 0 0 0 0 0
0 0 14 15 20 0 0 0 0 0
0 0 0 0 0 20 0 0 0 0
0 0 0 0 0 0 20 0 0 0
0 0 0 0 0 0 0 20 0 0
0 0 0 0 0 0 0 0 20 0
0 0 0 0 0 0 0 0 0 20
But notice that if I start at (1,1) again, every neighboring pixel has another non-zero neighboring pixel (i.e. connected).
The trace, starting at (1,1) would now look like:
(1,1)--> (2,2)--> (3,3) --> (4,3) --> (5,3)--> (5,4)--> (5,5)--> (6,6)--> (7,7)--> (8,8)--> (9,9)--> (10,10)
I think I need to use Depth First Search, but all the algorithms I see apply to adjacency matrices, not the type of matrices shown above.

Removing single pixels Matlab

I have a binary image. I have several single pixels in images. Single pixels are white (1) and all of their neighborhoods are black (0). for example image below shows a single pixel (at center) and two pixels (at left-bottom):
0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
1 1 0 0 0
How can I remove single pixels with morphological operations in Matlab?
I give you another option without loop, using a 2D convolution with conv2:
M = [0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0]
C = [0 1 0
1 1 1
0 1 0]; % The matrice that is going to check if a `1` is alone or not.
%if you also want to consider the neibhbors on the diagonal choose:
%C = ones(3);
R = M.*conv2(M,C,'same')>1 %Check for the neighbors.
RESULT
R =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0
Upon request by the OP, I'm converting my short comment into a reply:
Since you explicitly asked for morphological operations: bwmorph has a 'clean' option which is described as "Removes isolated pixels (individual 1s that are surrounded by 0s)" with an example close to yours. Have a look at the bwmorph documentation page.
As in your previous question, you can use bwboundaries:
if P is the binary image, than:
B = bwboundaries(P,8);
for k = 1:numel(B)
if size(B{k})<=2
P(B{k}(1,1),B{k}(1,2)) = 0;
end
end
So for the example above P becomes:
P =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 0 0 0

Create separated R-G-B array from loaded image

Sorry to bother, but it seem that I stuck with pretty easy task.
Simply, I want to create 3*m-by-3*n-by-3 RGB file from m-by-n-by-3 loaded image. Lets use folowing array as an example as example:
Image(:,:,1) = 0.5*ones(4);
Image(:,:,2) = ones(4);
Image(:,:,3) = 0.25*ones(4);
Image = uint8(255*Image); %3-D array, Red = 128, Green = 255, Blue = 64;
What I want to get is this:
ImageRGB(:,:,1) =
128 0 0 128 0 0 128 0 0 128 0 0
128 0 0 128 0 0 128 0 0 128 0 0
128 0 0 128 0 0 128 0 0 128 0 0
128 0 0 128 0 0 128 0 0 128 0 0
ImageRGB(:,:,2) =
0 255 0 0 255 0 0 255 0 0 255 0
0 255 0 0 255 0 0 255 0 0 255 0
0 255 0 0 255 0 0 255 0 0 255 0
0 255 0 0 255 0 0 255 0 0 255 0
ImageRGB(:,:,3) =
0 0 64 0 0 64 0 0 64 0 0 64
0 0 64 0 0 64 0 0 64 0 0 64
0 0 64 0 0 64 0 0 64 0 0 64
0 0 64 0 0 64 0 0 64 0 0 64
So far best I came up without using loops is this:
[i1,i2] = ndgrid(1:size(Image,1),[1:3:size(Image,2)*size(Image,3),2:3:size(Image,2)*size(Image,3),3:3:size(Image,2)*size(Image,3)]);
ImageRGB = accumarray([i1(:),i2(:),[ones(size(Image,1)*size(Image,2),1);2*ones(size(Image,1)*size(Image,2),1);3*ones(size(Image,1)*size(Image,2),1)] ],Image(:));
May be, there is some function I am not aware of, or more simple way to do this WITHOUT loops. Using them for such seemingly easy task feel just wrong.
What you have is completely fine, but it's very hard to read. Why not just do something very simple and very easy to understand:
ImageRGB = zeros(4,4*3,3);
ImageRGB(:,1:3:end,1) = Image(:,:,1);
ImageRGB(:,2:3:end,2) = Image(:,:,2);
ImageRGB(:,3:3:end,3) = Image(:,:,3);

Matrix Row manipulation in Breeze using Scala?

I've a DenseMatrix
1 2 3 0 0 0 0 0 0
0 0 0 11 22 33 0 0 0
0 0 0 0 0 0 111 222 333
I want to remove the first row and then a last row with all 0s
0 0 0 11 22 33 0 0 0
0 0 0 0 0 0 111 222 333
0 0 0 0 0 0 0 0 0
How do I achieve this in Breeze ?
First, gather the rows you still want:
val subset = matrix(::, 2 to 3)
then add the zeroes:
val newMatrix = DenseMatrix.horzcat(subset, DenseMatrix.zeros[Double](1,9))
I might have mixed up rows and columns in the last line.