Index exceeds matrix dimentions erro in matlab - matlab

This is part of my script:
fid = fopen([directory '001/listing.txt'],'r');
tline = fgetl(fid);
ii = 0;
while (tline ~= -1)
ii = ii + 1;
year(ii) = str2num(tline(11:14));
month(ii) = str2num(tline(15:16));
day(ii) = str2num(tline(17:18));
hour(ii) = str2num(tline(20:21));
min(ii) = str2num(tline(22:23));
sec(ii) = str2num(tline(24:25));
tline = fgetl(fid);
end
fclose(fid);
I keep getting the error "Index exceeds matrix dimensions". Can someone help me here?

Sometimes tline is less than 25 characters long.
My guess is that you have some blank lines in your file that doesn't cause fgetl to return -1 but an empty string instead.
Put an if just after while to skip empty lines:
if (length(tline) == 0)
continue
end
If you still have problems, change the == 0 part for <25 to make sure all lines you process are at least 25 characters long.

Related

read specific lines from a text file in matlab and associating the lines together

I have a text file that have many sets of 11 lines.
For each set, I would like to read line 2 and line 11 out of the 11 lines.
and associate the 2 lines together. how do I get about doing it?
I used "fgets" but I dunno how to read just specific lines. Help much needed. thanks!
fid = fopen('images_list1.txt');
tline = fgetl(fid);
char line[2];
while ischar(tline)
disp(tline)
tline = fgetl(fid);
end
fclose(fid);
You can use a while loop to keep getting lines of text from the file, keeping only every 2nd and 11th line:
% open the file
fid = fopen('images_list1.txt');
% initialize a counter
count = 0;
% keep reading the file
while 1;
% get a line of text
tline = fgetl(fid);
count = count + 1;
% exit if the line is empty
if tline == -1;
break;
end
% check modulus of count for every 2nd and 11th line
if mod(count,11) == 1;
tline_2nd = tline;
elseif mod(count,11) == 10;
tline_11th = tline;
% do something with the 2nd and 11th lines ("associate" them)
end
end

Importing data block with Matlab

I have a set of data in the following format, and I would like to import each block in order to analyze them with Matlab.
Emax=0.5/real
----------------------------------------------------------------------
4.9750557 14535
4.9825821 14522
4.990109 14511
4.9976354 14491
5.0051618 14481
5.0126886 14468
5.020215 14437
5.0277414 14418
5.0352678 14400
5.0427947 14372
5.0503211 14355
5.0578475 14339
5.0653744 14321
Emax=1/real
----------------------------------------------------------------------
24.965595 597544
24.973122 597543
24.980648 597543
24.988174 597542
24.995703 597542
25.003229 597542
I have modified this piece of code from MathWorks, but I think, I have problems dealing with the spaces between each column.
Each block of data consist of 3874 rows and is divided by a text (Emax=XX/real) and a line of ----, unfortunately is the only way the software export the data.
Here is one way to import the data:
% read file as a cell-array of lines
fid = fopen('file.dat', 'rt');
C = textscan(fid, '%s', 'Delimiter','');
C = C{1};
fclose(fid);
% remove separator lines
C(strncmp('---',C,3)) = [];
% location of section headers
headInd = [find(strncmp('Emax=', C, length('Emax='))) ; numel(C)+1];
% extract each section
num = numel(headInd)-1;
blocks = struct('header',cell(num,1), 'data',cell(num,1));
for i=1:num
% section header
blocks(i).header = C{headInd(i)};
% data
X = regexp(C(headInd(i)+1:headInd(i+1)-1), '\s+', 'split');
blocks(i).data = str2double(vertcat(X{:}));
end
The result is a structure array containing the data from each block:
>> blocks
blocks =
2x1 struct array with fields:
header
data
>> blocks(2)
ans =
header: 'Emax=1/real'
data: [6x2 double]
>> blocks(2).data(:,1)
ans =
24.9656
24.9731
24.9806
24.9882
24.9957
25.0032
This should work. I don't think textscan() will work with a file like this because of the breaks between blocks.
Essentially what this code does is loop through lines between blocks until it finds a line that matches the data format. The code is naive and assumes that the file will have exactly the number of blocks lines per block that you specify. If there were a fixed number of lines between blocks it would be a lot easier and you could remove the first inner loop and replace with just ~=fgets(fid) once for each line.
function block_data = readfile(in_file_name)
fid = fopen(in_file_name, 'r');
delimiter = ' ';
line_format = '%f %f';
n_cols = 2; % Number of numbers per line
block_length = 3874; % Number of lines per block
n_blocks = 2; % Total number of blocks in file
tline = fgets(fid);
line_data = cell2mat(textscan(tline,line_format,'delimiter',delimiter,'MultipleDelimsAsOne',1));
block_n = 0;
block_data = zeros(n_blocks,block_length,n_cols);
while ischar(tline) && block_n < n_blocks
block_n = block_n+1;
tline = fgets(fid);
if ischar(tline)
line_data = cell2mat(textscan(tline,line_format,'delimiter',delimiter,'MultipleDelimsAsOne',1));
end
while ischar(tline) && isempty(line_data)
tline = fgets(fid);
line_data = cell2mat(textscan(tline,line_format,'delimiter',delimiter,'MultipleDelimsAsOne',1));
end
line_n = 1;
while line_n <= block_length
block_data(block_n,line_n,:) = cell2mat(textscan(tline,line_format,'delimiter',delimiter,'MultipleDelimsAsOne',1));
tline = fgets(fid);
line_n = line_n+1;
end
end
fclose(fid)

error with "The matrix MSG in ENCODE must have K columns"

im working on a video steganography using LSB technique..im using traffic.avi and xylophone.mpg as the cover medium and when im using the licence.txt file (in the attach file) to encode into the video it runs well however when im using a short messsage for the input text it shows an error which is
"The matrix MSG in ENCODE must have K columns." and sometimes when use short text it gives error "msg is too long to encode"
i have no idea what does this 2 set of coding means and how to edit the code to make it possible to encode a short msg...below this is some of the code that i guess relate to this problem
num2add = 80-length(msg); % Number of spaces to add to end of MSG.
if num2add < 0, error('This message is too long to encode.'), end
newmsg = [msg,repmat(' ',1,num2add)]; % 80 chars always encoded.
msgmat = dec2bin(newmsg)-48; % Each row is a bin. rep. of an ascii char.
and also this coding
if m_msg == 1
type_flag = 2; % binary vector
[msg, added] = vec2mat(msg, k);
elseif m_msg ~= k
error('comm:encode:InvalidMatrixColumnSize','The matrix MSG in ENCODE must have K columns.');
BELOW THIS IS THE FULL ENCODE CODING continue after the first part of the above coding!
B = pic1(:,:,1); [piclngth pichght] = size(B); % Choose the first page.
dim1 = piclngth-2; dim2 = pichght-3; keyb = key(end:-1:1);
rows = cumsum(double(key));
columns = cumsum(double(keyb)); % Coord pairs for KEY (rows,columns)
A = zeros(dim1,dim2); % This matrix will house the hiding points.
A = crtmtrx(A,rows,columns,dim1,dim2,key);
idx = find(A==1); % This same index will be used for pic matrix.
for vv = 1:80 % This is the encoder.
for uu = 1:8
if msgmat(vv,uu)==1;
if rem(B(idx(uu+8*(vv-1))),2)==0
if(frame==1)
disp('some pixel value of original frame');
B(idx(uu+8*(vv-1)))
end
B(idx(uu+8*(vv-1))) = B(idx(uu+8*(vv-1)))+1;
if(frame==1)
disp('some pixel value of stegno video frame');
B(idx(uu+8*(vv-1)))
end
end
elseif rem(B(idx(uu+8*(vv-1))),2)==1
if(frame==1)
disp('some pixel value of original frame');
B(idx(uu+8*(vv-1)))
end
B(idx(uu+8*(vv-1))) = B(idx(uu+8*(vv-1)))-1;
if(frame==1)
disp('some pixel value of stegno video frame');
B(idx(uu+8*(vv-1)))
end
end
end
end
global newpic;
newpic = pic1; newpic(:,:,1) = B;
f(frame) = im2frame(newpic);
end
frameRate = get(vidObj,'FrameRate');
movie2avi(f,'stegano_video.avi','compression','None', 'fps', 20);
success = 1;
function A = crtmtrx(A,rows,columns,dim1,dim2,key)
% Creates the matrix used to find the points to hide the message.
jj = 1; idx = 1;
while 640 > length(idx) % Need 560 points to hide 80 characters.
for ii = 1:length(rows)
if rows(ii) < dim1
rows(ii) = rem(dim1,rows(ii))+1;
else
rows(ii) = rem(rows(ii),dim1)+1;
end
if columns(ii) < dim2
columns(ii) = rem(dim2,columns(ii))+1;
else
columns(ii) = rem(columns(ii),dim2)+1;
end
A(rows(ii),columns(ii)) = 1;
end
rows = jj*cumsum(double(columns))+round(dim2/2); % Each pass is diff.
columns = jj*cumsum(double(rows))+round(dim1/2);
if jj > ceil(640/length(key))+2 % Estimate how many iters. needed.
idx = find(A==1);
end
jj = jj+1;
end
this is some of the input text and the right one is the encypted txt
The code that triggers the error is pretty clear:
num2add = 80-length(msg); % Number of spaces to add to end of MSG.
if num2add < 0, error('This message is too long to encode.'), end
So basically you will get the error as soon as there are more than 80 characters in msg. I am not sure whether the 80 is meaningfull, you can try to increase it but that may break something else.

Matlab: Having trouble with this code regarding arrays

Here is the question:
The file upcs.txt contains a list of UPC codes that were scanned in a grocery
store. Each line should, ideally, contain 12 digits corresponding to a single product. Read
the contents of the file and store the entries into an m x 12 sized numeric array named
codes, where m is the number of valid lines in the le. Lines that have less or more than
12 digits should be discarded. Some lines with 12 digits may have digits that were not
correctly scanned, which were replaced by the letter X'. These missing digits should be
represented in the array codes by the integer-1'. After processing the file, print the total
number of lines read, the number of lines discarded, and the number of lines correctly
processed and stored in codes.
upcs.txt:
X9096X082489
921642004330
810905023006
733554287763
413527622XX1
287X35871528
100093334850
764491079X90
1537X8886614
086755751640
860053705316
980098819206
038356338621
577577248178
82825685985
684580785580
736657539753
71113617151
935014271064
702345843488
58316491755
110118383664
333841856254
996003013296
495258095746
4457870230
684104168936
522784039910
6504512835
699553963094
853110488363
554147120089
Here is my code so far:
fid = fopen('upcs.txt');
mat = [];
if fid == -1
disp('File open was not successful')
else codes = {};
while feof(fid) == 0
aline = fgetl(fid);
num = strtok(aline);
codes = [codes; num]
end;
[m n] = size(codes)
discard = 0
for i = 1:m
len = length (codes(i))
if len ~= 12
codes = [];
discard = discard + 1
else
char(codes(i))
codes = strrep(codes, 'X', '-1')
end
end
codes
end
The trouble I am having is that I don't know how to delete the codes that have less or more than 12 digits in my code.
clear;clc;
fid = fopen('upcs.txt','r');
if fid == -1
error('File open was not successful');
end
C = textscan(fid,'%s');
C = C{1};
all_codes_num = size(C,1);
codes_discarded_num = 0;
codes_missed_digit_num = 0;
codes_correct_num = 0;
codes = [];
for i = 1:all_codes_num
one_code = C{i};
if length(one_code) == 12
x_flag = 0;
code_tmp = zeros(1,12);
for j = 1:12
if one_code(j) == 'X' || one_code(j) == 'x'
code_tmp(j) = -1;
x_flag = 1;
else
code_tmp(j) = str2num(one_code(j));
end
end
if x_flag == 1
codes_missed_digit_num = codes_missed_digit_num +1;
end
codes = [codes;code_tmp];
elseif length(one_code) ~= 12
codes_discarded_num = codes_discarded_num + 1;
end
end
all_codes_num
codes_discarded_num
codes_with_x = codes_missed_digit_num
correct_codes_without_x = all_codes_num - codes_discarded_num - codes_with_x
codes: have all the correct codes and also 12-length codes with missing data which has been replaced with '-1'. This is a m*12 numeric matrix. Each row is a code.
all_codes_num: the number of all the lines we have read
codes_discarded_num: the number of all the codes which have more or less than 12 chars
codes_with_x: the number of 12-length codes which have missing digits.
correct_codes_without_x: the number of 12-length codes which have digits only.
In the codes, I assume that in the 'upcs.txt', each line is a code.

Matlab Muliple delimiter removing during import

I am struggling with a problem and want a easy way around. I have a big array of data where I have some vector values as ( 1.02 1.23 3.32) format. I want it as 1.02 1.23 3.32 in a tabular form. The problem here is that there are two types of delimiter '(' and ')'.
can anyone help in writing a code for this? I have something like this:
filename = 'U.dat';
delimiterIn = '(';
headerlinesIn = 0;
A = textscan(filename,delimiterIn,headerlinesIn);
But one thing is that it only have one delimiter "(" and it does not work either.
Nishant
If your text file looks something like this:
(1 2 3) (4 5 6)
(7 8 9) (10 11 12)
You can read it in as strings and convert it to a cell array of vectors like this:
% read in file
clear all
filename = 'delim.txt';
fid = fopen(filename); %opens file for reading
tline = fgets(fid); %reads in a line
index = 1;
%reads in all lines until the end of the file is reached
while ischar(tline)
data{index} = tline;
tline = fgets(fid);
index = index + 1;
end
fclose(fid); %close file
% convert strings to a cell array of vectors
rowIndex = 1;
colIndex = 1;
outData = {};
innerStr = [];
for aCell = data % for each entry in data
sline = aCell{1,1};
for c = sline % for each charecter in the line
if strcmp(c, '(')
innerStr = [];
elseif strcmp(c, ')')
outData{rowIndex,colIndex} = num2str(innerStr);
colIndex = colIndex + 1;
else
innerStr = [innerStr, c];
end
end
rowIndex = rowIndex + 1;
colIndex = 1;
end
outData