主要内容

找到一个钟摆运动的长度

这个例子向您展示了如何计算一个钟摆运动的长度,分段摆的摆和计算中心在许多图像帧,然后拟合圆的中心坐标方程。

步骤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和删除背景结构使用imopenimclearborder

初始化一个二进制数组包含分段摆帧。

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));

另请参阅

|||||