Find Specified Color In Each Frame Of Real-time Video - matlab

I am newbie in Matlab.
My Boss gave me a task and i stuck in last step.
the task is:
user should specify a rectangle in snapshot of real-time video and then i should detect the mean color of that rectangle in each frame of video.
first user specify the boundaries of rectangle in a snapshot of video with this code:
test = getsnapshot(vid);
imwrite(test,'mytest.png','png');
testsnap = imread('mytest.png');
Rectpos=getrect;
then I calculate mean degree of each R , G , B :
bbx=boundingboxPixels(testsnap,Rectpos(1),Rectpos(2),Rectpos(3),Rectpos(4));
rRect=mean(bbx(:,:,1));
gRect=mean(bbx(:,:,2));
bRect=mean(bbx(:,:,3));
where boundingboxPixels method is like this :
function pixel_vals = boundingboxPixels(img, x_init, y_init, x_width, y_width)
if x_init > size(img,2)
error('x_init lies outside the bounds of the image.'); end
if y_init > size(img,1)
error('y_init lies outside the bounds of the image.'); end
if y_init+y_width > size(img,1) || x_init+x_width > size(img,2) || ...
x_init < 1 || y_init < 1
warning([...
'Given rectangle partially falls outside image. ',...
'Resizing rectangle...']);
end
x_min = max(1, uint16(x_init));
y_min = max(1, uint16(y_init));
x_max = min(size(img,2), x_min+uint16(x_width));
y_max = min(size(img,1), y_min+uint16(y_width));
x_range = x_min : x_max;
y_range = y_min : y_max;
Upper = img( x_range, y_min , :);
Left = img( x_min, y_range, :);
Right = img( x_max, y_range, :);
Lower = img( x_range, y_max , :);
pixel_vals = [...
Upper
permute(Left, [2 1 3])
permute(Right, [2 1 3])
Lower];
end
then get the calculated Mean of RGB color with a threshold from each frame of video:
tv=getdata(vid,1);//vid is real-time video
r=tv(:,:,1,1);
g=tv(:,:,2,1);
b=tv(:,:,3,1);
redVal = (r >= rRect-thr) & (r <= rRect+thr);
greenVal = (g >= gRect-thr) & (g <= gRect+thr);
blueVal = (b >= bRect-thr) & (b <= bRect+thr);
Now How Should I use the redVal , greenVal , blueVal to detect this color?

as Steffen said , problem solved by adding & between arrays

Related

Capsule shape detection in image

I have a binary image and I'd like to detect all approximately capsule-shaped regions like this (marked in red).
The size and orientation of desired regions is different for each image and unknown.
The desired ratio of height and width is between 3 and 5.
I don't know how to detect shape with unknown orientation and size, so I tried to use the ratio of the region's area and its bounding box's diagonal squared as criterion, but the result is not very good. Here's the code I use.
regions = bwconncomp(img);
sizes = cellfun(#numel, regions.PixelIdxList);
N = regions.NumObjects;
is_capsule = false(N, 1);
for k = 1:N
idx = regions.PixelIdxList{k};
[row, col] = ind2sub(sz, idx);
h = max(row) - min(row) + 1;
w = max(col) - min(col) + 1;
l = numel(idx) / (h^2 + w^2);
if l >= 0.1 && l <= 0.2
is_capsule(k) = 1;
end
end

Find the boundaries of a local maxima

I have a 2D image (matrix). I have found the local maxima of this image. Now I want to define the boundaries around each local maxima in such a way that I want all the pixels around the local maxima that have a value above 85% of the maximum.
Here is my existing code:
function [location]= Mfind_peak_2D( Image,varargin )
p = inputParser;
addParamValue(p,'max_n_loc_max',5);
addParamValue(p,'nb_size',3);
addParamValue(p,'thre',0);
addParamValue(p,'drop',0.15);
parse(p,varargin{:});
p=p.Results;
if sum(isnan(Image(:)))>0
Image(isnan(Image))=0;
end
hLocalMax = vision.LocalMaximaFinder;
hLocalMax.MaximumNumLocalMaxima = p.max_n_loc_max;
hLocalMax.NeighborhoodSize = [p.nb_size p.nb_size];
end
This should do the job (the code is full of comments and should be pretty self-explanatory but if you have doubts feel free to ask for more details):
% Load the image...
img = imread('peppers.png');
img = rgb2gray(img);
% Find the local maxima...
mask = ones(3);
mask(5) = 0;
img_dil = imdilate(img,mask);
lm = img > img_dil;
% Find the neighboring pixels of the local maxima...
img_size = size(img);
img_h = img_size(1);
img_w = img_size(2);
res = cell(sum(sum(lm)),3);
res_off = 1;
for i = 1:img_h
for j = 1:img_w
if (~lm(i,j))
continue;
end
value = img(i,j);
value_thr = value * 0.85;
% Retrieve the neighboring column and row offsets...
c = bsxfun(#plus,j,[-1 0 1 -1 1 -1 0 1]);
r = bsxfun(#plus,i,[-1 -1 -1 0 0 1 1 1]);
% Filter the invalid positions...
idx = (c > 0) & (c <= img_w) & (r > 0) & (r <= img_h);
% Transform the valid positions into linear indices...
idx = (((idx .* c) - 1) .* img_h) + (idx .* r);
idx = reshape(idx.',1,numel(idx));
idx = idx(idx > 0);
% Retrieve the neighbors and filter them based on te threshold...
neighbors = img(idx);
neighbors = neighbors(neighbors > value_thr);
% Update the final result...
res(res_off,:) = {sub2ind(img_size,i,j) value neighbors};
res_off = res_off + 1;
end
end
res = sortrows(res,1);
The variable res will be a cell matrix with three columns: the first one contain the linear indices to the local maxima of the image, the second one contains the values of the local maxima and the third one a vector with the pixels around the local maxima that fall within the specified threshold.

MATLAB function for image filtering

I'm looking to implement my own Matlab function that can be used to compute image filtering with a 3x3 kernel.
It has to be like this: function [ output_args ] = fFilter( img, mask )
where img is a original image and mask is a kernel (for example B = [1,1,1;1,4,1;1,1,1] )
I'm not supposed to use any in-built functions from Image Processing Toolbox.
I have to use this
where:
s is an image after filter
p is an image before filter
M is a kernel
and N is 1 if sum(sum(M)) == 0 else N = sum(sum(M))
I'm new to MATLAB and this is like black magic for me -_-
This should do the work (Wasn't verified):
function [ mO ] = ImageFilter( mI, mMask )
%UNTITLED2 Summary of this function goes here
% Detailed explanation goes here
numRows = size(mI, 1);
numCols = size(mI, 2);
% Assuming Odd number of Rows / Columns
maskRadius = floor(siez(mMask, 1) / 2);
sumMask = sum(mMask(:));
if(sumMask ~= 0)
mMask(:) = mMask / sumMask;
end
mO = zeros([numRows, numCols]);
for jj = 1:numCols
for ii = 1:numRows
for kk = -maskRadius:maskRadius
nn = kk + 1; %<! Mask Index
colIdx = min(max(1, jj + kk), numCols); %<! Replicate Boundary
for ll = -maskRadius:maskRadius
mm = ll + 1; %<! Mask Index
rowIdx = min(max(1, ii + ll), numRows); %<! Replicate Boundary
mO(ii, jj) = mO(ii, jj) + (mMask(mm, nn) * mI(rowIdx, colIdx));
end
end
end
end
end
The above is classic Correlation (Image Filtering) with Replicate Boundary Condition.

Matlab Seeded Region Growing

I have used the following code from the matlab central website in my project to perform seeded region growing. This works perfectly but I am struggling to understand exactly what the code is doing in some places. I have contacted the author but have had no reply. Would anyone be able to provide me with some explanations ?
function Phi = segCroissRegion(tolerance,Igray,x,y)
if(x == 0 || y == 0)
imshow(Igray,[0 255]);
[x,y] = ginput(1);
end
Phi = false(size(Igray,1),size(Igray,2));
ref = true(size(Igray,1),size(Igray,2));
PhiOld = Phi;
Phi(uint8(x),uint8(y)) = 1;
while(sum(Phi(:)) ~= sum(PhiOld(:)))
PhiOld = Phi;
segm_val = Igray(Phi);
meanSeg = mean(segm_val);
posVoisinsPhi = imdilate(Phi,strel('disk',1,0)) - Phi;
voisins = find(posVoisinsPhi);
valeursVoisins = Igray(voisins);
Phi(voisins(valeursVoisins > meanSeg - tolerance & valeursVoisins < meanSeg + tolerance)) = 1;
end
Thanks
I've added some comments in your code :
function Phi = segCroissRegion(tolerance,Igray,x,y)
% If there's no point, select one from image
if(x == 0 || y == 0)
imshow(Igray,[0 255]);
[x,y] = ginput(1);
end
%Create seed with by adding point in black image
Phi = false(size(Igray,1),size(Igray,2));
ref = true(size(Igray,1),size(Igray,2));
PhiOld = Phi;
Phi(uint8(x),uint8(y)) = 1;
while(sum(Phi(:)) ~= sum(PhiOld(:)))
PhiOld = Phi;
% Evaluate image intensity at seed/line points
segm_val = Igray(Phi);
% Calculate mean intensity at seed/line points
meanSeg = mean(segm_val);
% Grow seed 1 pixel, and remove previous seed (so you'll get only new pixel perimeter)
posVoisinsPhi = imdilate(Phi,strel('disk',1,0)) - Phi;
% Evaluate image intensity over the new perimeter
voisins = find(posVoisinsPhi);
valeursVoisins = Igray(voisins);
% If image intensity over new perimeter is greater than the mean intensity of previous perimeter (minus tolerance), than this perimeter is part of the segmented object
Phi(voisins(valeursVoisins > meanSeg - tolerance & valeursVoisins < meanSeg + tolerance)) = 1;
% Repeat while there's new pixel in seed, stop if no new pixel were added
end

Cylinder with filled top and bottom in matlab

I am trying to create a "solid" cylinder that has a filled top and bottom to it. I know that there is the function cylinder(r) that creates one, though it does not have a top and bottom circle to "close it".
I did some research and can't seem to find a function that does this. I have found this: http://www.mathworks.com/help/symbolic/mupad_ref/plot-cylinder.html though it is mupad code, and I don't know how to call that function from matlab (from my .m file). Once again, I have done some research and this is what I have found, though is does not seem to work: http://www.mathworks.com/help/symbolic/create-matlab-functions-from-mupad-expressions.html . Is this possible, and if so how? If not, how can I make my "solid" cylinder in matlab?
Thanks
Assuming a cylinder aligned with the z-axis, radii R linearly spaced along the unit height above the XY-plane (same assumptions as built-in cylinder):
function [x,y,z] = solidCylinder(varargin)
%// Basic checks
assert(nargin >= 1, 'Not enough input arguments.');
assert(nargin <= 3, 'Too many input arguments.');
assert(nargout <= 3, 'Too many output arguments.');
%// Parse input
N = 20;
Ax = [];
switch nargin
case 1 %// R
R = varargin{1};
case 2 %// Ax, R or R, N
if ishandle(varargin{1})
Ax = varargin{1};
R = varargin{2};
else
R = varargin{1};
N = varargin{2};
end
case 3 %// Ax, R, N
Ax = varargin{1};
R = varargin{2};
N = varargin{3};
end
%// Check input arguments
if ~isempty(Ax)
assert(ishandle(Ax) && strcmp(get(Ax, 'type'), 'axes'),...
'Argument ''Ax'' must be a valid axis handle.');
else
Ax = gca;
end
assert(isnumeric(R) && isvector(R) && all(isfinite(R)) && all(imag(R)==0) && all(R>0),...
'Argument ''R'' must be a vector containing finite, positive, real values.');
assert(isnumeric(N) && isscalar(N) && isfinite(N) && imag(N)==0 && N>0 && round(N)==N,...
'Argument ''N'' must be a finite, postive, real, scalar integer.');
%// Compute cylinder coords (mostly borrowed from builtin 'cylinder')
theta = 2*pi*(0:N)/N;
sintheta = sin(theta);
sintheta(N+1) = 0;
M = length(R);
if M==1
R = [R;R]; M = 2; end
x = R(:) * cos(theta);
y = R(:) * sintheta;
z = (0:M-1).'/(M-1) * ones(1,N+1); %'
if nargout == 0
oldNextPlot = get(Ax, 'NextPlot');
set(Ax, 'NextPlot', 'add');
%// The side of the cylinder
surf(x,y,z, 'parent',Ax);
%// The bottom
patch(x(1,:) , y(1,:) , z(1,:) , z(1,:) );
%// The top
patch(x(end,:), y(end,:), z(end,:), z(end,:));
set(Ax, 'NextPlot', oldNextPlot);
end
end
To check whether points are inside a cylinder of height L (note: assuming a true 'cylinder' as created with [R R], and NOT some compound object (cones with cylinders) as created by [R1 R2 ... RN] with at least two different values):
function p = pointInCylinder(x,y,z)
%// These can also be passed by argument of course
R = 10;
L = 5;
%// Basic checks
assert(isequal(size(x),size(y),size(z)), ...
'Dimensions of the input arguments must be equal.');
%// Points inside the circular shell?
Rs = sqrt(x.^2 + y.^2 + z.^2) <= R;
%// Points inside the top and bottom?
Os = z>=0 & z<=L;
p = Rs & Os;
end
heres how to make lids:
clear all
close all
r = 1;
h = 2;
theta = 0:0.05:2*pi;
x = r*cos(theta);
y = r*sin(theta);
y(end) = 0;
z1 = 0;
z2 = h;
patch(x,y,z1*ones(size(x)),'b');
set(gca,'NextPlot','Add');
patch(x,y,z2*ones(size(x)),'b');
surf([x;x],[y;y],[z1*ones(size(x));z2*ones(size(x))],'parent',gca)