Closing a gap in time series

149 views Asked by At

I want to merge the right block (consisting of two smaller blocks) to look exactly like the two block to the left. I was thinking about morphological operations but these tend to alter the original shape, thus losing accuracy. Are there any other signal processing tools that would help? The data is presented as a time series.

segmentation problem

2

There are 2 answers

2
anandr On BEST ANSWER

First we need a test data set:

> x=1:40; y=x*0; y(5:10)=1; y(15:20)=1; y(25:30)=1;y(33:36)=1;
> disp([x;y])
   1     2     3     4     5     6     7     8     9    10    11    12    13    14    15    16    17    18    19    20    21    22    23    24    25    26    27    28    29    30    31    32    33    34    35    36    37    38    39    40
   0     0     0     0     1     1     1     1     1     1     0     0     0     0     1     1     1     1     1     1     0     0     0     0     1     1     1     1     1     1     0     0     1     1     1     1     0     0     0     0

Now we find first

> BlockStart = find( diff(y)>0 )+1
BlockStart =
  5    15    25    33

and last index of each non-zero block (note that numbers really coincide with the ones I used to make test data)

> BlockEnd = find( diff(y)<0 )
BlockEnd =
 10    20    30    36

Then we just delete the gap between 3rd and 4th block in X (I rearranged the output):

> x( BlockEnd(3)+1 : BlockStart(4)-1) = []; % delete the gap in X
> y( BlockEnd(3)+1 : BlockStart(4)-1) = []; % delete the gap in Y
> disp([x;y])
 1     2     3     4     5     6     7     8     9    10    11    12    13    14    15    16    17    18    19    20    21    22    23    24    25    26    27    28    29    30    33    34    35    36    37    38    39    40
 0     0     0     0     1     1     1     1     1     1     0     0     0     0     1     1     1     1     1     1     0     0     0     0     1     1     1     1     1     1     1     1     1     1     0     0     0     0

Also you may fill the gap in Y with ones instead of removing those elements:

> y( BlockEnd(3)+1 : BlockStart(4)-1) = 1;
> disp([x;y])
   1     2     3     4     5     6     7     8     9    10    11    12    13    14    15    16    17    18    19    20    21    22    23    24    25    26    27    28    29    30    31    32    33    34    35    36    37    38    39    40
   0     0     0     0     1     1     1     1     1     1     0     0     0     0     1     1     1     1     1     1     0     0     0     0     1     1     1     1     1     1     1     1     1     1     1     1     0     0     0     0
1
Dennis Jaheruddin On

There are various ways to deal with gaps. This assumes that a single value may accidentally be zero (or low), and should be fixed to match its neighbors:

vo =ones(1,3);
vz = zeros(1,3);
ts = [vo vz vo vz vz vo 0 vo];
bar(ts) 

c = min(circshift(ts,[0 1]),circshift(ts,[0 -1]));
ts_nogap = max(ts,c);
figure, bar(ts_nogap)

For more advanced requirements consider using filter instead of circshift or loop through all values and explore their 'neighborhood' in any way you like.