Working with .PGM files? - matlab

I need to do some number crunching in .PGM image files.
I'll use MatLab for that.
Now some files (apparently "P2" type) are plain-text and everything is straightforward because they look like this
P2
256 256
255
203 197 197 186 181 181 182 170 165 161 167 171 169 175 163 154 146
138 146 156 166 161 162 164 166 167 177 175 169 167 171 163 153 161
159 159 145 183 181 148 149 151 149 143 175 172 162 156 168 159 159
...
But some files (apparently "P5" type) are like this
P5
256 256
255
*all kinds of random symbols here*
...
Wikipedia here says that the difference is that the latter uses binary encoding. How should I deal with it? I doubt I can import binary data into MatLab...

Have you tired reading the images using imread?
I = imread( pngFilename );

Related

Why am I getting the error "Index exceeds matrix dimensions"?

I am currently new to MATLAB. My code is below. I just have a question regarding why I keep getting the error "Index exceeds matrix dimensions" for the functions provided:
a = [105 97 245 163 207 134 218 199 160 196 221 154 228 131 180 178 157 151 ...
175 201 183 153 174 154 190 76 101 142 149 200 186 174 199 115 193 167 ...
171 163 87 176 121 120 181 160 194 184 165 145 160 150 181 168 158 208 ...
133 135 172 171 237 170 180 167 176 158 156 229 158 148 150 118 143 141 ...
110 133 123 146 169 158 135 149];
mean = mean(a)
std = std(a)
max = max(a)
min = min(a)
range = range(a)
Don't give variables the same names as existing functions. This shadows the function. When you then try to call the function with an argument you instead end up indexing the variable with the argument, which in this case tries to index elements in the variable that don't exist, hence your error.
Use clear to remove the existing variables, then rerun the calculations with new variable names:
clear mean std max min range;
meanResult = mean(a);
stdResult = std(a);
...
Use clc (clear command window), clear (removes all variables from the workspace) and close all (closes off any previously used figures) to clean you work space. This could help run the script better.
clc, clear, close all
a = [105 97 245 163 207 134 218 199 160 196 221 154 228 131 180 178 157 151,...,
175 201 183 153 174 154 190 76 101 142 149 200 186 174 199 115 193 167,...,
171 163 87 176 121 120 181 160 194 184 165 145 160 150 181 168 158 208,...,
133 135 172 171 237 170 180 167 176 158 156 229 158 148 150 118 143 141,...,
110 133 123 146 169 158 135 149];
Mean = mean(a)
Std = std(a)
Max = max(a)
Min = min(a)
Range = range(a)

Skip/Ignore values with maximum difference more than 1 between successive vector from a large array in matlab

Given the following array:
[158 159 159 160 162 163 161 162 162 168 169 163 164 164 165 171 177 178 166 167]
How can I quickly recreate an array which keeps the same order but skips values with the maximum difference more than 1 between successive vector?
The desired result is:
[158 159 159 160 161 162 162 163 164 164 165 166 167]
A= [158 159 159 160 162 163 161 162 162 168 169 163 164 164 165 171 177 178 166 167];
for i=2:length(A)
if i>length(A)
break
end
while abs(A(i)-A(i-1))>1
A(i) = [];
end
end
The starting length(A) is 20 but it will be shorten. Hence, I have to check the condition and break the loop if needed.
I use while instead of if to check whether the successive element. For example, I check the difference between 160 and 162, then 162 was deleted. Then I need to keep check the difference between 160 and 163.
This is a recursive solution:
a= [158 159 159 160 162 163 161 162 162 168 169 163 164 164 165 171 177 178 166 167];
ii=1;
while true
l= length(a);
csa = circshift(a,1);
csa(1)=NaN;
a( a - csa >1 ) = [];
if l == length(a)
break;
end
end
disp(a)
a is the input array modified by the algorithm.
If you run it, the result is:
a = [158 159 159 160 161 162 162 163 164 164 165 166 167]
as desired.
You can use diff along with logical indexing:
a = [158 159 159 160 162 163 161 162 162 168 169 163 164 164 165 171 177 178 166 167];
test = [false diff(a)>1];
while any(test)
a = a(~test);
test = [false diff(a)>1];
end
Which returns:
a =
158 159 159 160 161 162 162 163 164 164 165 166 167

Save variable content to text file

I have 96 x 96 images, I want to convert each image to pixels and save it to a text file. This is an example of code :
frame = imread('c.jpg');
allpixels = reshape(frame, 96*96, 3)
The Output of the command window is :
a
allpixels =
211 194 176
200 183 163
186 169 143
170 150 123
154 133 104
149 128 99
156 135 106
157 136 109
155 135 110
148 126 102
147 123 97
143 118 88
.....
I want to save only the content of the variable allpixels to a text file. It means the text file should be exactly like this :
211 194 176
200 183 163
186 169 143
170 150 123
154 133 104
149 128 99
156 135 106
157 136 109
155 135 110
148 126 102
147 123 97
143 118 88
I have used :
diary('out.txt');
diary on
But out.txt will contain all the command window output, like this :
a
allpixels =
9216×3 uint8 matrix
211 194 176
200 183 163
186 169 143
170 150 123
154 133 104
149 128 99
156 135 106
157 136 109
155 135 110
148 126 102
147 123 97
143 118 88
How can I do that ?
diary is for activity log of your MATLAB session. To store the specific matrix you can use the following code:
dlmwrite('out.txt', a, 'delimiter', ' ');
See the details here.

Difference of pixel value between MATLAB and OpenCV extracting frames from video

I'm trying to open a video file encoded with H264 using Matlab. I rip the first frame, analyze the north-western square 9x9, I get the following matrix:
116 128 126 126 127 126 127 126 130
125 128 127 131 131 130 131 129 127
147 150 150 152 157 151 157 152 149
145 152 158 151 155 158 154 158 156
145 155 157 155 154 161 152 158 154
149 154 151 156 158 152 157 152 156
151 152 155 152 158 151 155 150 151
148 161 156 157 155 155 152 152 154
150 157 150 152 151 149 151 156 155
I try to do the same thing with OpenCV and have the following result:
116 128 125 125 126 125 126 125 130
124 128 126 131 131 130 131 129 126
146 150 150 152 157 151 157 152 149
145 152 158 151 154 158 153 158 156
145 154 157 154 153 160 152 158 153
149 153 151 156 158 152 157 152 156
151 152 154 152 158 151 154 150 151
147 160 156 157 154 154 152 152 153
150 157 150 152 151 149 151 156 154
It is seen that approximately in 50 percent of cases the brightness value of the pixel in the first matrix is one more than in the second one. For this reason, the results of further processing, respectively, in Matlab and OpenCV are different. Can someone explain to me, what is this effect related to and how to overcome it?

Trying to plot a CSV file

I'm trying to plot a CSV file, and this is what it looks like:
Date Ebola: Case counts and deaths from the World Health Organization and WHO situation reports
3/22/2014 49
3/24/2014 86
3/25/2014 86
3/26/2014 86
3/27/2014 103
3/28/2014 112
3/29/2014 112
3/31/2014 122
4/1/2014 127
4/4/2014 143
4/7/2014 151
4/9/2014 158
4/11/2014 159
4/14/2014 168
4/16/2014 197
4/17/2014 203
4/20/2014 208
4/23/2014 218
4/26/2014 224
5/1/2014 226
5/3/2014 231
5/5/2014 235
5/7/2014 236
5/10/2014 233
5/12/2014 248
5/23/2014 258
5/27/2014 281
5/28/2014 291
6/1/2014 328
6/3/2014 344
6/10/2014 351
6/16/2014 398
6/18/2014 390
6/20/2014 390
6/30/2014 413
7/2/2014 412
7/6/2014 408
7/8/2014 409
7/12/2014 406
7/14/2014 411
7/17/2014 410
7/20/2014 415
7/23/2014 427
7/27/2014 460
7/30/2014 472
I imported it into my MATLAB workspace. Now I want to plot this data using MATLAB, but how do I do this? The variables I have for each column are Date and EbolaCaseCountsAndDeathsFromTheWorldHealthOrganizationAndWHOsit (sorry I don't know how to make the latter variable shorter).
I tried doing plot(Date, EbolaCa[...]) but it gives me an error. What is the right way to do it?
You must use both datenum() and datetick() to actually show dates on the x-axis. I was able to create your table snippet as follows:
T={'3/22/2014' 49
'3/24/2014' 86
'3/25/2014' 86
'3/26/2014' 86
'3/27/2014' 103
'3/28/2014' 112
'3/29/2014' 112
'3/31/2014' 122
'4/1/2014' 127
'4/4/2014' 143
'4/7/2014' 151
'4/9/2014' 158
'4/11/2014' 159
'4/14/2014' 168
'4/16/2014' 197
'4/17/2014' 203
'4/20/2014' 208
'4/23/2014' 218
'4/26/2014' 224
'5/1/2014' 226
'5/3/2014' 231
'5/5/2014' 235
'5/7/2014' 236
'5/10/2014' 233
'5/12/2014' 248
'5/23/2014' 258
'5/27/2014' 281
'5/28/2014' 291
'6/1/2014' 328
'6/3/2014' 344
'6/10/2014' 351
'6/16/2014' 398
'6/18/2014' 390
'6/20/2014' 390
'6/30/2014' 413
'7/2/2014' 412
'7/6/2014' 408
'7/8/2014' 409
'7/12/2014' 406
'7/14/2014' 411
'7/17/2014' 410
'7/20/2014' 415
'7/23/2014' 427
'7/27/2014' 460
'7/30/2014' 472};
T=cell2table(T);
T.Properties.VariableNames={'Date','Ebola'};
where the first column is composed by strings and the second column is composed by numbers. To generate the plot() you might want to do something like
figure(1);
plot(datenum(T.Date,'m/dd/yyyy'),T.Ebola);
datetick('x','dd/mmm/yyyy'); grid on;
which shows
However, feel free to adjust datenum() and datetick() format(s) as you wish.