Based on a previous question (read coordinate text file for regionprop usage - Matlab) I wish to plot the object with an extended boundaries (zeros+10) but it does not work. Any reason why?
Code:
clc;
clear;
filename = fullfile('E:/outline.txt');
fileID = fopen(filename);
C = textscan(fileID,'%d %d');
fclose(fileID);
xMax = double(max(C{1})-10)
yMax = double(max(C{2})+10)
bw=roipoly(zeros(xMax ,yMax ),C{1},C{2});
imshow(bw);
stats = regionprops(bw);
coordinate text file content is as follow:
88 10
87 11
87 12
88 13
88 14
92 21
93 22
93 23
94 24
95 25
100 33
101 34
102 34
103 34
103 33
103 32
103 31
103 30
103 29
103 28
103 27
102 26
102 25
101 24
101 23
100 22
100 21
100 20
99 19
99 18
94 12
93 12
92 12
91 11
90 11
xMax = double(max(C{1})-10)
That should probably be +10. This way you make the image smaller than your polygon.
If you want to extend the image on the left side also, add an offset to your polygon coordinates:
bw = roipoly(zeros(yMax, xMax), C{1}+5, C{2}+5);
Note also that I swapped xMax and yMax from your code, this might be another issue you're seeing. Matrix dimensions are specified as (height, width), as are indices into the matrix. But some functions such as roipoly take coordinates with x first and y second. This is a common pitfall with MATLAB syntax.
I just learned that the above is the same as
bw = roipoly(yMax, xMax, C{1}+5, C{2}+5);
Related
I have a coordinate text file and I wish to read it into a regionprop. I wish to use the regionprop for few analysis like Centroid. How can I do it?
Code:
filename = fullfile('E:/outline.txt');
fileID = fopen(filename);
C = textscan(fileID,'%d %d');
fclose(fileID);
stats = regionprops(C,'Centroid')
coordinate text file content is as follow:
88 10
87 11
87 12
88 13
88 14
92 21
93 22
93 23
94 24
95 25
100 33
101 34
102 34
103 34
103 33
103 32
103 31
103 30
103 29
103 28
103 27
102 26
102 25
101 24
101 23
100 22
100 21
100 20
99 19
99 18
94 12
93 12
92 12
91 11
90 11
89 10
88 10
Why don't you just use centroid, which was introduced in 2017b?
[x,y] = centroid(C);
If you are insistent on regionprops (which is slower, and less accurate than operating on the polygon directly) then you are misunderstanding how region props works. Region props works on images. You need to first create an image, then pass the image to region props.
bw = roipoly(zeros(120), C(:,1), C(:,2));
stats = regionprops(bw);
You can find roipoly useful: this allows you to convert a list of 2d points/polygon vertices into a binary mask.
The resulting binary mask can then be fed to regionprops
I have a 3D scatter plot of points in the xyz-sphere. I was wondering if there is a way to colormap/hue the scatter plot based on the density of the data. Basically, the parts of the scatter plot with the most densely clustered data points would be dark red, semi densely clustered data points would be medium red, and sparsely clustered data points would be light red.
This is the way that I was thinking of, but (hopefully) there might be a simpler function or command to do this.
Set a threshold that a data point in the scatter has to be surrounded by:
[ >= 10 other points within a sphere of radius 1 to be colored dark red,
[ 5-9 other points within a sphere of radius 1 to be colored medium red, and
[ 0-4 within a sphere of radius 1 to be colored light red.
Of course, I'm hoping there is a simpler way to do this that involves more than 3 colors in the color map, so if anyone has any ideas how to code this, I'd appreciate the help! Thank you so much.
Here's a snippet of my array:
184 115 3915
185 115 3916
185 115 1205
186 115 4094
187 115 2237
192 115 1519
193 115 1327
201 115 1170
240 115 2946
241 115 1332
54 116 1244
58 116 3650
59 116 3984
60 116 1631
61 116 1198
61 116 1194
62 116 1189
65 116 1185
186 116 3669
188 116 3986
189 116 2027
197 116 1200
201 116 1254
226 116 3752
227 116 1457
242 116 1405
54 117 1191
54 117 1305
56 117 1177
58 117 1169
61 117 1367
62 117 1428
62 117 1434
62 117 1435
63 117 1422
198 117 1197
229 117 1312
230 117 1179
243 117 1272
55 118 1236
56 118 1166
61 118 1191
65 118 1755
57 119 1213
57 119 1176
58 119 1253
62 119 1365
62 119 1331
63 119 1457
63 119 1251
66 119 1842
66 119 1468
59 120 1489
59 120 1387
60 120 1218
60 120 1224
61 120 1214
61 120 1440
62 120 1198
64 120 1240
205 120 3601
205 120 1168
206 120 3727
207 120 4089
208 120 2128
208 120 1160
56 121 1293
57 121 1183
59 121 1371
59 121 1347
61 121 1314
64 121 1346
207 121 3562
208 121 3845
209 121 3534
210 121 1201
210 121 1405
83 122 1794
206 122 1259
207 122 1161
83 123 3550
In my approach I'm using a threshold factor T to determine how many other points are considered in the calculation of distances for each individual point. T = 1 means for every point the average distance to all other points is calculated, T = 0.01 means for every point the average distance to the closest 1% of the the other points is calculated.
figure
%// example data
[X,Y,Z] = sphere(15);
x = [0.1*X(:); 0.4*X(:); 0.7*X(:)];
y = [0.2*Y(:); 0.5*Y(:); 0.8*Y(:)];
z = [0.3*Z(:); 0.6*Z(:); 0.9*Z(:)];
D = [x(:), y(:), z(:)];
N = numel(x);
%// calculation of color vector
[n,m] = ndgrid(1:N,1:N);
%// euclidian distance of each point to every other point
X = arrayfun(#(a,b) sum( (D(a,:) - D(b,:)).^2 ), n, m);
%% subplot 1
%// threshold factor
T = 0.01;
%// sort distances of points
Y = sort(X,2);
%// calculate average distance of the closest T% of all points
Z = mean(Y(:,2:ceil(N*T)),2);
%// plot
subplot(121)
scatter3(x,y,z,20,Z,'filled');
title('T = 0.01')
colormap
colorbar
%% subplot 2
%// threshold factor
T = 1;
Y = sort(X,2);
Z = mean(Y(:,2:ceil(N*T)),2);
%// plot
subplot(122)
scatter3(x,y,z,20,Z,'filled');
title('T = 1')
colormap
colorbar
This is a pretty crude function, but I think it achieves a similar result to what you want.
Loop through each point, calculate the number of points within some tolerance distance.
Plot these points, using the count of nearby points as a scaling for the colour.
Code:
a = rand(1000,3); % Create random matrix, use your data here
n = zeros(size(a,1),1); % Set up array for number of nearby points
tol = 0.2; % Tolerance for (squared) distance to count as "nearby"
sz = size(a,1); % Shorthand for size of data
% Loop over every point
for ii = 1:sz;
dists = sum((repmat(a(ii,:), sz, 1) - a).^2, 2); % Get standard Euclidean distance
n(ii) = nnz(dists < tol); % Count number of points within tolerance
end
% Plot, colouring by an nx3 RGB array, in this case just
% scaling the red and having no green or blue.
scatter3(a(:,1), a(:,2), a(:,3), [], [n./max(n), zeros(numel(n),2)], 'filled');
grid on;
Output:
It is the result of GLCM matrix. What is the meaning of black horizontal and vertical lines in GLCM image? Are they a problem?
N = numel(unique(img)); % img is uint8
glcm = graycomatrix(img, 'NumLevels', N);
imshow(glcm)
I suspect this is the problem: For the function graycomatrix, You have supplied a 'NumLevels' argument which is larger than the number of unique graylevels in your image. For instance, a 256-level (8-bit) image will have only 256 graylevels. Asking for 1000 levels in the output means 744 levels will have no data! i.e. Yes, this is a problem. You can check how many graylevels your image has using numel(unique(I)).
p.s. In the future, please attach the code you used to generate the problem.
graycomatrix calculates the GLCM from a scaled version of the image. Due to round-off errors in the scaling process the number of different intensity levels in the scaled image may be less than the number of different intensity levels in the original image .
Consider the following sample image:
img = uint8([ 48 161 209 64 133 240 166 227;
184 54 181 33 107 252 242 255
217 191 125 112 204 252 135 201
163 222 66 125 229 140 38 97
252 214 201 191 10 102 242 74
191 74 77 8 163 51 189 186]);
From the documentation (emphasis mine):
[glcms,SI] = graycomatrix(___) returns the scaled image, SI, used to calculate the gray-level co-occurrence matrix. The values in SI are between 1 and NumLevels.
If you set NumLevels to the number of different intensity levels (which in this example is 39)
N = numel(unique(img))
[glcm_scaled, img_scaled] = graycomatrix(img, 'NumLevels', N);
the returned GLCM has 39*39 elements. The issue is that the scaled image has only 28 different intensity levels:
>> img_scaled
img_scaled =
8 25 32 10 21 37 26 35
29 9 28 6 17 39 38 39
34 30 20 18 32 39 21 31
25 34 11 20 36 22 6 15
39 33 31 30 2 16 38 12
30 12 12 2 25 8 29 29
>> numel(unique(img_scaled))
ans =
28
As a consequence, the GLCM will have 11 rows and 11 columns in which all the entries are zero (black lines).
If you do not wish this to happen, you can map the intensity levels through a lookup table:
levels = unique(img);
N = numel(levels);
lut = zeros(256, 1);
for i=1:N;
index = uint16(levels(i)) + 1;
lut(index) = i;
end
img_lut = lut(uint16(img) + 1);
[glcm_mapped, img_mapped] = graycomatrix(img_lut, 'NumLevels', N, 'GrayLimits', []);
By doing so, img_mapped is exactly the same as img_lut and there is no black lines in the GLCM. Notice that by specifying empty brackets for the GrayLimits parameter, graycomatrix uses the minimum and maximum grayscale values in the input image as limits.
I was seeing the same behaviour under my own GLCM implementation.
The issue was that I was implementing the histogram equalization given a number of gray levels.
I compute the discretization of the image before dividing first and then enter to review if any row or column is given inly zeros values.
I would like to plot a topographic map from EEG network. The electrodes (nodes) have a associated networks metric and from these values I want to interpolate between them and plot in a head shape. Here is the code that i have reseached and the result that I am getting...
=========================================
%The position X and Y as integers (electrodes position) and the value of Z (network metric)
X = [36 51 66 11 22 51 79 91 3 16 51 86 99 1 14 51 88 101 3 16 51 86 99 11 22 51 79 91 36 51 66];
Y = [99 101 99 80 85 87 85 80 66 69 70 69 66 51 51 51 51 51 36 33 32 33 36 22 17 15 17 22 3 1 3];
Z = [-404 -566 -379 -71 -102 -119 -87 9 -62 -160 -104 -81 -26 12 -120 -176 -85 -13 0 -118 -288 -159 -36 -115 -145 -292 -215 -266 -235 -364 -192];
%Making the meshgrid
for dd = 1:31
I(Xd(dd),Yd(dd))=Zd(dd);
end
Zd = [Zd; zeros(70,1)];
Xd = [Xd; zeros(70,1)];
Yd = [Yd; zeros(70,1)];
[XX,YY] = meshgrid(1:101,1:101);
z = griddata(Xd,Yd,Zd,XX,YY,'cubic');
contourf(z)
=========================================
The resulting plot of this code is
http://s16.postimg.org/s7a627s5h/Graph.jpg
I would like some help to remove this "tail" from my graph and a sugggestion of how to draw a head + nose on the same picture (only if it is possible to plot this kind of graph).
I don't have enough reputation to comment above but you can set your own custom locations in EEGlab as far as I remember. Have you looked at the function writelocs? Maybe that helps. EEGlab's topoplots include nose and ears.
http://sccn.ucsd.edu/eeglab/allfunctions/writelocs.html
The below code is not running in matlab. I am trying an anonymous function in matlab.Can you pls tell me whats wrong in this line :
Inv_Y_Quant = blockproc(BB,[8 8], InvQuant);
and the related code is below:
clear all
clc
I = imread('cameraman.tif');
% convert it to double
I = im2double(I);
% "Trim by 128"
I = I-128;
% Generate the DCT matrix
T = dctmtx(8);
% Generate Function handler for DCT
MyFun1 = #(block_struct) T * block_struct.data * T';
% BlockProcess the DCT the function for 8 by 8 blocks
B = blockproc(I,[8 8],MyFun1);
% Form the Quantization matrix
Q = [ 16 11 10 16 24 40 51 61
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99];
% now generate function handler for the quantization
MyFun2 = #(block_struct)block_struct.data ./Q;
% perform the quantization
BB = blockproc(B,[8 8],MyFun2);
InvQuant = #(block_struct)round(block_struct.data.*Q);
Inv_Y_Quant = blockproc(BB,[8 8], InvQuant);
InvDct = #(block_struct)dct_matrix'*block_struct.data*dct_matrix;
Z = blockproc(Inv_Y_Quant, [8 8], InvDct);
Z = Z+128;
figure, imshow(Z)
Z = uint8(Z);
figure, imshow(Z)
%imwrite(Z, 'Mar7.tif');
%b = imread('Mar7.tif');
%imshow(b)
As you wrote in your comment, the problem is that you try to use array dct_matrix in anonymous function InvDct. This array was never defined in your code.
Did you meant to use matrix T (init as dctmtx(8))?
edit:
When using parameters in anonymous functions (as dct_matrix in this example), these parameters should be defined before the anonymous function is defined.