I am working with this code to import a spread sheet containing x (angle) and y (intensity) axes and plot the results:
%% Initialize variables
filename = ['C:\Users\themosawi\Desktop\khalifadec2104\mih10distracks-azi\mih10-distal-2_5mmbelowDH\mih10distracks_0363.dat'];
startRow = 5;
%% Format string for each line of text:
formatSpec = '%14f%f%[^\n\r]';
%% Open the text file.
fileID = fopen(filename,'r');
%% Read columns of data according to format string.
dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', '', 'HeaderLines' ,startRow-1, 'ReturnOnError', false);
%% Close the text file.
fclose(fileID);
%% Allocate imported array to column variable names
angle = dataArray{:, 1};
intensity = dataArray{:, 2};
%% Plot
plot(angle, intensity)
Sometimes I get plots looking like this (in which the plotting starts at the middle of the peak):
I would like the plotting to start from angle 45 instead of angle 0 (in the x-axis) so I can identify both peaks.
Here is the file:
http://mosawi.co.uk/mih10distracks_0363.dat
Try the code below, it may work:
%% Initialize variables
filename = ['C:\Users\themosawi\Desktop\khalifadec2104\mih10distracks-azi\mih10-distal-2_5mmbelowDH\mih10distracks_0363.dat.txt'];
startRow = 5;
%% Format string for each line of text:
formatSpec = '%14f%f%[^\n\r]';
%% Open the text file.
fileID = fopen(filename,'r');
%% Read columns of data according to format string.
dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', '', 'HeaderLines' ,startRow-1, 'ReturnOnError', false);
%% Close the text file.
fclose(fileID);
%% Allocate imported array to column variable names
angle = dataArray{:, 1};
intensity = dataArray{:, 2};
%% New angle & Intensity
lap = 100; % // Enter any angle value in range of your angle data
ind = find(angle > lap -.4 & angle < lap + .6);
newAngle = linspace(angle(ind), angle(ind)+angle(end), length(angle));
newIntensity = [intensity(ind:end); intensity(1:ind-1)];
%% Plot
plot(newAngle, newIntensity)
What I got as output:
Here's one approach, working with the cyclical nature of the data:
angle = angle(:).'; % ensures that these are both row
intensity = intensity(:).'; % vectors (may be unnecessary)
plot( [ angle-360 angle angle+360 ], [ intensity intensity intensity ] )
xlim( [0 360] + 45 ) % or +/- whatever you want
I'm not 100% sure I got your question right, but this is what I would do to phase shift this plot:
If so, you could replace:
%% Plot
plot(angle, intensity)
with
%% Plot
shift_angle = 45;
plot(angle, [intensity(shift_angle:end) ; intensity(1:shift_angle-1)])
Related
I am trying to figure out how to make a program in Matlab to detect edges of flames so I can compare their flame shape. I have been able to get this program to work half of the time. The program reads the files, coverts it to black and white, and then I have been having issues with the bwboundaries function (I think).
It will work some times and not others depending on the picture, they can be seen below.
Any help anyone could give me would be appreciated. I am struggling here to figure out what I am doing wrong.
clear, clc , close all
%% Specify the folder where the files live.
%myFolder = 'D:\Try';
myFolder = 'D:\Try\PicNamed\SpTestTry\hope';
%% Check to make sure that folder actually exists.
if ~isdir(myFolder)
errorMessage = sprintf('Error: The following folder does not exist:\n%s', myFolder);
uiwait(warndlg(errorMessage));
return;
end
%% Get a list of all files in the folder with the pattern
filePattern = fullfile(myFolder, '*.jpg'); % Change to whatever need.
theFiles = dir(filePattern);
line = cell(length(theFiles), 1) ;
rValue = cell(length(theFiles),1);
baseFileName = theFiles(1).name;
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
imageArray = imread(fullFileName);
% getting the rectanglur cords to crop the images
[I2, rect] = imcrop(imageArray);
%% Run Loop
for k = 1 : length(theFiles)
%Pulling in multiple Images from folder
baseFileName = theFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
fprintf(1, 'Now reading %s\n', fullFileName);
imageArray = imread(fullFileName);
%% Cropping Image with Rect Cords
Icrop = imcrop(imageArray,rect);
%% convert to bw
BW = im2bw(Icrop, graythresh(Icrop));
%% Get Boundries
boundaries = bwboundaries(BW);
% putting in x and y cord
x = boundaries{1}(:, 2);
y = boundaries{1}(:, 1);
%% Curve Fit
%pulling up picture of x,y plot to determing where base of flame is
figure
plot(x, y)
% cutting off bottom of flame edge so we can do curve fit
prompt = '(******) cut off line = ';
cutnum = input(prompt);
indices = find(abs(y)>cutnum);
y(indices) = NaN;
y(indices) = [];
x(indices) = [];
%% Looking for repate x values, averaging them together, and replacing with 1 x value
uc1 = unique( x ) ;
mc2 = accumarray( x, y, [], #mean ) ;
newData = [uc1, mc2(uc1)];
%% splitting AA into two sperate matricies, i.e. x/y cordinates
y = newData(:,2);
x = newData(:,1);
%% Creating a line Based off of the averaged x and y cords
[p,S] = polyfit(x,y,4); % 4th degree polynomail
line{k} = p;
rValue{k} = S.normr;
Rsquared{k}=1-S.normr^2/norm(y-mean(y))^2;
close all
clear BW
clear x
clear y
end
I have a text file, suppose myfile.txt, that stores floating point coordinates in following manner:
53
-464.000000 -20.000000 0.009000
-464.000000 -17.000000 0.042000
-464.000000 -13.000000 0.074000
-464.000000 -11.000000 0.096000
-464.000000 -8.000000 0.114000
...
...
...
42
380.000000 193.000000 7.076000
381.000000 190.000000 7.109000
383.000000 186.000000 7.141000
384.000000 184.000000 7.163000
384.000000 183.000000 7.186000
386.000000 179.000000 7.219000
...
...
...
the first line specifies the number of lines for the first set of coordinates, followed by that many lines. and then theres is another integer specifying the the number of lines for the next set of coordinates.
i.e. 1st line has 53, so next 53 lines are 1st set of coords(ending at line 54). Then line 55 has value 42, so next 42 lines are 2nd set of coords.
How can I read the text file such that i read 1st line, and the next 53 lines are read and stored in matrix. Then read 42 and the next 42 lines are read and stored? The text file is like this until EOF.
You could do it with Low-Level File I/O, like this:
fid = fopen('myfile.txt', 'r');
matrix = {};
while ~feof(fid)
N = fscanf(fid, '%d\n', 1);
matrix{end + 1} = fscanf(fid, '%f\n', [3 N])';
end
fclose(fid);
fid = fopen('myfile.txt ', 'r');
ind = 1;
mycell = {};
while ~feof(fid)
N = fscanf(fid, '%d\n', 1);
matrix = fscanf(fid, '%f\n', [3 N]);
matrix = transpose(matrix);
cell{ind} = matrix;
ind = ind + 1;
end
fclose(fid);
My two cents:
function matrix_cells = import_coordinates(filename, startRow, endRow)
%IMPORT_COORDINATES Import numeric data from a text file as a matrix.
% MATRIX_CELLS = IMPORT_COORDINATES(FILENAME) Reads data from text file FILENAME
% for the default selection and store it into the array of cells MATRIX_CELLS.
%
% MATRIX_CELLS = IMPORT_COORDINATES(FILENAME, STARTROW, ENDROW) Reads data from
% rows STARTROW through ENDROW of text file FILENAME.
%
% Example:
% matrix_cells = import_coordinates('coordinates.txt', 1, 15);
%
% See also TEXTSCAN.
%% Initialize variables.
delimiter = ' ';
if nargin<=2
startRow = 1;
endRow = inf;
end
%% Format string for each line of text:
% column1: double (%f)
% column2: double (%f)
% column3: double (%f)
% For more information, see the TEXTSCAN documentation.
formatSpec = '%f%f%f%[^\n\r]';
%% Open the text file.
fileID = fopen(filename,'r');
%% Read columns of data according to format string.
% This call is based on the structure of the file used to generate this
% code. If an error occurs for a different file, try regenerating the code
% from the Import Tool.
dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'EmptyValue' ,NaN,'HeaderLines', startRow(1)-1, 'ReturnOnError', false);
for block=2:length(startRow)
frewind(fileID);
dataArrayBlock = textscan(fileID, formatSpec, endRow(block)-startRow(block)+1, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'EmptyValue' ,NaN,'HeaderLines', startRow(block)-1, 'ReturnOnError', false);
for col=1:length(dataArray)
dataArray{col} = [dataArray{col};dataArrayBlock{col}];
end
end
%% Close the text file.
fclose(fileID);
%% Post processing for unimportable data.
% No unimportable data rules were applied during the import, so no post
% processing code is included. To generate code which works for
% unimportable data, select unimportable cells in a file and regenerate the
% script.
%% Create output variable
matrix_temp = [dataArray{1:end-1}];
%% MY CONTRIBUTION ;)
% find rows with nan values
[i,~]=find(isnan(matrix_temp));
indexes=unique(i);
%% Create output cell array
matrix_cells=cell(numel(indexes),1);
%% Fill cell array filtering out unuseful rows and parting original matrix
for i=1:1:numel(indexes)-1
matrix_cells{i}=matrix_temp(indexes(i)+1:indexes(i+1)-1,:);
end
% Last matrix
matrix_cells{end}=matrix_temp(indexes(end)+1:size(matrix_temp,1),:);
The first part (reading and import of text file) of this function was autogenerated by MATLAB. I added only the code to split and save the matrix into a cell array.
I assume that coordinates do not contain nan values; morevoer, I do not check for consistency between the declared number of rows and the actual one for each block.
Here an example; the following is the file coordinates.txt
5
-464.000000 -20.000000 0.009000
-464.000000 -17.000000 0.042000
-464.000000 -13.000000 0.074000
-464.000000 -11.000000 0.096000
-464.000000 -8.000000 0.114000
3
380.000000 193.000000 7.076000
381.000000 190.000000 7.109000
383.000000 186.000000 7.141000
2
384.000000 184.000000 7.163000
384.000000 183.000000 7.186000
1
386.000000 179.000000 7.219000
Excute the function:
coordinate_matrices=import_coordinates('coordinates.txt')
coordinate_matrices =
[5x3 double]
[3x3 double]
[2x3 double]
[1x3 double]
This is the content of every cell:
>> coordinate_matrices{1}
ans =
-464.0000 -20.0000 0.0090
-464.0000 -17.0000 0.0420
-464.0000 -13.0000 0.0740
-464.0000 -11.0000 0.0960
-464.0000 -8.0000 0.1140
>> coordinate_matrices{2}
ans =
380.0000 193.0000 7.0760
381.0000 190.0000 7.1090
383.0000 186.0000 7.1410
>> coordinate_matrices{3}
ans =
384.0000 184.0000 7.1630
384.0000 183.0000 7.1860
>> coordinate_matrices{4}
ans =
386.0000 179.0000 7.2190
I have the following code where I have two lines (L1 and L2) and I can find the point of intersection between the lines. However, L1 never changes but L2 does. This is where I am having the problem. I have a .txt file with a list of x and y coordinates. How do I alter the code such that I can swap out the figures 660 and 122.75 in L2 for the top two numbers in my list. Then save the intersection point and start again but this time replacing the two numbers with the second set of numbers in my list.
Regards,
Jer
clc;
clear;
%% Load data
filename = 'C:\blade1_data.txt';
delimiter = ' ';
formatSpec = '%f%f%[^\n\r]';
fileID = fopen(filename,'r');
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'ReturnOnError', false);
fclose(fileID);
X_coords = dataArray{:, 1};
Y_coords = dataArray{:, 2};
clearvars filename delimiter formatSpec fileID dataArray ans;
%% Find intersection between lines
L1 = [656.25 122.75; 611.625 378.875]; % Defines rotor line
L2 = [0 122.75; 660 122.75]; % Defines coordinate where blade tip was located
dx = diff(L1); %# Take the differences down each column
dy = diff(L2);
den = dx(1)*dy(2)-dy(1)*dx(2); %# Precompute the denominator
ua = (dx(2)*(L2(1)-L2(3))-dy(2)*(L1(1)-L1(3)))/den;
ub = (dx(1)*(L2(1)-L2(3))-dy(1)*(L1(1)-L1(3)))/den;
% Intersection point of the two lines:
xi = L1(1)+ua*dx(1);
yi = L2(1)+ua*dy(1);
Working code
clc;
clear;
%% Load data
filename = 'C:data.txt';
delimiter = ' ';
formatSpec = '%f%f%[^\n\r]';
fileID = fopen(filename,'r');
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'ReturnOnError', false);
fclose(fileID);
X_coords = dataArray{:, 1};
Y_coords = dataArray{:, 2};
clearvars filename delimiter formatSpec fileID dataArray ans;
%% Find intersection between lines
nfiles = length(X_coords);
for n = 1: nfiles;
ptx = X_coords(n:n,1);
pty = Y_coords(n:n,1);
L1 = [656.25 122.75; 611.625 378.875]; % Defines rotor line
L2 = [0 pty; ptx pty]; % Defines coordinate where blade tip was located
dx = diff(L1); %# Take the differences down each column
dy = diff(L2);
den = dx(1)*dy(2)-dy(1)*dx(2); %# Precompute the denominator
ua = (dx(2)*(L2(1)-L2(3))-dy(2)*(L1(1)-L1(3)))/den;
ub = (dx(1)*(L2(1)-L2(3))-dy(1)*(L1(1)-L1(3)))/den;
% Intersection point of the two lines:
xi = L1(1)+ua*dx(1);
yi = L2(1)+ua*dy(1);
data(n,:) = [xi yi];
end
I want to segment an Arabic word into single characters. Based on the histogram/profile, I assume that I can do the segmentation process by cut/segment the characters based on it's baseline (it have similar pixel values).
But, unfortunately, I still stuck to build the appropriate code, to make it works.
% Original Code by Soumyadeep Sinha
% Saving each single segmented character as one file
function [segm] = trysegment (a)
myFolder = 'D:\1. Thesis FINISH!!!\Data set\trial';
level = graythresh (a);
bw = im2bw (a, level);
b = imcomplement (bw);
i= padarray(b,[0 10]);
verticalProjection = sum(i, 1);
set(gcf, 'Name', 'Trying Segmentation for Cursive', 'NumberTitle', 'Off')
subplot(2, 2, 1);imshow(i);
subplot(2,2,3);
plot(verticalProjection, 'b-'); %histogram show by this code
% hist(reshape(input,[],3),1:max(input(:)));
grid on;
% % t = verticalProjection;
% % t(t==0) = inf;
% % mayukh = min(t)
% 0 where there is background, 1 where there are letters
letterLocations = verticalProjection > 0;
% Find Rising and falling edges
d = diff(letterLocations);
startingColumns = find(d>0);
endingColumns = find(d<0);
% Extract each region
y=1;
for k = 1 : length(startingColumns)
% Get sub image of just one character...
subImage = i(:, startingColumns(k):endingColumns(k));
% se = strel('rectangle',[2 4]);
% dil = imdilate(subImage, se);
th = bwmorph(subImage,'thin',Inf);
n = imresize (th, [64 NaN], 'bilinear');
figure, imshow (n);
[L,num] = bwlabeln(n);
for z= 1 : num
bw= ismember(L, z);
% Construct filename for this particular image.
baseFileName = sprintf('char %d.png', y);
y=y+1;
% Prepend the folder to make the full file name.
fullFileName = fullfile(myFolder, baseFileName);
% Do the write to disk.
imwrite(bw, fullFileName);
% subplot(2,2,4);
% pause(2);
% imshow(bw);
end
% y=y+1;
end;
segm = (n);
Word image is as follow:
Why the code isn't work?
do you have any recommendation of another codes?
or suggested algorithm to make it works, to do a good segmentation on cursive character?
Thanks before.
Replace this code part from the posted code
% 0 where there is background, 1 where there are letters
letterLocations = verticalProjection > 0;
% Find Rising and falling edges
d = diff(letterLocations);
startingColumns = find(d>0);
endingColumns = find(d<0);
with the new code part
threshold=max(verticalProjection)/3;
thresholdedProjection=verticalProjection > threshold;
count=0;
startingColumnsIndex=0;
for i=1:length(thresholdedProjection)
if thresholdedProjection(i)
if(count>0)
startingColumnsIndex=startingColumnsIndex+1;
startingColumns(startingColumnsIndex)= i-floor(count/2);
count=0;
end
else
count=count+1;
end
end
endingColumns=[startingColumns(2:end)-1 i-floor(count/2)];
No changes needed for the rest of the code.
I've been trying to look around online for something I want but I'm not having much luck so I thought I would just ask on here.
Is it possible to pinpoint in a different color and show the point on the graph where there are intersections between the two plots?
Thanks for any help you can give.
Here is the code:
file1 = fopen('C:\Program Files (x86)\Notepad++\avatar1.txt'); % open text file
file2 = fopen('C:\Program Files (x86)\Notepad++\avatar2.txt'); % open text file
file3 = fopen('C:\Program Files (x86)\Notepad++\avatar3.txt'); % open text file
tline1 = fgetl(file1); % read line by line and remove new line characters
tline2 = fgetl(file2); % read line by line and remove new line characters
tline3 = fgetl(file3); % read line by line and remove new line characters
% declare empty arrays
CX1 = [];
CY1 = [];
CZ1 = [];
CX2 = [];
CY2 = [];
CZ2 = [];
CX3 = [];
CY3 = [];
CZ3 = [];
while ischar(tline1) % true if tline is a character array
temp = cell2mat(textscan(tline1, '<%n,%n,%n>'));
% convert all the cell fields to a matrix
CX1 = vertcat(CX1, temp(1));
CY1 = vertcat(CY1, temp(2));
CZ1 = vertcat(CZ1, temp(3));
tline1 = fgetl(file1);
end
while ischar(tline2) % true if tline is a character array
temp = cell2mat(textscan(tline2, '<%n,%n,%n>'));
% convert all the cell fields to a matrix
CX2 = vertcat(CX2, temp(1));
CY2 = vertcat(CY2, temp(2));
CZ2 = vertcat(CZ2, temp(3));
tline2 = fgetl(file2);
end
while ischar(tline3) % true if tline is a character array
temp = cell2mat(textscan(tline3, '<%n,%n,%n>'));
% convert all the cell fields to a matrix
CX3 = vertcat(CX3, temp(1));
CY3 = vertcat(CY3, temp(2));
CZ3 = vertcat(CZ3, temp(3));
tline3 = fgetl(file3);
end
fclose(file1); % close the file
fclose(file2); % close the file
fclose(file3); % close the file
plot3(CX1, CY1, CZ1) % plot the data and label the axises
plot3(CX2, CY2, CZ2)
plot3(CX3, CY3, CZ3)
xlabel('x')
ylabel('y')
zlabel('z')
grid on
axis square
rotate3d on; % activate interactive mouse rotation
Changing the colours is simple, that's just a case of adding a colour code to the plot3 command, e.g.:
plot3(CX1, CY1, CZ1, 'b'); % blue lines/markers
plot3(CX2, CY2, CZ2, 'r'); % red lines/markers
plot3(CX3, CY3, CZ3, 'g'); % green lines/markers
For more details on colour codes, see the Matlab Colourspec Page.
The intersection could be a bit more tricky, depending on whether you want the intersection of the points (i.e. specific points which appear in all 3 datasets) or the intersection points of the lines that join the points.
I think the former should be fairly easy (this is untested and assumes CX1,etc are vertical vectors):
figure; % Open up a new figure
hold on; % This means the everything you plot stays in the figure and is not overwritten
% Plot the original points
plot3(CX1, CY1, CZ1, '-*b'); % blue lines/markers
plot3(CX2, CY2, CZ2, '-*r'); % red lines/markers
plot3(CX3, CY3, CZ3, '-*g'); % green lines/markers
% turn those 1xn vectors into 3xn matrices for each set of points
points1 = [CX1, CY1, CZ1];
points2 = [CX2, CY2, CZ2];
points3 = [CX3, CY3, CZ3];
% Find the intersection of the 3 sets
CX_intersect = intersect( points1, intersect( points2, points3, 'rows'), 'rows');
% Draw a scatter plot of the intersection points. the 'mo' means:
% m: magenta in colour, o: circular markers
scatter3( CX_intersect(:,1),CX_intersect(:,2),CX_intersect(:,3),'mo');
The intersection works like so:
Say we have 3 matrices, each containing a number of 3d points. Let's call them A,B and C.
To find the intersection between all 3 sets we first find the points that intersect just in A and B. We now have a set of points that we know are in A and B, so now we just have to check if those points are in C as well. we do this by doing another intersection.
I just chained those together into one line of code, which was probably not very useful, so I apologise. The code for the A,B,C intersections is below:
D = intersect(A,B,'rows') % we use rows because each row represents a 3D point
E = intersect(C,D,'rows') % E is the intersection of the 3 sets.
We can then substitute D into the line E = ... and we get:
E = intersect( intersect(A,B,'rows'), C, 'rows' );
Hope that helps!