Error Using VideoReader/read (line 160) Unable to read the file.

3 views (last 30 days)
I am analyzing every 50th frame from a videofile. I store mulitple .avi files to analyze in a folder. My code loops through these video files one by one, analyzing every 50th frame. This code can successfully analyze multiple 30s videos with no errors. A problem occurs when I run the code to analyze longer video files (1hr-2hr).
When I run my code to read the frames of a longer file I get the following error: Error Using VideoReader/read (line 160) Unable to read the file. The code successfully reads and analyzes several hundred frames, and then abruptly throws out an error message at a seemingly arbitrary point in the analysis.
The first time that I ran the code on a long file, the error occured at frame no. 32'401. I ran the code a second time, and the error occured at frame no. 97'901. After each error, I tried to see if there was something errorneous about that particular frame in the video - this is not the case, I could successfully read both of the frames individually using the function from my loop: read(video,frameNo.).
This error, and my subsequent plot of the frame that caused the error, can be seen in the picture below. Please draw your attention to the picture. In the command window we see the output from the script; the text displayed describes the video being analyzed, and the frame no. being analyzed "video 1 of 2, second 1958 of 2408". We see that 1958s into the video analysis there is a frame that causes an error, see error message in command window. The following lines under the error message show my investigation as to whether there is something wrong with the frame itself. The frame no. at 1958s is 97901. Imshow is able to show the frame in question (xray image in Figure 1) leading me to believe the error does not lie with the frame itself.
MATLAB Error.jpg
Below is my code. The error occurs 1/3 through the script, marked by the !! ERROR HERE !! sign.
To run properly, it needs to access a video file with the word 'xray' in the title. To replicate the error, create a folder and save a 1+hr video in that folder with XRAY in the title of the video.
% select folder where data is stored
datafolder = uigetdir([],'SELECT DATA FOLDER');
cd(datafolder)
% read all folders with the word file in the name
folders2read = dir('*XRAY*');
% Define variables
binarize_threshold = 0.1; % setting the screen from greyscale to black and white with this threshold
fps = 50;
% Read in video data to MATLAB
for k = 1:length(folders2read)
Patient_data{k} = VideoReader(folders2read(k).name);
d(k) = Patient_data{k}.Duration;
totalframes(k) = d(k)*fps;
end
% Define region of interest for image analysis. Same for all.
frame = read(Patient_data{1}, round(Patient_data{1}.NumberOfFrames/2)); %#ok<*VIDREAD> % choose frame in middle of video as in the beginning the video sometime is all black
frame = rgb2gray(frame);
frame = imbinarize(frame, binarize_threshold);
imshow(frame);
roi = round(getPosition(imrect)); % select roi: Draw bounding box close to digits! This region of interest is the same for all videos.
ocr_results(1) = ocr(frame, roi, 'CharacterSet', '0123456789:');
close
%%
% Loop through each frame within each Video and get Radiation Time
for k = 1:length(folders2read)
j = 1;
for i = 1:fps:totalframes(k) %initval:step:endval
time(j,1)=j-1; % tracks the no. of seconds of video passed, starts at 0s.
fprintf('Video %d of %d. Second %d of %d.\n',k,length(folders2read),time(j,1),round(d(k))); %print analysis info to console
!! ERROR HERE !!
%reads frame (i) in XRayVideo put myvideodata{k}
frame = read(Patient_data{k}, i); % !! ERROR HERE !!!
!! ERROR HERE !!
% Test if faster to use: frame = imcrop(frame, roi);
frame = rgb2gray(frame);
frame = imbinarize(frame, binarize_threshold);
ocr_results(j) = ocr(frame, roi, 'CharacterSet', '0123456789:'); % ocr = optical character recognition. recognize text in region of interest.
text = deblank(ocr_results(j).Text); % remove any trailing characters, such as white space or new lines
% check if text has enough entries at least 5 are needed (mm:ss)
% check if ocr found two digits for mm and two digits for ss in mm:ss.
if length(text)>=5 %what happens if the text is greater than 5...we always take the 1st two digits as the minutes, this could be a problem.
if isstrprop(text(1),'digit') && isstrprop(text(2),'digit') && isstrprop(text(4),'digit')&& isstrprop(text(5),'digit')%length(ocr_results(j).Text)>=5. Evaluate if text(i) is a digit.
radminutes(j,1) = str2num(text(1:2)); % converts the text strings into numbers
radseconds(j,1) = str2num(text(4:5));
rad_vid(j,1) = 60*radminutes(j,1) + radseconds(j,1); %records the no. of seconds of radiation time from the video
end
else
radminutes(j,1) = NaN;
radseconds(j,1) = NaN;
rad_vid(j,1) = NaN; % sets the no. of seconds of radiation time to NaN if it cannot read the ROI.
end
% time
frame_count(j,1) = i;
j = j+1;
end
%% Post-Processing: Check Whether Radiation was On/Off
% confirm whether the radiation was on or not. The plot of this data will also check whether
% the radiation decreases, or increases by 2+ i.e. if there were any bugs in the video.
% initialize
on_off = zeros(length(rad_vid),1);
on_off(1) = 0; % the first radiation value we set to Off, because we don't know if it was on before the recording started.
% we may underestimate by 1second every time.
for i = 2:length(rad_vid)
on_off(i,1) = rad_vid(i) - rad_vid(i-1); % will output 1s or 0s (or 2s if the video jumped)
end
%% save data to text file
fid = fopen(sprintf('%s .txt',folders2read(k).name),'w'); %create the text file. name should be from original file name.
fprintf(fid,'Time(s) Frame RadiationTime(s) OnOff %s \r\n',folders2read(k).name); % set the headers of text file
fprintf(fid,'%d %d %d %d\r\n',[time frame_count rad_vid on_off]'); % write data from MATLAB to text file
fclose(fid);
p = plot(time,on_off);
saveas(p,sprintf('OnOff %s.png',folders2read(k).name));
% p = plot(time,rad_vid);
% saveas(p,sprintf('Rate %s.png',folders2read(k).name));
%import = importdata('XRAY_short.mp4.txt')
%% Clear data in variables for the next video to be analyzed
time = [];
frame_count = [];
on_off = [];
rad_vid = [];
end
  1 Comment
Steven Flavell
Steven Flavell on 6 Apr 2020
Did you ever find a solution to this problem? I believe we are encountering the same problem

Sign in to comment.

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!