How to arrange pixel address as order under certain condition? - matlab

I am currently doing map processing in matlab. Now i solved the maze and get the path of maze. Now i have turning point in map. But this address pixel are not in correct order. So i want to order the incorrect order of pixel address in to correct order.
INCORRECT ORDER:
shape(1).cen=[28;136];
shape(2).cen=[122;136];
shape(3).cen=[344;391];
shape(4).cen=[548;493];
shape(5).cen=[548;191];
shape(6).cen=[344;191];
shape(7).cen=[122;391];
CORRECT ORDR:
map(1).cen=[28;136];
map(2).cen=[122;136];
map(3).cen=[122;391];
map(4).cen=[344;391];
map(5).cen=[344;191];
map(6).cen=[548;191];
map(7).cen=[548;493];
My code is below:-
`map(1).cen=[28;136];
o=0; order=1;xflag=0;yflag=0;
k=length(shape); %indicates the total elements in shape.cen structure
for (j=1:k)
order=order+1; o=o+1;
if (j==1)
x=map(1).cen(1,1);
y=map(1).cen(2,1);
for(i=1:k)
xi=shape(i).cen(1,1);
yi=shape(i).cen(2,1);
if((x==xi)||(y==yi))
if(x==xi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
xflag=1;
break;
else
(y==yi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
yflag=1;
break;
end
end
end
end
x=map(o).cen(1,1);
y=map(o).cen(2,1);
for(i=1:k)
xi=shape(i).cen(1,1);
yi=shape(i).cen(2,1);
if(xflag==1)
if(y==yi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
xflag=0;
yflag=1;
break;
end
end
if (yflag==1)
if(x==xi)
map(order).cen(1,1)=xi;
map(order).cen(2,1)=yi;
xflag=1;
yflag=0;
break;
end
end
end
end
`

[shape.cen]' will give you the following array:
ans =
28 136
122 136
344 391
548 493
548 191
344 191
122 391
Now that it's a regular numerical array, you can use sortrows, like this.
map = sortrows([shape.cen]')
to get:
map =
28 136
122 136
122 391
344 191
344 391
548 191
548 493
If you don't want it as a numerical array, but a struct similar to shape, you can do:
[~, ID] = sortrows([shape.cen]')
map = shape(ID)'

Related

How make endpoints of bwboundaries consistent in Matlab?

I have an image with 2 edges
if I then plot the boundary of the edges with the code below:
imshow(I); hold on; [B,L,N] = bwboundaries(I);
for k=1:length(B),
boundary = B{k};
BL=size(boundary);
plot(boundary(1,2), boundary(1,1), '*g','MarkerSize',15);
for j=1:10:BL(1)
plot(boundary(j,2), boundary(j,1), '.r','MarkerSize',5);
end
end
As seen in the image above, the starting point (the green star) for the left edge is at the left side of the image, which is what I expected. However, the starting point for the right edge is towards the middle
Apparently this is because bwboundaries deals with tracing objects in clockwise direction, whereas the 2nd edge needs to be traced counterclockwise for it to begin and end on the right boundary of the image
How can Matlab be able to take the positions from bwboundaries and correctly determine the endpoints for the edge on the right?
Not a complete answer to your problem, but an idea I came up with. You can check all points of a boundary for their "closeness" to an image border, and then find minimum/maximum (x, y) values, that'll describe those "ends" you're interested in.
B = bwboundaries(img);
% Threshold for "closeness" to an image border.
thrNear = 5;
for k = 1:numel(B)
b = B{k};
nearTop = b(:, 1) < thrNear;
nearBottom = b(:, 1) > (size(img, 1) - thrNear);
nearLeft = b(:, 2) < thrNear;
nearRight = b(:, 2) > (size(img, 2) - thrNear);
closeToTop = b(nearTop, :)
closeToBottom = b(nearBottom, :)
closeToLeft = b(nearLeft, :)
closeToRight = b(nearRight, :)
end
For example, for the right shape in your original image, you get:
closeToTop = [](0x2)
closeToBottom = [](0x2)
closeToLeft = [](0x2)
closeToRight =
79 283
79 284
79 285
79 286
79 287
80 287
81 287
81 286
81 285
81 284
81 283
215 283
215 284
215 285
215 286
215 287
216 287
217 287
217 286
217 285
217 284
217 283
Now, go for the maximum x value(s) (287), and find appropriate (non-neighbouring) y values (79-81 vs. 215-217). Repeat that for each image border.
I hope, you get my idea. To be honest, I don't want to implement that entirely, but don't hesitate to ask, if my description is not precise enough.

Import coordinates from file .txt with Matlab

I need to plot some trajectories with matlab, i have the coordinates of each points in a file .txt, i work with c++ i want to plot this trajectories with Matlab to make some comparisons, this is an example of the file who contains the coordinates :
515 // this is x
317 // this is y
0 // i dont want to import this variable
511 // this is x
328 // this is y
20 // i dont want to import this variable
508
353
40
511
... etc
there is a function in Matlab that can help me to import only x and y?
file :
172
489
54460
283
469
54480
388
428
54500
476
384
54520
555
350
54540
635
325
54560
700
286
54580
760
250
54600
811
222
54620
840
192
54640
856
171
54660
871
175
54680
890
181
54700
930
170
54720
979
168
54740
You can read in all values using textscan and simply ignore every third value in the output by using the * in the format specifier.
fid = fopen('filename.txt', 'r');
data = textscan(fid, '%d\n%d\n%*d\n');
[x,y] = data{:};
fclose(fid);
Another option is to read in all data, then reshape and grab the parts you care about.
fid = fopen('filename.txt', 'r');
data = textscan(fid, '%d');
data = reshape(data{1}, 3, []);
x = data(1,:);
y = data(2,:);
fclose(fid);

Concatenation of Matlab strings

I want to make a Matlab function that takes two matrices A and B (of the same size) and combines them in a certain way to give an output that can be used in Latex - table.
I want the first row of the output matrix to consist of the first row of matrix A, with ampersands (&) in between them, and that ends with an double backslash.
The second row should be the first row of B with parentheses around them, and ampersands in between. And so on for the rest of A and B.
If I let A=rand(1,2), I could do this by using [num2str(A(1)), ' & ', num2str(A(2)),' \\'] and so on.
But I want to be able to make a function that does this for any size of the matrix A. I guess I have to make cell structures in some way. But how?
This could be one approach -
%// First off, make the "mixed" matrix of A and B
AB = zeros(size(A,1)*2,size(A,2));
AB(1:2:end) = A;
AB(2:2:end) = B;
%// Convert all numbers of AB to characters with ampersands separating them
AB_amp_backslash = num2str(AB,'%1d & ');
%// Remove the ending ampersands
AB_amp_backslash(:,end-1:end) = [];
%// Append the string ` \\` and make a cell array for the final output
ABcat_char = strcat(AB_amp_backslash,' \\');
ABcat_cell = cellstr(ABcat_char)
Sample run -
A =
183 163 116 50
161 77 107 91
150 124 56 46
B =
161 108 198 4
198 18 14 137
6 161 188 157
ABcat_cell =
'183 & 163 & 116 & 50 \\'
'161 & 108 & 198 & 4 \\'
'161 & 77 & 107 & 91 \\'
'198 & 18 & 14 & 137 \\'
'150 & 124 & 56 & 46 \\'
' 6 & 161 & 188 & 157 \\'
You can use sprintf, it will repeat the format spec as many times as required until all input variables are processed:
%combine both to one matrix
C=nan(size(A).*[2,1]);
C(1:2:end)=A;
C(2:2:end)=B;
%print
sprintf('%f & %f \\\\\n',C.')
The transpose (.') is required to fix the ordering.

If and Contains Statement combined

I have a dimension that logs successes or failures. And I want to create a measure of each (Success and Failure Counts) from this string. I tried creating a calculated field but not sure what is going on: (IF CONTAINS ([RESULT], "success") THEN "Success" ELSE "" END). Here is sample data:
Failure-2DispIn90Or0-Transfer 206
Failure-AcctOverDue-Transfer 625
Success-AppointConfirmMenu 738
Success-ApptFoundReview 1384
Success-Balance Playback 330
Success-BalanceDown 352
Success-FAQ Copy Playback 164
Success-FileAClaimMenu 570
Success-General FAQ Playback 388
Success-GetDispatchByContract Module 15247
Success-Move to Balance Menu 1830
Failure-ValidateContractEntry-Balance-Transfer 162
Failure-ValidateContractEntry-Claims Status-Hang Up 73
Failure-ValidateContractEntry-Claims Status-Normal 22
Failure-ValidateContractEntry-Claims Status-Transfer 170
Failure-ValidateContractEntry-Contract Status-Transfer 131
Failure-ValidateContractEntry-Schedule a Repair-Hang Up 441
Failure-ValidateContractEntry-Schedule a Repair-Transfer 1236
Failure-ValidatePhone Entry-Balance-Hang Up 208
You could go for something like:
Success/Failure:
IF STARTSWITH([Result],"Successs") = true THEN
"Success"
ELSEIF STARTSWITH([Result],"Failure") = true THEN
"Failure"
ELSE
Null
END
Colour the marks by the new calculated field.

plot a stacked bar chart in matlab that shows all the values

Hi I have the following code in Matlab
CC_monthly_thermal_demand = [495 500 500 195 210 100 70 65 85 265 320 430]';
AD_monthly_thermal_generation_250 = [193 193 193 193 193 193 193 193 193 193 193 193]';
figure;
bar(1:12,AD_monthly_thermal_generation_250)
hold on
bar(1:12,CC_monthly_thermal_demand,'r')
set(gca,'XTickLabel',{'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',' Sep', 'Oct', 'Nov',' Dec'},'FontSize',18)
title('Seasonal Anaerobic Digestion (250kWe) Thermal Energy Supply to Demand - 2012','FontSize',22)
ylabel('Thermal Energy (MWhe)')
legend('250 kWth Supply','Thermal Energy Demand')
grid on
axis([0 13 0 600])
I am trying to plot a stacked bar chart that shows the colour of each variable for every bar. However, for the bars where the "AD_monthly_thermal_generation_250" is a lower value than the "CC_monthly_thermal_demand" the "AD_monthly_thermal_generation_250" colour is completely covered by the "CC_monthly_thermal_demand" and so I can't see these values. Is it possible to be able to see them?
Thank you
Combine the inputs together such that each series is a column, then use the option 'stack':
A = [495 500 500 195 210 100 70 65 85 265 320 430]';
B = [193 193 193 193 20 193 193 193 193 193 193 193]';
bar([B,A],'stacked')
EDIT addressing comment:
% Create random data and filler
A = randi(100,10,1);
B = randi(100,10,1);
mxA = max(A);
filler = mxA-A;
% Plot stacked bar chart
h = bar([A,filler,B],'stacked');
% Set the filler to transparent
set(h(2),'Face','none','Edge','none')
% Set y-labels
yticks = linspace(0,max(B),5) + mxA;
set(gca,'Ytick', [linspace(0,mxA,5) yticks(2:end)],'YtickL', [linspace(0,mxA,5) yticks(2:end)-mxA])