matching row samples to class labels - matlab

I have a small problem with the below code the last line to be specific, I am attempting to find the class names of my "sample" by that I mean I need to know which normal and which smurf belongs to each line of my 1000x6 sample.
%% sampling
normIdx = strmatch('normal.', Book2);
normalSubset = fulldata(normIdx, :);
normal = randperm(size(normalSubset , 1));
p = (normal(1:750)-1)';
%
smurfIdx = strmatch('smurf.', Book2);
smurfSubset = fulldata(smurfIdx, :);
smurf = randperm(size(smurfSubset , 1));
a = (smurf(1:250)-1)';
%
normalSample = normalSubset (p, :);
smurfSample = smurfSubset (a, :);
%
sample = [normalSample ; smurfSample]
%
sample = sample(randperm(1000),:);
%
idx = [a ; p];
K1 = Book2(idx (sample==1), :)
K1 should equal 1000 sample class labels of which 750 should be normal and 250 should be smurf and they should correspnd exactly to the same line in the sample. Book2 contains the class labels I also have fulldata from which the sample was derived.
Atm K1 results in:
Index exceeds matrix dimensions
There could just be an easy way of matching the data of the sample to the data in fulldata but im not sure if there could be repeating data in fulldata... so matching is out and because sample is random so I am thrown off as to what I can do to match the class labels to the sampling.

Is this what you mean? :
%
shuffle = randperm(1000);
sample = sample(shuffle,:);
%
idx = [a ; p];
K1 = Book2(idx (shuffle), :);

Related

Histogram of an image

I need to take histogram of each splited image and i want to calculate mean and variance of the splited image. here i am getting an error while i calculating the mean value..... please guide me
[h w c] = size(x);
numSplits = 3; %
sw = floor(w/numSplits); %
widths = repmat(sw, 1, numSplits-1);
widths(numSplits) = w - sum(widths);
splits = mat2cell(x, h, widths, c);
% show the splits
for ii=1:numSplits
subplot(1,numSplits,ii);
imshow(splits{ii});
g(ii)=(splits{ii});
figure, imhist(g(ii));
end
%mean
im1=g(ii);
su=mean2(im1);
mean=ceil(su);
disp('mean Value');
disp(mean)
%variance
sv=double(im1);
v = var(sv);
disp(v)
i need to get the histograms of each seperate images and i need to calculate the mean for that splitted images
I assume that x is the image you want to split and analyze and that it is the image you have linked:
First, I load the image (you have already done this, I guess, so you do not need to copy this):
x = imread('https://i.stack.imgur.com/4PAaI.png');
The following code solves your coding errors:
[h, w, c] = size(x);
numSplits = 3; %
sw = floor(w/numSplits); %
widths = repmat(sw, 1, numSplits-1);
widths(numSplits) = w - sum(widths);
splits = mat2cell(x, h, widths, c);
results = repmat(struct('mean',[], 'variance',[]),numSplits, 1);
% show and analyze the splits
for ii=1:numSplits
subplot(2,numSplits,ii);
imshow(splits{ii});
subplot(2,numSplits, ii+numSplits);
imhist(splits{ii});
results(ii).mean = mean2(splits{ii});
results(ii).variance = (std2(splits{ii})).^2;
end
The mean and variance are stored in results:
>> results(1)
ans =
struct with fields:
mean: 118.0233
variance: 1.3693e+03
>> results(2)
ans =
struct with fields:
mean: 126.1719
variance: 1.9608e+03
>> results(3)
ans =
struct with fields:
mean: 121.9004
variance: 958.3740
However, please double check that you really want to compute the stats for the combined color channels of the images and not only for, for eample, the red one.

Issues with imgIdx in DescriptorMatcher mexopencv

My idea is simple here. I am using mexopencv and trying to see whether there is any object present in my current that matches with any image stored in my database.I am using OpenCV DescriptorMatcher function to train my images.
Here is a snippet, I am wishing to build on top of this, which is one to one one image matching using mexopencv, and can also be extended for image stream.
function hello
detector = cv.FeatureDetector('ORB');
extractor = cv.DescriptorExtractor('ORB');
matcher = cv.DescriptorMatcher('BruteForce-Hamming');
train = [];
for i=1:3
train(i).img = [];
train(i).points = [];
train(i).features = [];
end;
train(1).img = imread('D:\test\1.jpg');
train(2).img = imread('D:\test\2.png');
train(3).img = imread('D:\test\3.jpg');
for i=1:3
frameImage = train(i).img;
framePoints = detector.detect(frameImage);
frameFeatures = extractor.compute(frameImage , framePoints);
train(i).points = framePoints;
train(i).features = frameFeatures;
end;
for i = 1:3
boxfeatures = train(i).features;
matcher.add(boxfeatures);
end;
matcher.train();
camera = cv.VideoCapture;
pause(3);%Sometimes necessary
window = figure('KeyPressFcn',#(obj,evt)setappdata(obj,'flag',true));
setappdata(window,'flag',false);
while(true)
sceneImage = camera.read;
sceneImage = rgb2gray(sceneImage);
scenePoints = detector.detect(sceneImage);
sceneFeatures = extractor.compute(sceneImage,scenePoints);
m = matcher.match(sceneFeatures);
%{
%Comments in
img_no = m.imgIdx;
img_no = img_no(1);
%I am planning to do this based on the fact that
%on a perfect match imgIdx a 1xN will be filled
%with the index of the training
%example 1,2 or 3
objPoints = train(img_no+1).points;
boxImage = train(img_no+1).img;
ptsScene = cat(1,scenePoints([m.queryIdx]+1).pt);
ptsScene = num2cell(ptsScene,2);
ptsObj = cat(1,objPoints([m.trainIdx]+1).pt);
ptsObj = num2cell(ptsObj,2);
%This is where the problem starts here, assuming the
%above is correct , Matlab yells this at me
%index exceeds matrix dimensions.
end [H,inliers] = cv.findHomography(ptsScene,ptsObj,'Method','Ransac');
m = m(inliers);
imgMatches = cv.drawMatches(sceneImage,scenePoints,boxImage,boxPoints,m,...
'NotDrawSinglePoints',true);
imshow(imgMatches);
%Comment out
%}
flag = getappdata(window,'flag');
if isempty(flag) || flag, break; end
pause(0.0001);
end
Now the issue here is that imgIdx is a 1xN matrix , and it contains the index of different training indices, which is obvious. And only on a perfect match is the matrix imgIdx is completely filled with the matched image index. So, how do I use this matrix to pick the right image index. Also
in these two lines, I get the error of index exceeding matrix dimension.
ptsObj = cat(1,objPoints([m.trainIdx]+1).pt);
ptsObj = num2cell(ptsObj,2);
This is obvious since while debugging I saw clearly that the size of m.trainIdx is greater than objPoints, i.e I am accessing points which I should not, hence index exceeds
There is scant documentation on use of imgIdx , so anybody who has knowledge on this subject, I need help.
These are the images I used.
Image1
Image2
Image3
1st update after #Amro's response:
With the ratio of min distance to distance at 3.6 , I get the following response.
With the ratio of min distance to distance at 1.6 , I get the following response.
I think it is easier to explain with code, so here it goes :)
%% init
detector = cv.FeatureDetector('ORB');
extractor = cv.DescriptorExtractor('ORB');
matcher = cv.DescriptorMatcher('BruteForce-Hamming');
urls = {
'http://i.imgur.com/8Pz4M9q.jpg?1'
'http://i.imgur.com/1aZj0MI.png?1'
'http://i.imgur.com/pYepuzd.jpg?1'
};
N = numel(urls);
train = struct('img',cell(N,1), 'pts',cell(N,1), 'feat',cell(N,1));
%% training
for i=1:N
% read image
train(i).img = imread(urls{i});
if ~ismatrix(train(i).img)
train(i).img = rgb2gray(train(i).img);
end
% extract keypoints and compute features
train(i).pts = detector.detect(train(i).img);
train(i).feat = extractor.compute(train(i).img, train(i).pts);
% add to training set to match against
matcher.add(train(i).feat);
end
% build index
matcher.train();
%% testing
% lets create a distorted query image from one of the training images
% (rotation+shear transformations)
t = -pi/3; % -60 degrees angle
tform = [cos(t) -sin(t) 0; 0.5*sin(t) cos(t) 0; 0 0 1];
img = imwarp(train(3).img, affine2d(tform)); % try all three images here!
% detect fetures in query image
pts = detector.detect(img);
feat = extractor.compute(img, pts);
% match against training images
m = matcher.match(feat);
% keep only good matches
%hist([m.distance])
m = m([m.distance] < 3.6*min([m.distance]));
% sort by distances, and keep at most the first/best 200 matches
[~,ord] = sort([m.distance]);
m = m(ord);
m = m(1:min(200,numel(m)));
% naive classification (majority vote)
tabulate([m.imgIdx]) % how many matches each training image received
idx = mode([m.imgIdx]);
% matches with keypoints belonging to chosen training image
mm = m([m.imgIdx] == idx);
% estimate homography (used to locate object in query image)
ptsQuery = num2cell(cat(1, pts([mm.queryIdx]+1).pt), 2);
ptsTrain = num2cell(cat(1, train(idx+1).pts([mm.trainIdx]+1).pt), 2);
[H,inliers] = cv.findHomography(ptsTrain, ptsQuery, 'Method','Ransac');
% show final matches
imgMatches = cv.drawMatches(img, pts, ...
train(idx+1).img, train(idx+1).pts, ...
mm(logical(inliers)), 'NotDrawSinglePoints',true);
% apply the homography to the corner points of the training image
[h,w] = size(train(idx+1).img);
corners = permute([0 0; w 0; w h; 0 h], [3 1 2]);
p = cv.perspectiveTransform(corners, H);
p = permute(p, [2 3 1]);
% show where the training object is located in the query image
opts = {'Color',[0 255 0], 'Thickness',4};
imgMatches = cv.line(imgMatches, p(1,:), p(2,:), opts{:});
imgMatches = cv.line(imgMatches, p(2,:), p(3,:), opts{:});
imgMatches = cv.line(imgMatches, p(3,:), p(4,:), opts{:});
imgMatches = cv.line(imgMatches, p(4,:), p(1,:), opts{:});
imshow(imgMatches)
The result:
Note that since you did not post any testing images (in your code you are taking input from the webcam), I created one by distorting one the training images, and using it as a query image. I am using functions from certain MATLAB toolboxes (imwarp and such), but those are non-essential to the demo and you could replace them with equivalent OpenCV ones...
I must say that this approach is not the most robust one.. Consider using other techniques such as the bag-of-word model, which OpenCV already implements.

Dataset minus 10%

Below is a method of sampling 10% of my data:
%%
% Normal
normIdx = strmatch('normal.', K2);
normalSubset = cluster2(normIdx, :);
normal = randperm(size(normalSubset , 1));
p = (normal(1:3495))';
%% DoS
DoSIdx = strmatch('DoS', K2);
DoSSubset = cluster2(DoSIdx, :);
DoS = randperm(size(DoSSubset , 1));
a = (DoS(1:8))';
%%
ProbeIdx = strmatch('Probe', K2);
ProbeSubset = cluster2(ProbeIdx, :);
Probe = randperm(size(ProbeSubset , 1));
d = (Probe(1:71))';
%%
normalSample = normalSubset (p, :);
%%
DoSSample = DoSSubset (a, :);
%%
ProbeSample = ProbeSubset (d, :);
%%
idx = [normIdx(p);DoSIdx(a);ProbeIdx(d)];
%
sample = [normalSample ; DoSSample ; ProbeSample]
%
shuffle = randperm(3574);
%
TestData = sample(shuffle,:);
%
TestDataLabels = K2(idx (shuffle), :);
I was wondering how I could then remove this 10% from the dataset (cluster2)? Note that when I say 10% I have worked this out, hence (Probe(1:71) which is 10% of the probe class etc
IF i understand it correctly, you have an index vector idx that contains all the rows that you want to preserve.
In this case the solution is quite simple, to remove them you can follow the approach indicated by #H.Munster, but with the correct index:
cluster2(idx, :) = [];

randperm of multiple columns

on a previous question here Sampling the answer given for sample on the last line of code only returns 1000x1 rather than 1000x6?
%%
normIdx = strmatch('normal.', Book2);
normalSubset = fulldata(normIdx, :);
normal = randperm(size(normalSubset , 1));
p = normal(1:750)-1;
%
smurfIdx = strmatch('smurf.', Book2);
smurfSubset = fulldata(smurfIdx, :);
smurf = randperm(size(smurfSubset , 1));
a = smurf(1:250)-1;
%
normalSample = normalSubset (p, :);
smurfSample = smurfSubset (a, :);
%
sample = [normalSample ; smurfSubset]
%
sample = sample(randperm(1000)); % this line
I tried:
sample = randperm( size(sample, 1));
This outputs 28 thousand records on one line, obviously not what I want. I then tried:
rows = 1000;
columns = 6;
%# pick random columns
indY = randperm( size(sample,2) );
indY = indY(1:columns);
%# pick random rows
indX = randperm( size(sample,1) );
indX = indX(1:rows)';
%# filter data
sample = [indX ; indY];
But I couldnt concatenate the last line? This was only an attempt to try fix the 1000x6 problem, if anyone could come up with a better way "a working way".
how about
sample = sample(randperm(1000),:);

change filter(B,A, X) in matlab and Out of memoy Error

this post is related to my previous question : image processing in matlab
as I have uploaded my algorithme there.
the think is that I am trying to change the filtering part of the code.
in matlab filter.m function can accpet filter(B, A, my pixels evolutions in Time) and it return me the filtered values.
but at the moment I have to pass the the whole time series together.
but the problem is that now I want to change the code in a way instead of passing the whole timeseries into the filter, I want to pass one value at a time, but I want filter function treat the value like the nth value not the first valu.
I have created a sudo code, as I am injecting one picture into the code, but I dont know how can change the filtering part., any body has any idea??
clear all
j=1;
for i=0:3000
str = num2str(i);
str1 = strcat(str,'.mat');
load(str1);
D{j}=A(20:200,130:230);
j=j+1;
end
N=5;
w = [0.00000002 0.05;0.05 0.1;0.1 0.15;0.15 0.20;
0.20 0.25;0.25 0.30;0.30 0.35;0.35 0.40;
0.40 0.45;0.45 0.50;0.50 0.55;0.55 0.60;
0.60 0.65;0.65 0.70;0.70 0.75;0.75 0.80;
0.80 0.85;0.85 0.90;0.90 0.95;0.95 0.99999999];
for ind=1:20
wn = w(ind,:);
[b,a] = butter(N,wn);
bCoeff(ind,:)=b;
aCoeff(ind,:)=a;
end
ts=[];
sumLastImages=[];
for k=1:10 %number of images
for bands=1:20 %number of bands
for i=1:10 %image h
for j=1:10 %image w
pixelValue = D{k}(i,j);
% reflectivity elimination
% for the current pixel, have the summation of the same position from before
% images and create a mean value base on the temporal values
sumLastImages(i,j)=pixelValue+sumLastImages(i,j);
meanValue = sumLastImages(i,j)/k;
if(meanValue==0)
filteredimages{bands}(i,j)=0;
continue;
else
pixel_calculated_meanvalue = pixelValue/meanValue;
end
% filter part that need to be changed, and because we are adding
% one value then the reutrn of the filter is one too
ts_f = filter(bCoeff(bands,:), aCoeff(bands,:), ...
pixel_calculated_meanvalue);
filteredimages{bands}(i,j)=ts_f;
end
end
finalImagesSummation{bands}(:,:) = ...
(filteredimages{bands}(:,:)^2)+finalImagesSummation{bands}(:,:);
finalImages{bands}(:,:)=finalImagesSummation/k;
end
end
EDIT
I managed to change the code like this, which now I load the fist 200 images, and after that I am able to inject the images one by one into the filter, but now the problem is that I am getting "Out of memory. Type HELP MEMORY for your options." error for big
images.
here is my code any idea to efficent the code :
%%
cd('D:\MatlabTest\06-06-Lentils');
clear all
%%
N=5;
W = [0.0 0.10;0.10 0.20;0.20 0.30;0.30 0.40;
0.40 0.50;0.50 0.60 ;0.60 0.70;0.70 0.80 ;
0.80 0.90;0.90 1.0];
[bCoeff{1},aCoeff{1}] = butter(N,0.1,'Low');
for ind=2:9
wn = W(ind,:);
[b,a] = butter(N,wn);
bCoeff{ind}=b;
aCoeff{ind}=a;
end
[bCoeff{10},aCoeff{10}] = butter(N,0.9,'high');
%%
j=1;
D = zeros(200,380,320);
T = 200;
K = 0:399;
l = T+1;
Yout = cell(1,10);
figure;
for i = 1:length(K)-200
disp(i)
if i == 1
for j = 1:T
str = int2str(K(1)+j-1);
str1 = strcat(str,'.mat');
load(str1);
D(j,1:380,1:320) = A;
end
else
str = int2str(l);
str1 = strcat(str,'.mat');
load(str1);
temp = D(2:200,1:380,1:320) ;
temp(200,1:380,1:320) = A;
D = temp;
clear temp
l = l +1;
end
for p = 1:380
for q = 1:320
x = D(:,p,q) - mean(D(:,p,q));
for k = 1:10
temp = filter(bCoeff{k},aCoeff{k},x);
if i == 1
Yout{k}(p,q) = mean(temp);
else
Yout{k}(p,q) = (Yout{k}(p,q) + mean(temp))/2;
end
end
end
end
for k = 1:10
subplot(5,2,k)
subimage(Yout{k}*1000,[0 255]);
color bar
colormap jet
end
pause(0.01);
end
disp('Done Loading...')
No need to rewrite the filter function, there is a simple solution!
If you want to feed filter with one sample at a time, you need to pass the state parameters as well so that each input sample is processed depending on its predecessor. After filtering, the new state is actually returned as a second parameter, so that most of the work is already done by MATLAB for you. This is good news!
For the sake of readability, allow me to temporarily replace your variable names with simple letters:
a = aCoeff(bands, :);
b = bCoeff(bands, :);
x = pixel_calculated_meanvalue;
ts_f is represented by y.
And so, this:
y = filter(b, a, x);
is actually equivalent to this:
N = numel(x);
y = zeros(N, 1); %# Preallocate memory for output
z = zeros(max(length(a), length(b)) - 1, 1); %# This is the initial filter state
for i = 1:N
[y(i), z] = filter(b, a, x(i), z);
end
You can check for yourself that the result is the same!
For your example, the code would be:
N = numel(pixel_calculated_meanvalue);
ts_f = zeros(N, 1);
z = zeros(max(length(aCoeff(bands, :)), length(bCoeff(bands, :))) - 1, 1);
for i = 1:N
[ts_f(i), z] = filter(bCoeff(bands, :), aCoeff(bands, :), ...
pixel_calculated_meanvalue(i), z);
end
With this method you can process one input sample at a time, just make sure you store the last filter state after every filter call. If you plan on using multiple filters, you'll have to store a state vector per filter!
Overview
If all you want to have is an IIR filter, which you can feed incrementally, i.e. where you do not have to supply the full vector at once, you can simply implement your own function and use either persistent variables.
Simple approach
The code snippet below defines a function myFilter, which makes use of persistent
variables, which you can control with the following commands:
init: set up the IIR coefficients
getA: returns the A coefficients, i.e. the outputweights
getB: returns the B coefficients, i.e. the input weights
getX: returns the stored input data x[0], x[1], ... x[M]
getY: returns the output data y[0], y[1], ... y[N]
getCurrentY: returns the last output data y[N]
Here is the function:
function result = myFilter(varargin)
% myFilter A simple IIR filter which can be fed incrementally.
%
% The filter is controlled with the following commands:
% myFilter('init', B, A)
% Initializes the coefficients B and A. B are the weights for the
% input and A for the output.
% myFilter('reset')
% Resets the input and output buffers to zero.
% A = myFilter('getA')
% B = myFilter('getB')
% Returns the filter coefficients A and B, respectively.
% x = myFilter('getX')
% y = myFilter('getY')
% Returns the buffered input and output vectors.
% y = myFilter('getCurrentY')
% Returns the current output value.
% myFilter(x)
% Adds the new value x as input to the filter and updates the
% output.
persistent Bcoeff
persistent Acoeff
persistent x
persistent y
if ischar(varargin{1})
% This is a command.
switch varargin{1}
case 'init'
Bcoeff = varargin{2};
Acoeff = varargin{3};
Bcoeff = Bcoeff / Acoeff(1);
Acoeff = Acoeff / Acoeff(1);
x = zeros(size(Bcoeff));
y = zeros(1, length(Acoeff) - 1);
return
case 'reset'
x = zeros(size(Bcoeff));
y = zeros(1, length(Acoeff) - 1);
return
case 'getA'
result = Acoeff;
return
case 'getB'
result = Bcoeff;
return
case 'getX'
result = x;
return
case 'getY'
result = y;
return
case 'getCurrentY'
result = y(1);
return
otherwise
error('Unknown command');
end
end
% A new value has to be filtered.
xnew = varargin{1};
x = [xnew, x(1:end-1)];
ynew = sum(x .* Bcoeff) - sum(y .* Acoeff(2:end));
y = [ynew, y(1:end-1)];
end
And a usage example:
% Define the filter coefficients. Bcoeff acts on the input, Acoeff on
% the output.
Bcoeff = [4, 5];
Acoeff = [1, 2, 3];
% Initialize the filter.
myFilter('init', Bcoeff, Acoeff);
% Add a value to be filtered.
myFilter(10)
myFilter('getCurrentY')
ans =
40
% Add another one.
myFilter(20)
myFilter('getCurrentY')
ans =
50
% And a third one.
myFilter(30)
myFilter('getCurrentY')
ans =
0
% Compare with the Matlab filter function.
filter(Bcoeff, Acoeff, [10 20 30])
ans =
40 50 0
The drawback of this approach is that it is only possible to have one active filter
simultaneously. This is problematic e.g. in your question, where you have different
filters which are updated in an alternating fashion.
Advanced approach
In order to operate multiple filters simultatenously, you need some way to identify
the filter. The solution I present here works with handles. A handle is simple an
integer. To be more precise, it is actually an index into a persistent array, which
itself holds the filter state, i.e. the filter coefficients and the buffers for the
input and the output.
The calling syntax is a bit more complicated, because you have to pass a handle. However,
it is possible that multiple filters are active simultaneously.
function result = myFilterH(varargin)
% myFilterH A simple IIR filter which can be fed incrementally.
% Operates on a filter handle.
%
% The filter is controlled with the following commands:
% handle = myFilterH('create')
% Creates a new filter handle.
% myFilterH(handle, 'init', B, A)
% Initializes the coefficients B and A. B are the weights for the
% input and A for the output. handle identifies the filter.
% myFilterH(handle, 'reset')
% Resets the input and output buffers to zero.
% A = myFilterH(handle, 'getA')
% B = myFilterH(handle 'getB')
% Returns the filter coefficients A and B, respectively.
% x = myFilterH(handle, 'getX')
% y = myFilterH(handle, 'getY')
% Returns the buffered input and output vectors.
% y = myFilterH(handle, 'getCurrentY')
% Returns the current output value.
% myFilterH(handle, x)
% Adds the new value x as input to the filter and updates the
% output.
persistent handles
if ischar(varargin{1})
if strcmp(varargin{1}, 'create')
if isempty(handles)
handles = struct('x', [], 'y', [], 'A', [], 'B', []);
result = 1;
else
result = length(handles) + 1;
handles(result).x = [];
end
return
else
error('First argument must be a filter handle or ''create''');
end
end
% The first input should be the handles(hIdx).
hIdx = varargin{1};
if hIdx < 0 || hIdx > length(handles)
error('Invalid filter handle')
end
if ischar(varargin{2})
% This is a command.
switch varargin{2}
case 'init'
handles(hIdx).B = varargin{3};
handles(hIdx).A = varargin{4};
handles(hIdx).B = handles(hIdx).B / handles(hIdx).A(1);
handles(hIdx).A = handles(hIdx).A / handles(hIdx).A(1);
handles(hIdx).x = zeros(size(handles(hIdx).B));
handles(hIdx).y = zeros(1, length(handles(hIdx).A) - 1);
return
case 'reset'
handles(hIdx).x = zeros(size(handles(hIdx).B));
handles(hIdx).y = zeros(1, length(handles(hIdx).A) - 1);
return
case 'getA'
result = handles(hIdx).A;
return
case 'getB'
result = handles(hIdx).B;
return
case 'getX'
result = handles(hIdx).x;
return
case 'getY'
result = handles(hIdx).y;
return
case 'getCurrentY'
result = handles(hIdx).y(1);
return
otherwise
error('Unknown command');
end
end
% A new value has to be filtered.
xnew = varargin{2};
handles(hIdx).x = [xnew, handles(hIdx).x(1:end-1)];
ynew = sum(handles(hIdx).x .* handles(hIdx).B) ...
- sum(handles(hIdx).y .* handles(hIdx).A(2:end));
handles(hIdx).y = [ynew, handles(hIdx).y(1:end-1)];
end
And the example:
% Define the filter coefficients.
Bcoeff = [4, 5];
Acoeff = [1, 2, 3];
% Create new filter handles.
fh1 = myFilterH('create');
fh2 = myFilterH('create');
% Initialize the filter handle. Note that reversing Acoeff and Bcoeff creates
% two totally different filters.
myFilterH(fh1, 'init', Bcoeff, Acoeff);
myFilterH(fh2, 'init', Acoeff, Bcoeff);
% Add a value to be filtered.
myFilterH(fh1, 10);
myFilterH(fh2, 10);
[myFilterH(fh1, 'getCurrentY'), myFilterH(fh2, 'getCurrentY')]
ans =
40.0000 2.5000
% Add another one.
myFilterH(fh1, 20);
myFilterH(fh2, 20);
[myFilterH(fh1, 'getCurrentY'), myFilterH(fh2, 'getCurrentY')]
ans =
50.0000 6.8750
% And a third one.
myFilterH(fh1, 30);
myFilterH(fh2, 30);
[myFilterH(fh1, 'getCurrentY'), myFilterH(fh2, 'getCurrentY')]
ans =
0 16.4063
% Compare with the Matlab filter function.
filter(Bcoeff, Acoeff, [10 20 30])
ans =
40 50 0
filter(Acoeff, Bcoeff, [10 20 30])
ans =
2.5000 6.8750 16.4063
Using it for your example
To use the advanced approach in your example, you could first create an array of filters:
fh = [];
for ind = 1:20
wn = w(ind,:);
[b,a] = butter(N,wn);
fh(ind) = myFilterH('create');
myFilterH(fh(ind), 'init', b, a);
end
Later on in the filter part simply add your value to all of the filters. However, for this
you also need to reverse the loops because right now you would need one filter per
band per pixel. If you loop over pixels first and then over bands, you can reuse the filters:
for height = 1:10
for width = 1:10
for bands = 1:20
myFilterH(fh(bands), 'reset');
for k = 1:10
[...]
ts_f = myFilterH(fh(bands), ...
pixel_calculated_meanvalue);
filteredimages{bands}(i,j) = myFilterH(fh(bands), 'getCurrentY');
end
end
end
end
Hope that helps!
If I understand the question correctly, the crux is "How do I return multiple things from a Matlab function?"
You can return multiple things like this:
function [a, b, np, x, y] = filter(ord, a, b, np, x, y)
%code of function here
%make some changes to a, b, np, x, and y
end
If you want to call the filter from another function and catch its return values, you can do this:
function [] = main()
%do some stuff, presumably generate initial values for ord, a, b, np, x, y
[new_a, new_b, new_np, new_x, new_y] = filter(ord, a, b, np, x, y)
end
In short, if you do function [x, y] = myfunc(a, b), then myfunc returns both x and y.