在出现一组n个相等值后插入某个值

时间:2015-02-11 16:41:46

标签: matlab image-processing

示例:

input = [1 255 0 0 0 9 9 9 1 6 6 6 6 6 6 1]; % array of numbers (uint8)

output = [1 255 0 0 0 255 9 9 9 255 1 6 6 6 255 6 6 6 255 1];

% output must have 255 inserted at positions 6, 10, 15, 19
% because 0, 9, 6, 6 have occurred three times respectively

outputIndex = [6 10 15 19]; 
% outputIndex must indicate the positions where 255 was inserted

2 个答案:

答案 0 :(得分:2)

这可能是一种 vectorized 方法,可以有效地完成工作 -

%// Input
A = [1 255 0 0 0 9 9 9 1 6 6 6 6 6 6 1]

%// Input paramter (how many times a value must be repeated for detection)
search_count = 3; 

%// Find difference between consecutive elemnts and set all non zero
%// differences as ones, otherwise as zeros in a binary array
diffA = diff(A)~=0

%// Find start and end indices of "islands" of same value 
starts = strfind([1 diffA],[1 zeros(1,search_count-1)])
ends = strfind([diffA 1],[zeros(1,search_count-1) 1])+search_count

%// For each island of same valued elements, find out where first group ends
firstgrp = starts + search_count

%// Find how many times a group of that same value of search_count times repeats 
%// within each "island" of same valued elements. Also get the max repeats.
pattern_repeats = floor((ends - starts)./search_count)
max_repeat = max(pattern_repeats)

%// All possible repeat indices within all islands
all_repeats = bsxfun(@plus,firstgrp,[0:max_repeat-1]'*(search_count)) %//'

%// Use a binary mask to select only those repeats allowed with pattern_repeat 
out_idx = all_repeats(bsxfun(@lt,[0:max_repeat-1]',pattern_repeats))  %//'
out_idx = out_idx + [0:numel(out_idx)-1]'                             %//'

%// Create output arary, insert 255 at out_idx locations and put values
%// from input array into rest of the locations
out  = zeros(1,numel(A)+numel(out_idx));
out(out_idx) = 255
out(out==0) = A

代码运行 -

>> A
A =
  Columns 1 through 13
     1   255     0     0     0     9     9     9     1     6     6     6     6
  Columns 14 through 16
     6     6     1
>> out_idx
out_idx =
     6
    10
    15
    19
>> out
out =
  Columns 1 through 13
     1   255     0     0     0   255     9     9     9   255     1     6     6
  Columns 14 through 20
     6   255     6     6     6   255     1

答案 1 :(得分:1)

我不理解这些挫折,这实际上是一个有趣的问题。

这里的答案很长:

n = 3;
subst = 255;
input = [1 255 0 0 0 9 9 9 1 6 6 6 6 6 6 61]; 

%// mask
X = NaN(1,numel(input));
%// something complicated (see below)
X(filter(ones(1,n-1),1,~([0. diff(input)])) == n-1) = 1;

%// loop to split multiple occurences of n-tuples
for ii = 1:numel(input)
    if X(ii) == 1 && ii < numel(X)-n+1
       X(ii+1:ii+n-1) = NaN(1,n-1);
    end
end

%// output vector
D = [input; X.*subst];
E = D(:);
output = E(isfinite(E))

%// indices of inserted 255
D = [input.*0; X.*subst];
E = D(:);
outputIndex = find(E(isfinite(E)))

复杂部分的说明:

%// finite differences of input
A = [0 diff(input)];
%// conversion to logical
B = ~A;
%// mask consecutive values
mask = filter(ones(1,n-1),1,B) == n-1;
%// set masked values to 1
X(mask) = 1;

如果您有图像处理工具箱,可以使用这个花哨的oneliner保存循环以获取遮罩:

mask = accumarray(bwlabel(filter(ones(1,n-1),1,~([0. diff(input)])) == n-1).'+1,1:numel(input),[],@(x) {getfield(sort(x),{find(mod(cumsum(1:numel(x)),n) == 1)})});
X = NaN(1,numel(input));
X(vertcat(mask{2:end})) = subst;

%// output vector
D = [input; X];
E = D(:);
output = E(isfinite(E))

%// indices of inserted 255
D = [input.*0; X];
E = D(:);
outputIndex = find(E(isfinite(E)))