找到一个钟摆运动的长度
这个例子向您展示了如何计算一个钟摆运动的长度,分段摆的摆和计算中心在许多图像帧,然后拟合圆的中心坐标方程。
步骤1:加载图片
负载从垫摆数据文件。该文件包含两个变量。的帧
作为一个四维数值数组变量包含视频。的矩形
变量包含一个感兴趣的区域,摆的程度。
负载摆;
预览视频使用implay
。你可以看到钟摆摆动在每一帧的上半部分。
implay(帧);
步骤2:选择区域摆摆动
为了提高分割的效率,创建一个新的一系列帧,只包含地区钟摆摆动。
第一次执行imcrop
在一帧,specifyiing种植地区预加载矩形
变量。接下来,初始化一个数组来存储所有的剪裁框架,基于最先帧的大小。最后,遍历所有的帧,使用相同的种植作物每一个区域,并将结果保存到数组初始化。
first_frame =帧(:,:,:1);first_region = imcrop (first_frame、矩形);nFrames =大小(框架,4);frame_regions = repmat (uint8(0)[大小(first_region) nFrames]);为数= 1:nFrames frame_regions(:,:,:,数)= imcrop(帧(::,:,计数),矩形);结束imshow (frame_regions (:,:,: 1))
步骤3:段每一帧的钟摆
注意,摆比背景要暗许多。可以通过转换段钟摆在每一帧的帧灰度,阈值使用imbinarize
和删除背景结构使用imopen
和imclearborder
。
初始化一个二进制数组包含分段摆帧。
seg_pend = false([大小(first_region, 1)大小(first_region 2) nFrames]);质心= 0 (nFrames, 2);se_disk = strel (“磁盘”3);
遍历所有的框架和执行分割和后处理。蒙太奇,显示原始帧和分割的结果。
为数= 1:nFrames fr = frame_regions(:,:,:,数);肾小球滤过率(gfr) = im2gray (fr);肾小球滤过率(gfr) = imcomplement (gfr);bw = imbinarize(肾小球滤过率(gfr), 0.7);%确定阈值实验bw = imopen (bw, se_disk);bw = imclearborder (bw);seg_pend(:,:,数)= bw;蒙太奇({fr, labeloverlay(肾小球滤过率(gfr), bw)});暂停(0.2)结束
步骤4:在每一帧找到分段摆的中心
你可以看到摆的形状变化在不同的帧。这不是一个严重的问题,因为你只需要它的中心。您将使用钟摆中心找到摆的长度。
使用regionprops
计算中心的钟摆。
pend_centers = 0 (nFrames, 2);为数= 1:nFrames属性= regionprops (seg_pend (:,:,)“重心”);pend_centers(计数:)= property.Centroid;结束
显示钟摆中心使用情节
。
x = pend_centers (: 1);y = pend_centers (:, 2);图绘制(x, y,“m”。)轴ij轴平等的持有在;包含(“x”);ylabel (“y”);标题(“摆中心”);
第五步:计算半径通过拟合圆摆中心
重写一个圆的基本方程:
(x-xc) ^ 2 + (y-yc) ^ 2 = r ^ 2
在哪里(xc、yc)
是中心,用参数一个
,b
,c
作为
x ^ 2 + y ^ 2 + x + b * * y + c = 0
在哪里= 2 *我
,b = 2 * yc
,c = xc ^ 2 + yc ^ 2 -半径^ 2
。
你可以求出参数一个
,b
,c
使用最小二乘法。重写上述方程
* x + b * y + c = - (x ^ 2 + y ^ 2)
也可以写成
[x y 1] * [a, b, c] = - x ^ 2 - y ^ 2
。
解这个方程使用反斜杠(\
)算子。
这个圆的半径是钟摆在像素的长度。
abc = [x y的(长度(x), 1)] \ (x。^ 2 + y ^ 2);一个= abc (1);b = abc (2);c = abc (3);xc =——/ 2;yc = - b / 2;circle_radius =√(xc ^ 2 + yc ^ 2) - c);pendulum_length =圆(circle_radius)
pendulum_length = 253
重叠的圆和圆摆的情节中心中心。
circle_theta =π/ 3:0.01:π* 2/3;x_fit = circle_radius * cos (circle_theta) + xc;y_fit = circle_radius * sin (circle_theta) + yc;情节(x_fit y_fit,“b -”);情节(xc、yc“软”,“线宽”2);情节(xc x (1), (yc y (1)),“b -”);文本(xc - 110, yc + 100, sprintf (“摆长度= % d像素”pendulum_length));
另请参阅
regionprops
|imclearborder
|imopen
|imbinarize
|imcomplement
|labeloverlay