MATLAB - video processing - matlab

The code is for video processing in MATLAB and I have a problem in the first loop. I do not know what the problem is but the error that MATLAB gives is :
Assignment has more non-singleton rhs dimensions than non-singleton subscripts
Error in fi (line 34)
data(:,:,f) = I;
Here is my code:
clc;
close all;
clear all;
It1c = imread( '\\icnas1.cc.ic.ac.uk\fi15\Desktop\frames\Frames_V11\051.png' );
It600c = imread( '\\icnas1.cc.ic.ac.uk\fi15\Desktop\frames\Frames_V11\009.png' );
resf = 0.27e-6;
fr_r = 12000; %frame rate = 12000 fps
figure();
imagesc(It1c);
figure();
imagesc(It600c);
listing = dir('\\icnas1.cc.ic.ac.uk\fi15\Desktop\frames\Frames_V11\*.png');
N = 51;
data = zeros(624,1024,N);
for f = 1:N,
f
I = imread(['Frames_V11\',fullfile(listing(f).name)] );
data(:,:,f) = I;
end
figure; %see frames
for i = 1:N,
imagesc(data(:,:,i));
colorbar;
pause(0.1);
end
figure; %see frames
for i = 1:N,
imagesc(data(:,:,i)-data(:,:,1));
colorbar;
pause(0.1);
end
for i = 1:N,
i
data2(:,:,i) = data(:,:,i)-data(i);
end
figure; %see frames
for i = 1:N,
imagesc(data2(:,:,i));
colorbar;
pause(0.1);
end
figure;
imagesc(squeeze( mean(data2(230:270,:,:),1) ));
figure;
plot(squeeze(mean(mean(data5(210:235,395:425,:),1),2)));

Your image data is likely RGB and therefore has the following dimensions [nRows, nCols, nChannels] where nChannels is likely 3. The error is because you're trying to assign this 3D matrix to a 2D slice in data.
You need to therefore concatenate all of the images along the fourth dimension instead of the third.
data = zeros(624, 1024, 3, N);
for f = 1:N
data(:,:,:,f) = imread(['Frames_V11\',fullfile(listing(f).name)]);
end

Related

Detecting lanes in a video using matlab and image processing.

I am a little bit new to matlab and imageprocessing and I was given a task at my faculty to carry out a project which detects the lanes for a moving car in a video. I tried to use some tutorials on Mathworks and other sites and there were really helpful and I came out with a code that detects lanes in an image and I just want to know how to apply my code on a video as I see it working properly on an image.
and here is my code :
img = imread ('test_image.jpg');
I = rgb2gray (img);
%making a gaussian kernel
sigma = 1 ; %standard deviation of distribution
kernel = zeros (5,5); %for a 5x5 kernel
W = 0 ;
for i = 1:5
for j = 1:5
sq_dist = (i-3)^2 + (j-3)^2 ;
kernel (i,j) = exp (-1*exp(sq_dist)/(2*sigma));
W = W + kernel (i,j) ;
end
end
kernenl = kernel/W ;
%Now we apply the filter to the image
[m,n] = size (I) ;
output = zeros (m,n);
Im = padarray (I , [2 2]);
for i=1:m
for j=1:n
temp = Im (i:i+4 , j:j+4);
temp = double(temp);
conv = temp.*kernel;
output(i,j) = sum(conv(:));
end
end
output = uint8(output);
%--------------Binary image-------------
level = graythresh(output);
c= im2bw (output,level);
%---------------------------------------
output2 = edge (c , 'canny',level);
figure (1);
%Segment out the region of interest
ROI = maskedImage;
CannyROI = edge (ROI , 'canny',.45);
%----------------------------------
set (gcf, 'Position', get (0,'Screensize'));
%subplot (141), imshow (I), title ('original image');
%subplot (142), imshow (c), title ('Binary image');
%subplot (143), imshow (output2), title ('Canny image');
%subplot (144), imshow (CannyROI), title ('ROI image');
[H ,T ,R] = hough(CannyROI);
imshow (H,[],'XData',T,'YData',R,'initialMagnification','fit');
xlabel('\theta'), ylabel('\rho');
axis on , axis normal, hold on ;
P = houghpeaks(H,5,'threshold',ceil (0.3*max(H(:))));
x = T(P(:,2));
y = R(P(:,1));
plot (x,y,'s','color','white');
%Find lines and plot them
lines = houghlines (CannyROI,T,R,P,'FillGap',5,'MinLength',7);
figure, imshow (img), hold on
max_len = 0 ;
for k = 1:length(lines);
xy = [lines(k).point1; lines(k).point2];
plot (xy(:,1), xy(:,2), 'LineWidth', 5 , 'Color', 'blue');
%plot beginnings and ends of the lines
plot (xy(1,1), xy(1,2),'x', 'LineWidth', 2, 'Color', 'yellow');
plot (xy(2,1), xy(2,2),'x', 'LineWidth', 2, 'Color', 'red');
%determine the endpoints of the longest line segment
len = norm(lines(k).point1 - lines(k).point2);
if (len>max_len)
max_len = len;
xy_long = xy;
end
end
and here is the link of the image and the video :
https://github.com/rslim087a/road-video
https://github.com/rslim087a/road-image
Thanks in advance.
Basically video processing happens in such a way that video will be converted to video frames (images). So if you need, you can convert your video to video frames and run the code, looping over the folder having the video frames. Change the imread function to get images from video frames folder...
img = imread(path_to_video_frames_folder/*)

To refresh imshow in Matlab?

I want to convert this answer's code to imshow.
It creates a movie in MOVIE2AVI by
%# preallocate
nFrames = 20;
mov(1:nFrames) = struct('cdata',[], 'colormap',[]);
%# create movie
for k=1:nFrames
surf(sin(2*pi*k/20)*Z, Z)
mov(k) = getframe(gca);
end
close(gcf)
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10);
My pseudocode
%# preallocate
nFrames = 20;
mov(1:nFrames) = struct('cdata',[], 'colormap',[]);
%# create movie
for k=1:nFrames
imshow(signal(:,k,:),[1 1 1]) % or simply imshow(signal(:,k,:))
drawnow
mov(k) = getframe(gca);
end
close(gcf)
movie2avi(mov, 'myPeaks1.avi', 'compression','None', 'fps',10);
However, this creates the animation in the screen, but it saves only a AVI -file which size is 0 kB. The file myPeaks1.avi is stored properly after running the surf command but not from imshow.
I am not sure about the command drawnow.
Actual case code
%% HSV 3rd version
% https://stackoverflow.com/a/29801499/54964
rgbImage = imread('http://i.stack.imgur.com/cFOSp.png');
% Extract blue using HSV
hsvImage=rgb2hsv(rgbImage);
I=rgbImage;
R=I(:,:,1);
G=I(:,:,2);
B=I(:,:,3);
R((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
G((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
B((hsvImage(:,:,1)>(280/360))|(hsvImage(:,:,1)<(200/360)))=255;
I2= cat(3, R, G, B);
% Binarize image, getting all the pixels that are "blue"
bw=im2bw(rgb2gray(I2),0.9999);
% The label most repeated will be the signal.
% So we find it and separate the background from the signal using label.
% Label each "blob"
lbl=bwlabel(~bw);
% Find the blob with the highes amount of data. That will be your signal.
r=histc(lbl(:),1:max(lbl(:)));
[~,idxmax]=max(r);
% Profit!
signal=rgbImage;
signal(repmat((lbl~=idxmax),[1 1 3]))=255;
background=rgbImage;
background(repmat((lbl==idxmax),[1 1 3]))=255;
%% Error Testing
comp_image = rgb2gray(abs(double(rgbImage) - double(signal)));
if ( sum(sum(comp_image(32:438, 96:517))) > 0 )
break;
end
%% Video
% 5001 units so 13.90 (= 4.45 + 9.45) seconds.
% In RGB, original size 480x592.
% Resize to 480x491
signal = signal(:, 42:532, :);
% Show 7 seconds (298 units) at a time.
% imshow(signal(:, 1:298, :));
%% Video VideoWriter
% movie2avi deprecated in Matlab
% https://stackoverflow.com/a/11054155/54964
% https://stackoverflow.com/a/29952648/54964
%# figure
hFig = figure('Menubar','none', 'Color','white');
Z = peaks;
h = imshow(Z, [], 'InitialMagnification',1000, 'Border','tight');
colormap parula; axis tight manual off;
set(gca, 'nextplot','replacechildren', 'Visible','off');
% set(gcf,'Renderer','zbuffer'); % on some Windows
%# preallocate
N = 40; % 491;
vidObj = VideoWriter('myPeaks3.avi');
vidObj.Quality = 100;
vidObj.FrameRate = 10;
open(vidObj);
%# create movie
for k=1:N
set(h, 'CData', signal(:,k:k+40,:))
% drawnow
writeVideo(vidObj, getframe(gca));
end
%# save as AVI file
close(vidObj);
How can you substitute the drawing function by imshow or corresponding?
How can you store the animation correctly?
Here is some code to try:
%// plot
hFig = figure('Menubar','none', 'Color','white');
Z = peaks;
%h = surf(Z);
h = imshow(Z, [], 'InitialMagnification',1000, 'Border','tight');
colormap jet
axis tight manual off
%// preallocate movie structure
N = 40;
mov = struct('cdata',cell(1,N), 'colormap',cell(1,N));
%// aninmation
for k=1:N
%set(h, 'ZData',sin(2*pi*k/N)*Z)
set(h, 'CData',sin(2*pi*k/N)*Z)
drawnow
mov(k) = getframe(hFig);
end
close(hFig)
%// save AVI movie, and open video file
movie2avi(mov, 'file.avi', 'Compression','none', 'Fps',10);
winopen('file.avi')
Result (not really the video, just a GIF animation):
Depending on the codecs installed on your machine, you can apply video compression, e.g:
movie2avi(mov, 'file.avi', 'Compression','XVID', 'Quality',100, 'Fps',10);
(assuming you have the Xvid encoder installed).
EDIT:
Here is my implementation of the code you posted:
%%// extract blue ECG signal
%// retrieve picture: http://stackoverflow.com/q/29800089
imgRGB = imread('http://i.stack.imgur.com/cFOSp.png');
%// detect axis lines and labels
imgHSV = rgb2hsv(imgRGB);
BW = (imgHSV(:,:,3) < 1);
BW = imclose(imclose(BW, strel('line',40,0)), strel('line',10,90));
%// clear those masked pixels by setting them to background white color
imgRGB2 = imgRGB;
imgRGB2(repmat(BW,[1 1 3])) = 255;
%%// create sliding-window video
len = 40;
signal = imgRGB2(:,42:532,:);
figure('Menubar','none', 'NumberTitle','off', 'Color','k')
hImg = imshow(signal(:,1:1+len,:), ...
'InitialMagnification',100, 'Border','tight');
vid = VideoWriter('signal.avi');
vid.Quality = 100;
vid.FrameRate = 60;
open(vid);
N = size(signal,2);
for k=1:N-len
set(hImg, 'CData',signal(:,k:k+len,:))
writeVideo(vid, getframe());
end
close(vid);
The result look like this:

How should I update the data of a plot in Matlab? part - 2

This is a continuation from the question already posted here. I used the method that #Andrey suggested. But there seems to be a limitation. the set(handle, 'XData', x) command seems to work as long as x is a vector. what if x is a matrix?
Let me explain with an example.
Say we want to draw 3 rectangles whose vertices are given by the matrices x_vals (5,3 matrix) and y_vals (5,3 matrix). The command that will be used to plot is simply plot(x,y).
Now, we want to update the above plot. This time we want to draw 4 rectangles. whose vertices are present in the matrices x_new(5,4 matrix) and y_new (5,4 matrix) that we obtain after some calculations. Now using the command set(handle, 'XData', x, 'YData', y) after updating x and y with new values results in an error that states
Error using set
Value must be a column or row vector
Any way to solve this problem?
function [] = visualizeXYZ_struct_v3(super_struct, start_frame, end_frame)
% create first instance
no_objs = length(super_struct(1).result);
x = zeros(1,3000);
y = zeros(1,3000);
box_x = zeros(5, no_objs);
box_y = zeros(5, no_objs);
fp = 1;
% cascade values across structures in a frame so it can be plot at once;
for i = 1:1:no_objs
XYZ = super_struct(1).result(i).point_xyz;
[r,~] = size(XYZ);
x(fp:fp+r-1) = XYZ(:,1);
y(fp:fp+r-1) = XYZ(:,2);
% z(fp:fp+r-1) = xyz):,3);
fp = fp + r;
c = super_struct(1).result(i).box;
box_x(:,i) = c(:,1);
box_y(:,i) = c(:,2);
end
x(fp:end) = [];
y(fp:end) = [];
fig = figure('position', [50 50 1280 720]);
hScatter = scatter(x,y,1);
hold all
hPlot = plot(box_x,box_y,'r');
axis([-10000, 10000, -10000, 10000])
xlabel('X axis');
ylabel('Y axis');
hold off
grid off
title('Filtered Frame');
tic
for num = start_frame:1:end_frame
no_objs = length(super_struct(num).result);
x = zeros(1,3000);
y = zeros(1,3000);
box_x = zeros(5, no_objs);
box_y = zeros(5, no_objs);
fp = 1;
% cascade values accross structures in a frame so it can be plot at once;
for i = 1:1:no_objs
XYZ = super_struct(num).result(i).point_xyz;
[r,~] = size(XYZ);
x(fp:fp+r-1) = XYZ(:,1);
y(fp:fp+r-1) = XYZ(:,2);
fp = fp + r;
c = super_struct(num).result(i).box;
box_x(:,i) = c(:,1);
box_y(:,i) = c(:,2);
end
x(fp:end) = [];
y(fp:end) = [];
set(hScatter, 'XData', x, 'YData', y);
set(hPlot, 'XData', box_x, 'YData', box_y); % This is where the error occurs
end
toc
end
Each line on the plot has its own XData and YData properties, and each can be set to a vector individually. See the reference. I am not at a Matlab console right now, but as I recall...
kidnum = 1
h_axis = gca % current axis - lines are children of the axis
kids = get(h_axis,'Children')
for kid = kids
kid_type = get(kid,'type')
if kid_type == 'line'
set(kid,'XData',x_new(:,kidnum))
set(kid,'YData',y_new(:,kidnum))
kidnum = kidnum+1
end
end
Hope that helps! See also the overall reference to graphics objects and properties.
To add a series, say
hold on % so each "plot" won't touch the lines that are already there
plot(x_new(:,end), y_new(:,end)) % or whatever parameters you want to plot
After that, the new series will be a child of h_axis and can be modified.

How to perform matching by MSER and HOG in Matlab

I wanted to know if there is any full implementation of image-matching by MSER and HOG in Matlab. Currently I am using VLFeat but found difficulties when performing the image matching. Any help?
Btw, I've tried the below code in VLFeat -Matlab environment but unfortunately the matching can't be performed.
%Matlab code
%
pfx = fullfile(vl_root,'figures','demo') ;
randn('state',0) ;
rand('state',0) ;
figure(1) ; clf ;
Ia = imread(fullfile(vl_root,'data','roofs1.jpg')) ;
Ib = imread(fullfile(vl_root,'data','roofs2.jpg')) ;
Ia = uint8(rgb2gray(Ia)) ;
Ib = uint8(rgb2gray(Ib)) ;
[ra,fa] = vl_mser(I,'MinDiversity',0.7,'MaxVariation',0.2,'Delta',10) ;
[rb,fb] = vl_mser(I,'MinDiversity',0.7,'MaxVariation',0.2,'Delta',10) ;
[matches, scores] = vl_ubcmatch(fa, fb);
figure(1) ; clf ;
imagesc(cat(2, Ia, Ib));
axis image off ;
vl_demo_print('mser_match_1', 1);
figure(2) ; clf ;
imagesc(cat(2, Ia, Ib));
xa = ra(1, matches(1,:));
xb = rb(1, matches(2,:)) + size(Ia,2);
ya = ra(2, matches(1,:));
yb = rb(2,matches(2,:));
hold on ;
h = line([xa ; xb], [ya ; yb]);
set(h, 'linewidth', 1, 'color', 'b');
vl_plotframe(ra(:,matches(1,:)));
rb(1,:) = fb(1,:) + size(Ia,2);
vl_plotframe(rb(:,mathces(2,:)));
axis image off ;
vl_demo_print('mser_match_2', 1);
%%%%%%
There are a couple problems. First, the code has several errors and doesn't run as-is. I've pasted my working version below.
More importantly, you're trying to use the SIFT feature-matching function to match the MSER ellipsoids. This won't work at all, since SIFT gives a very high dimensional feature vector based on local image gradients, and the MSER detector is just giving you a bounding ellipsoid.
VLFeat doesn't appear to include an MSER-matching function, so you'll probably have to write your own. Take a look at the original MSER paper to understand how they did matching:
"Robust wide-baseline stereo from maximally stable extremal regions", Matas et al. 2002
% Read the input images
Ia = imread(fullfile(vl_root,'data','roofs1.jpg')) ;
Ib = imread(fullfile(vl_root,'data','roofs2.jpg')) ;
% Convert to grayscale
Ia = uint8(rgb2gray(Ia)) ;
Ib = uint8(rgb2gray(Ib)) ;
% Find MSERs
[ra,fa] = vl_mser(Ia, 'MinDiversity',0.7,'MaxVariation',0.2,'Delta',10) ;
[rb,fb] = vl_mser(Ib, 'MinDiversity',0.7,'MaxVariation',0.2,'Delta',10) ;
% Match MSERs
[matches, scores] = vl_ubcmatch(fa, fb);
% Display the original input images
figure(1); clf;
imagesc(cat(2, Ia, Ib));
axis image off;
colormap gray;
% Display a second copy with the matches overlaid
figure(2) ; clf ;
imagesc(cat(2, Ia, Ib));
axis image off;
colormap gray;
xa = fa(1, matches(1,:));
ya = fa(2, matches(1,:));
xb = fb(1, matches(2,:)) + size(Ia,2);
yb = fb(2, matches(2,:));
hold on ;
h = line([xa ; xb], [ya ; yb]);
set(h, 'linewidth', 1, 'color', 'y');
I don't know how, but MSER matching works in Matlab itself.
The code below
file1 = 'roofs1.jpg';
file2 = 'roofs2.jpg';
I1 = imread(file1);
I2 = imread(file2);
I1 = rgb2gray(I1);
I2 = rgb2gray(I2);
% %Find the SURF features.
% points1 = detectSURFFeatures(I1);
% points2 = detectSURFFeatures(I2);
points1 = detectMSERFeatures(I1);
points2 = detectMSERFeatures(I2);
%Extract the features.
[f1, vpts1] = extractFeatures(I1, points1);
[f2, vpts2] = extractFeatures(I2, points2);
%Retrieve the locations of matched points. The SURF featurevectors are already normalized.
indexPairs = matchFeatures(f1, f2, 'Prenormalized', true) ;
matched_pts1 = vpts1(indexPairs(:, 1));
matched_pts2 = vpts2(indexPairs(:, 2));
figure; showMatchedFeatures(I1,I2,matched_pts1,matched_pts2,'montage');
legend('matched points 1','matched points 2');
gives the following picture

Image Processing using Gabor Filter

I am trying to execute gabor filter on images.
%% Read
clear all;
close all;
clc;
I=imread('test.png');
imshow(I);
%% Crop
I2 = imcrop(I);
figure, imshow(I2)
m=size(I2,1);
n=size(I2,2);
%% Gabor
phi = 7*pi/8;
theta = 2;
sigma = 0.65*theta;
for i=1:3
for j=1:3
xprime= j*cos(phi);
yprime= i*sin(phi);
K = exp(2*pi*theta*i(xprime+ yprime));
G= exp(-(i.^2+j.^2)/(sigma^2)).*abs(K);
end
end
%% Convolve
for i=1:m
for j=1:n
J(i,j)=conv2(I2,G);
end
end
imshow(uint8(J))
I am getting this error always.
??? Subscript indices must either be real positive integers or logicals.
Not sure how to solve this...
You are missing a * in K = exp(2*pi*theta*i(xprime+ yprime)); between i and the parentheses. You like should be K = exp(2*pi*theta*i*(xprime+ yprime));. It is because of such cases Mathworks recommends using sqrt(-1) for the imaginary number.
Update:
You don't need a loop to do convolution in Matlab. You simply say J=conv2(I2,G);
Update 2:
Here's the working code
%% Gabor
phi = 7*pi/8;
theta = 2;
sigma = 0.65*theta;
filterSize = 6;
G = zeros(filterSize);
for i=(0:filterSize-1)/filterSize
for j=(0:filterSize-/filterSize
xprime= j*cos(phi);
yprime= i*sin(phi);
K = exp(2*pi*theta*sqrt(-1)*(xprime+ yprime));
G(round((i+1)*filterSize),round((j+1)*filterSize)) = exp(-(i^2+j^2)/(sigma^2))*K;
end
end
%% Convolve
J = conv2(I2,G);
imshow(imag(J));
According to the answers above, the final code being :
clear all;
close all;
clc;
I=imread('test.png');
imshow(I);
%% Crop
I2 = imcrop(I);
figure, imshow(I2)
phi = 7*pi/8;
theta = 2;
sigma = 0.65*theta;
filterSize = 6;
G = zeros(filterSize);
for i=(0:filterSize-1)/filterSize
for j=(0:filterSize-1)/filterSize
xprime= j*cos(phi);
yprime= i*sin(phi);
K = exp(2*pi*theta*sqrt(-1)*(xprime+ yprime));
G(round((i+1)*filterSize),round((j+1)*filterSize)) = exp(-(i^2+j^2)/(sigma^2))*K;
end
end
J = conv2(I,G);
figure(2);
imagesc(imag(J))