I have to represent this pulses in Matlab but only when i find a 0 in a vector
This is my code, i generate a vector with 10 numbers 0s and 1s but I am not able to program the representation of the pulse when a 0 appears in the vector.
L=10;
bits = rand(1,L) < 0.5;
dom = [1:length(bits)];
for c = length(bits):-1:2
if bits(c) ~= 1
bits = [bits(1:c-1), bits(c-1:end)];
dom = [dom(1:c),dom(c:end)];
end
end
figure(2)
plot (dom,bits)
Related
I have a materials matrix where the values indicate the type of material (value between 1 and 8). Each value below 5 indicates an "interesting" material. Now at a certain point, i want to sum up the amount of non-interesting neighbor materials. So in a 3D-matrix the result at one point can be value between 0 and 6. One of the problems is that the "current" point is at the edge of the 3D matrix. I can solve this using 3 very expensive for-loops:
materials; % given 3D matrix i.e. 97*87*100
matrixSize = size(materials);
n = matrixSize(1)*matrixSize(2)*matrixSize(3); * total number of points
materialsFlattened = reshape(materials, [n 1]); % flattened materials matrix from a 3D matrix to a 1D matrix
pageSize = matrixSize(1)*matrixSize(2); % size of a page in z-direction
interestingMaterials = materialsFlattened(:) < 5; % logical vector indicating if the materials are interesting
n_bc = zeros(obj.n, 1); % amount of neighbour non-interesting materials
for l = 1:matrixSize(3) % loop over all z
for k = 1:matrixSize(2) % loop over all y
for j = 1:matrixSize(1) % loop over all x
n_bc(sub2ind(matrixSize,j,k,l)) = ...
~interestingMaterials(sub2ind(matrixSize,j,k,max(1, l-1)))...
+ ~interestingMaterials(sub2ind(matrixSize,j,max(1,k-1),l))...
+ ~interestingMaterials(sub2ind(matrixSize,max(1, j-1),k,l))...
+ ~interestingMaterials(sub2ind(matrixSize,min(matrixSize(1),j+1),k,l))...
+ ~interestingMaterials(sub2ind(matrixSize,j,min(matrixSize(2),k+1),l))...
+ ~interestingMaterials(sub2ind(matrixSize,j,k,min(matrixSize(3),l+1)));
end
end
end
So note that i first flatten the matrix to a 1D matrix using reshape. The min and max operators ensure that i do not go out of the bounds of the matrix; instead i take the value of the material where i currently am. For my application, speed is of the essence and i was hoping i can get rid of this ugly loop in loop structure. Often times that is possible in MATLAB, as the element-wise indexing is amazing and sometimes kinda magic.
I want to perform a Census transform in MATLAB at the center pixels of each filter's window as shown below:
If the the image does not appear, an alternative link: https://i.ibb.co/9Y6LfSL/Shared-Screenshot.jpg
My Initial attempt for the code is:
function output =census(img,census_size)
img_gray = rgb2gray(img);
[y,x]=size(img_gray);
borders = floor(census_size/2); % limit to exclude image borders when filtering
for(iy = 1+borders : y-borders)
for(ix = 1+borders : x-borders)
f=img_gray(iy-borders:iy+borders,ix-borders:ix+borders);
iix=ix-borders;
iiy=iy-borders;
% shift=bitsll(img_out(iiy,iix),1);
img_out(iiy,iix)= % Must be Implemented with census
end
end
%normalised_image = img_out ./ max(max(img_out)) ;
output=img_out;
imshow(normalised_image);
end
iix and iiy at the second for loop represents my current location for the center pixels. f is my current filter window.
In addition to comparsion operation with the window's other pixels, I need to set each comparsion result to logical 1/0, and extend the total result ( by shifting I guess) to 8-bit data, then convert this binary number to a deciaml number. How I can do this in a practical way in MATLAB?
I have checked this in Python: https://stackoverflow.com/a/38269363/12173333
But could not make a similarity in MATLAB.
If you have the image processing toolbox you can use blockproc:
%Load your image
I = imread('https://i.stack.imgur.com/9oxaQ.png');
%Creation of the census transform function
fun = #(B) [128 64 32 16 0 8 4 2 1]*(B.data(:)>B.data(2,2));
%Process the image, block-by-block with overlap, force the result to be of type uint8
I2 = uint8(blockproc(I.',[1 1],fun,'BorderSize',[1,1],'TrimBorder',0)).'
Here blockproc is configured for a 3x3 windows (with overlap) and work for grayscale image. The function fun check which part of the block is strictly bigger than the center of the block. We obtain a 1x9 logical vector. Then I multiply this vector with [128 64 32 16 0 8 4 2 1] (binary to decimal transformation).
Update:
Optimisation with linear algeabra
For random windows size you can use:
I = imread('https://i.stack.imgur.com/9oxaQ.png');
w = 5; % windows size, any odd number between 3 and 31.
b2d = 2.^[w^2-1:-1:ceil(w^2/2),0,floor(w^2/2):-1:1] % binary to decimal vector
cen = ceil(w/2); % center position
%Creation of the census transform function
fun = #(B) b2d*(B.data(:)>B.data(cen,cen));
%Process the image, block-by-block with overlap
I2 = blockproc(I.',[1 1],fun,'BorderSize',[cen-1,cen-1],'TrimBorder',0).'/sum(b2d)
Input:
Output:
Trying to assign appropriate value to x that would result in random integers between 1 to 60. Any suggestions? I did randn but am getting small numbers over and over. Here's the code so far:
function s = Q11sub1(x)
x = % <------ Question is what goes here
if x <= 30
s = "small";
elseif x > 30 & x <= 50
s = "medium";
else
s = "high";
end
end
Use randi:
randi(60)
This will give you a pseudorandom integer between 1 to 60.
Reference: https://www.mathworks.com/help/matlab/ref/randi.html
The problem is randn generates random numbers that follow a standard Normal distribution, e.g. Normal(mu = 0, std = 1).
As #Banghua Zhao points out, you want the randi function and I'll add they will be uniformly distributed across the integers (inclusively) between those integer bounds (known as the discrete uniform distribution).
The code X = randi([a b],N,M) will generate a NxM matrix of integers uniformly distributed on the interval [a,b] inclusively. A call randi(Imax) defaults the lower bound to 1.
See the difference below.
N = 500; % Number of samples
a = 1; % Lower integer bound
b = 60; % Upper integer bound
X = randi([a b],N,1); % Random integers between [a,b]
Y = randn(N,1);
figure, hold on, box on
histogram(X)
histogram(Y)
legend('randi[1,60]','randn','Location','southeast')
xlabel('Result')
ylabel('Observed Frequency')
title({'randi([a b],N,1) vs randn(N,1)';'N = 500'})
EDIT: At #Max's suggestion, I've added 60*randn.
% MATLAB R2017a
W = 60*randn(N,1);
figure, hold on, box on
hx = histogram(X,'Normalization','pdf')
hw = histogram(W,'Normalization','pdf')
legend('randi[1,60]','60*randn','Location','southeast')
xlabel('Result')
ylabel('Observed Estimated Density')
title({'randi([a b],N,1) vs 60*randn(N,1)';['N = ' num2str(N)]})
I have a binary barcode image, I want to apply a sobel filter that I created so that I can detect the positive/negative vertical edges of the barcode lines which I can then use to determine the start/end of each barcode line.
The idea of implementing my own sobel filter is so that I can preserve the polarity(for start/end of each barcode line) and then plot different color lines over the positive/negative values marking the beginning and end of each bar in the barcode.
My problem is that I am not getting every line from my original barcode when I apply my filter in my output image. Can anyone see the problem in my code?
Image =imread('barcode.jpg')
I = im2double(Image);
G = rgb2gray(I);
avgI=mean(mean(G))
Threshold = avgI;
T=(G<Threshold);
figure()
New = T.*G
imshow(New);
G = [1 0 -1
2 0 -2
1 0 -1];
Output = I;
for n = 1:1000
Output = conv2(New,G); % 2D Convolution Function
end
subplot(1,2,1), imshow (New);
subplot(1,2,2), imshow (Output);
Use the convolution operation directly on the thresholded image. Also make sure to convert it to double since it will be of class logical. Lastly I dont know why you were performing the convolution 1000 times but overall I think you put in a good effort and were relatively close to a solution.
Code:
Image =imread('barcode.jpg');
I = im2double(Image);
G = rgb2gray(I);
avgI=mean(mean(G));
Threshold = avgI;
T=(G<Threshold);
figure
G = [1 0 -1
2 0 -2
1 0 -1];
Output = conv2(double(T),G); % 2D Convolution Function
subplot(1,2,1), imshow (T,[]);
subplot(1,2,2), imshow (Output,[]);
Output:
I have a set a section of code that is taking a long time to run. I read over the vectorization page on the mathworks site. I am still a little confused on one part, is it possible to vectorize the part where I run plane_intersect?
Unvectorized
for N = 1:sizeDimages
imPos = anaInfoSat(N).ImagePositionPatient;
A2Z = imPos(3);
A2Y = imPos(2);
A2X = imPos(1);
[upP1(N,:)]=plane_intersect([cosSx(1),cosSy(1),cosSz(1)],[uppersatX1,uppersatY1,uppersatZ1],crossS,[A2X,A2Y,A2Z]);
[loP1(N,:)]=plane_intersect([cosSx(1),cosSy(1),cosSz(1)],[lowersatX1,lowersatY1,lowersatZ1],crossS,[A2X,A2Y,A2Z]);
end
My attempt at vectorization, the thing is upP1 is a Nx3 matrix. I preallocate the upP1 matrix. This code below returns an error about dimension mismatch. ImagePosition is a 1x3 matix.
N = 1:sizeDimages;
imPos = anaInfoSat(N).ImagePositionPatient;
A2Z = imPos(3);
A2Y = imPos(2);
A2X = imPos(1);
[upP1(N,:)]=plane_intersect([cosSx(1),cosSy(1),cosSz(1)],[uppersatX1,uppersatY1,uppersatZ1],crossS,[A2X,A2Y,A2Z]);
[loP1(N,:)]=plane_intersect([cosSx(1),cosSy(1),cosSz(1)],[lowersatX1,lowersatY1,lowersatZ1],crossS,[A2X,A2Y,A2Z]);
Here is part of the plane_intersect code, should be enough to let you know what it does.
function [P,N,check]=plane_intersect(N1,A1,N2,A2)
%plane_intersect computes the intersection of two planes(if any)
% Inputs:
% N1: normal vector to Plane 1
% A1: any point that belongs to Plane 1
% N2: normal vector to Plane 2
% A2: any point that belongs to Plane 2
%
%Outputs:
% P is a point that lies on the interection straight line.
% N is the direction vector of the straight line
% check is an integer (0:Plane 1 and Plane 2 are parallel'
% 1:Plane 1 and Plane 2 coincide
% 2:Plane 1 and Plane 2 intersect)
%
% Example:
% Determine the intersection of these two planes:
% 2x - 5y + 3z = 12 and 3x + 4y - 3z = 6
% The first plane is represented by the normal vector N1=[2 -5 3]
% and any arbitrary point that lies on the plane, ex: A1=[0 0 4]
% The second plane is represented by the normal vector N2=[3 4 -3]
% and any arbitrary point that lies on the plane, ex: A2=[0 0 -2]
%[P,N,check]=plane_intersect([2 -5 3],[0 0 4],[3 4 -3],[0 0 -2]);
In your vectorized code anaInfoSat(N).ImagePositionPatient; won't return a single, but several answers. If you assign the resuts to a single variable it will receive only the first answer. This is why you get dimension mismatch error.
Depending on the data class you can combine into a matrix
imPos = [anaInfoSat(N).ImagePositionPatient];
or into a cell array
imPos = {anaInfoSat(N).ImagePositionPatient};
You can also assign to several variables as the same time:
[A2X, A2Y, A2Z] = anaInfoSat(1:3).ImagePositionPatient;