首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >晶须匹配轨迹

晶须匹配轨迹
EN

Stack Overflow用户
提问于 2015-07-16 12:02:41
回答 1查看 72关注 0票数 2

我在做一个胡须追踪实验。我有一段高速视频(500 rats ),老鼠与物体相撞。在每一个这样的视频中,我跟踪老鼠的鼻子和胡须的形状。由于跟踪是有噪声的,每个帧中的晶须数可能是不同的(见所附图像中连续的2帧,注意左边帧中出现的黄色假阳性晶须,而不是右边的)。

参见示例1:

作为跟踪的最终结果,对于每个帧,我得到了不同数量的可变长度向量;每个向量对应于一个晶须。在这一点上,我想匹配框架之间的胡须。我试过使用Matlab的示例对齐来完成这个任务,但是它的工作方式有些不太好。其结果附在下面(附图显示超过227帧的所有晶须的基点)。

参见示例2:

我想运行一些算法来正确地聚类晶须,这样每个晶须都被识别为它自己,并且在许多帧的过程中与其他的胡子分离。换句话说,我希望在第二个图像中的每一个轻微的正弦轨迹被识别为一个轨迹。无论我使用什么排序算法,都应该考虑到晶须可能在连续帧之间消失并重新出现。不幸的是,我已经没有主意了.

有什么帮助吗?

再次记住,对于附图2中的每一点,我都有很多数据点,因为这只是一个须基点的图,而实际上我有整个晶须长度的数据。

EN

回答 1

Stack Overflow用户

发布于 2015-07-16 22:52:36

我就是这样处理这个问题的。假设不同大小的数据向量是cell类型的,称为dataVectors,并且知道晶须的数量(nSignals),我将尝试将数据扩展到从原始数据导出的第二个维度,然后在两个维度上执行k均值。

因此,首先,我将得到向量的最大大小,以便将数据转换为矩阵并执行NaN-padding。

代码语言:javascript
复制
maxSize = -Inf;
for k = 1:nSignals
    if length(dataVectors{k}.data) > maxSize
        maxSize = length(dataVectors{k}.data);
    end
end

现在,我会通过将数据提升到2或3的功率(你的选择)来制作2D数据。这只是一个非常简单的转变。但是,您也可以在这里使用核方法,并将每个向量与其余的向量进行投影;但是,我不认为这是必要的,而且如果您的数据非常大,它可能效率很低。就目前而言,将数据提高到两个人的能力应该是可行的。结果存储在第二维度中。

代码语言:javascript
复制
projDegree = 2;
projData = zeros(nSignals, maxSize, 2).*NaN;
for k = 1:nSignals
    vecSize = length(dataVectors{k}.data);
    projData(k, 1:vecSize, 1) = dataVectors{k}.data;
    projData(k, 1:vecSize, 2) = dataVectors{k}.data.*projDegree;
end
projData = reshape(projData, [], 2);

在这里,projData将有行1和列1,第一个晶须的原始数据(或在这里称为信号),列2将具有新的维度。假设您总共有8晶须,那么,projData将获得1917等行中第一个晶须的数据。21018等行中第二晶须的数据。如果您想要返回原始数据,这一点很重要。另外,您可以尝试使用不同的projDegree,但我怀疑这会产生很大的不同。

现在我们对2D数据执行K-指;但是,我们提供了初始点,而不是让它用k-方式++来确定它们。我在这里提出的初始点是每个晶须的每个矢量的第一个数据点。以这种方式,k-方法将离开那里,并将相应地转移到集群。我们将结果保存在idxK中。

代码语言:javascript
复制
idxK = kmeans(projData,nSignals, 'Start', projData(1:nSignals, :));

然后你就有了。变量idxK将告诉您哪个数据点属于哪个集群。

下面是我建议的解决方案的工作示例。第一部分只是试图生成看起来像您的数据的数据,您可以跳过它。

代码语言:javascript
复制
rng(9, 'twister')
nSignals = 8;   % number of whiskers
n = 1000;       % number of data points
allData = zeros(nSignals, n);   % all the data will be stored here

% this loop will just generate some data that looks like yours
for k = 1:nSignals
    x = sort(rand(1,n));
    nPeriods = round(rand*9)+1;     % the sin can have between 1-10 periods
    nShiftAmount = round(randn*30);     % shift between ~ -100 to +100
    y = sin(x*2*pi*nPeriods) + (randn(1,n).*0.5);
    y = y + nShiftAmount;
    allData(k, :) = y;
end
nanIdx = round(rand(1, round(n*0.05)*nSignals).*((n*nSignals)-1))+1;   
allData(nanIdx) = NaN;      % about 5% of the data is now missing

figure(1);
for k = 1:nSignals
    nanIdx = ~isnan(allData(k, :));
    dataVectors{k}.data = allData(k, nanIdx);
    plot(dataVectors{k}.data, 'kx'), hold on;
end

代码语言:javascript
复制
% determine the max size 
maxSize = -Inf;
for k = 1:nSignals
    if length(dataVectors{k}.data) > maxSize
        maxSize = length(dataVectors{k}.data);
    end
end

% making the data now into two dimensions and NaN pad
projDegree = 2;
projData = zeros(nSignals, maxSize, 2).*NaN;
for k = 1:nSignals
    vecSize = length(dataVectors{k}.data);
    projData(k, 1:vecSize, 1) = dataVectors{k}.data;
    projData(k, 1:vecSize, 2) = dataVectors{k}.data.*projDegree;
end
projData = reshape(projData, [], 2);
figure(2); plot(projData(:,1), projData(:,2), 'kx');

代码语言:javascript
复制
% run k-means using the first points of all measure as the initial points
idxK = kmeans(projData,nSignals, 'Start', projData(1:nSignals, :));
figure(3);
liColors = [{'yx'},{'mx'},{'cx'},{'bx'},{'kx'},{'gx'},{'rx'},{'gd'}];
for k = 1:nSignals
    plot(projData(idxK==k,1), projData(idxK==k,2), liColors{k}), hold on;
end

代码语言:javascript
复制
% plot results on original data
figure(4);
for k = 1:nSignals
    plot(projData(idxK==k,1), liColors{k}), hold on;
end

如果这有帮助的话请告诉我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31453614

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档