【OpenCv光流法进行运动目标检测】

opencv系列文章目录

文章目录

  • opencv系列文章目录
  • 前言
  • 一、光流法是什么?
  • 二、光流法实例
    • 1.C的
    • 2.C++版本
    • 3.python版本
  • 总结


前言

随着计算机视觉技术的迅猛发展,运动目标检测在图像处理领域中扮演着至关重要的角色。在现实世界中,我们常常需要追踪视频中的运动目标,例如交通摄像头中的车辆、安防监控中的行人,甚至是自动驾驶领域中的车辆和行人。为了实现高效准确的运动目标检测,研究者们提出了各种各样的方法。

在众多运动目标检测方法中,光流法(Optical Flow)是一种经典且有效的技术。光流法通过追踪图像中像素点的运动轨迹,可以帮助我们实时了解运动目标的位置和速度信息。它不仅在实时性上具有优势,还在处理各种环境和运动类型下都表现出色。


一、光流法是什么?

光流法(Optical Flow)是计算机视觉领域中一种经典的技术,用于描述图像序列中像素点在时间上的运动轨迹。光流法的基本思想源于图像中的像素在相邻帧之间随时间的变化,通过检测像素点的移动,我们可以获得关于场景中物体运动的重要信息。这种技术在目标跟踪、运动分析、视觉导航等领域得到广泛应用。

光流法的基本假设是,相邻帧之间相邻像素的灰度值在短时间内基本保持不变。根据这个假设,光流法通过分析图像序列中相邻帧之间的灰度值变化,推断出像素点的运动信息。它可以帮助我们了解运动目标的速度、方向和轨迹,甚至可以用于运动目标的跟踪和分割。

在实际应用中,光流法的算法有多种。其中,Lucas-Kanade方法是最常见的一种,它假设了图像中的运动是局部的,即在图像上某一点附近的像素具有相似的运动。该方法通过计算像素点周围区域的梯度和时间上的灰度变化,求解一个线性方程组,从而估计出光流向量。另外,Horn-Schunck方法则假设了整幅图像的运动是平滑的,并且在整个图像上求解一个全局的光流场。

光流法的应用非常广泛。在视频压缩中,光流信息可以用于帧内预测,提高压缩效率。在自动驾驶领域,光流法可以用于车辆和行人的运动轨迹预测,帮助车辆规划路径。在医学图像分析中,光流法可以用于心脏和血流的运动分析,帮助医生诊断心脏疾病。

总的来说,光流法作为一种经典的计算机视觉技术,为我们提供了探测运动目标、分析动态场景的重要手段。它的应用不仅帮助我们更好地理解图像序列中的运动信息,也推动了计算机视觉领域的发展。
几种光流估计算法的简介

1) 基于梯度的方法

基于梯度的方法又称为微分法,它是利用时变图像灰度(或其滤波形式)的时空微分(即时空梯度函数)来计算像素的速度矢量。

由于计算简单和较好的结果,该方法得到了广泛应用和研究。典型的代表是Horn-Schunck算法与Lucas-Kanade(LK)算法。

Horn-Schunck算法在光流基本约束方程的基础上附加了全局平滑假设,假设在整个图像上光流的变化是光滑的,即物体运动矢量是平滑的或只是缓慢变化的。

基于此思想,大量的改进算法不断提出。Nagel采用有条件的平滑约束,即通过加权矩阵的控制对梯度进行不同平滑处理;Black和Anandan针对多运动的估计问题,提出了分段平滑的方法。

  1. 基于匹配的方法

基于匹配的光流计算方法包括基于特征和区域的两种。

基于特征的方法不断地对目标主要特征进行定位和跟踪,对目标大的运动和亮度变化具有鲁棒性。存在的问题是光流通常很稀疏,而且特征提取和精确匹配也十分困难。

基于区域的方法先对类似的区域进行定位,然后通过相似区域的位移计算光流。这种方法在视频编码中得到了广泛的应用。然而,它计算的光流仍不稠密。另外,这两种方法估计亚像素精度的光流也有困难,计算量很大。

3)基于能量的方法

基于能量的方法又称为基于频率的方法,在使用该类方法的过程中,要获得均匀流场的准确的速度估计,就必须对输入的图像进行时空滤波处理,即对时间和空间的整合,但是这样会降低光流的时间和空间分辨率。基于频率的方法往往会涉及大量的计算,另外,要进行可靠性评价也比较困难。

4)基于相位的方法

基于相位的方法是由Fleet和Jepson提出的,Fleet和Jepson最先提出将相位信息用于光流计算的思想。当我们计算光流的时候,相比亮度信息,图像的相位信息更加可靠,所以利用相位信息获得的光流场具有更好的鲁棒性。基于相位的光流算法的优点是:对图像序列的适用范围较宽,而且速度估计比较精确,但也存在着一些问题:第一,基于相位的模型有一定的合理性,但是有较高的时间复杂性;第二,基于相位的方法通过两帧图像就可以计算出光流,但如果要提高估计精度,就需要花费一定的时间;第三,基于相位的光流计算法对图像序列的时间混叠是比较敏感的。

5)神经动力学方法

神经动力学方法是利用神经网络建立的视觉运动感知的神经动力学模型,它是对生物视觉系统功能与结构比较直接的模拟。

尽管光流计算的神经动力学方法还很不成熟,然而对它的研究却具有极其深远的意义。随着生物视觉研究的不断深入,神经方法无疑会不断完善,也许光流计算乃至计算机视觉的根本出路就在于神经机制的引入。神经网络方法是光流技术的一个发展方向。

3.稠密光流与稀疏光流

除了根据原理的不同来区分光流法外,还可以根据所形成的光流场中二维矢量的疏密程度将光流法分为稠密光流与稀疏光流两种。

二、光流法实例

1.C的

设置参数放到C#版本里面,效果好像没有C++效果来的明显,可能是一些参数的设置导致的。

代码如下(示例):

using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Windows.Forms;namespace WindowsFormsApp
{public partial class Form1 : Form{// 当前图片public Mat gray = new Mat();      // 预测图片public Mat gray_prev = new Mat();// point1为特征点的原来位置,point2为特征点的新位置public Point2f[] points1;public Point2f[] points2;// 初始化跟踪点的位置public Point2f[] initial;// 检测的最大特征数public int maxCount = 500;         // 特征检测的等级public double qLevel = 0.01;       // 两特征点之间的最小距离public double minDist = 10.0;     // 跟踪特征的状态,特征的流发现为1,否则为0public byte[] status;       public float[] err;public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){var capture = new VideoCapture(@"1.avi");// 计算帧率int sleepTime = (int)Math.Round(1000 / capture.Fps);// 声明实例 Mat类Mat image = new Mat();// 进入读取视频每镇的循环while (true){capture.Read(image);//判断是否还有没有视频图像 if (image.Empty())break;Mat result = tracking(image);// 在pictureBox1中显示效果图pictureBox1.Image = BitmapConverter.ToBitmap(result);Cv2.WaitKey(sleepTime);}}//--------------------------------------// function: tracking// brief: 跟踪// parameter: frame 输入的视频帧//            output 有跟踪结果的视频帧// return: void//--------------------------------------public Mat tracking(Mat frame){Mat output = new Mat();Cv2.CvtColor(frame, gray, ColorConversionCodes.BGR2GRAY);frame.CopyTo(output);// 添加特征点if (addNewPoints()){// 只用这个好像也没啥区别points1 = Cv2.GoodFeaturesToTrack(gray, maxCount, qLevel, minDist, new Mat(), 10, true, 0.04);initial = points1; 像素级检测特征点//Point2f[] po = Cv2.GoodFeaturesToTrack(gray, maxCount, qLevel, minDist, new Mat(), 3, true, 0.04); 亚像素级检测//points1 = Cv2.CornerSubPix(gray, po, new Size(5, 5), new Size(-1, -1), new TermCriteria());}if (gray_prev.Empty()){gray.CopyTo(gray_prev);}//光流金字塔,输出图二的特征点points2 = new Point2f[points1.Length];Cv2.CalcOpticalFlowPyrLK(gray_prev, gray, points1, ref points2, out status, out err);// 去掉一些不好的特征点int k = 0;for (int i = 0; i < points2.Length; i++){if (acceptTrackedPoint(i)){initial[k] = initial[i];points2[k++] = points2[i];}}// 显示特征点和运动轨迹for (int i = 0; i < k; i++){Cv2.Line(output, (Point)initial[i], (Point)points2[i],new Scalar(0, 0, 255));Cv2.Circle(output, (Point)points2[i], 3,new Scalar(0, 255, 0), -1);}// 把当前跟踪结果作为下一此参考Swap(ref points2, ref points1);Swap(ref gray_prev, ref gray);return output;}static void Swap<T>(ref T a, ref T b){T t = a;a = b;b = t;}//-------------------------------------// function: addNewPoints// brief: 检测新点是否应该被添加// parameter:// return: 是否被添加标志//-------------------------------------public bool addNewPoints(){if (points1 == null) return true;// 这个实际上是限制了点数,最好别开//return  points1.Length <= 10;//System.Diagnostics.Debug.WriteLine(points1.Length);return true;}//--------------------------------------// function: acceptTrackedPoint// brief: 决定哪些跟踪点被接受// parameter:// return://-------------------------------------bool acceptTrackedPoint(int i){return status[i] == 1 && ((Math.Abs(points1[i].X - points2[i].X) + Math.Abs(points1[i].Y - points2[i].Y)) > 5);}}
}

这段代码是一个基于OpenCVSharp的C#程序,实现了光流法(Optical Flow)在视频中的运动目标跟踪。下面对代码进行逐行解释:

using OpenCvSharp; 和 using OpenCvSharp.Extensions;:导入OpenCVSharp库的命名空间,该库是OpenCV的C#封装。public partial class Form1 : Form:定义一个名为Form1的Windows窗体类,该类继承自基类Form。类中声明了一系列变量,如gray和gray_prev是用于存储灰度图像的Mat对象,points1和points2是特征点的原始和新位置,initial是特征点的初始位置,status和err是用于存储光流算法的状态和误差的数组。public Form1():构造函数,初始化窗体。private void button1_Click(object sender, EventArgs e):按钮点击事件的处理函数,该函数实现了视频的读取和光流法运动目标跟踪。var capture = new VideoCapture(@"1.avi");:打开名为"1.avi"的视频文件。Mat image = new Mat();:创建一个Mat对象用于存储视频帧。while (true):无限循环,用于处理视频的每一帧。capture.Read(image);:读取视频的一帧。Mat result = tracking(image);:调用tracking函数进行运动目标跟踪。pictureBox1.Image = BitmapConverter.ToBitmap(result);:将跟踪结果显示在Windows窗体中。public Mat tracking(Mat frame):跟踪函数,接受一个视频帧作为输入,返回一个Mat对象,其中包含了运动目标的跟踪结果。Cv2.CvtColor(frame, gray, ColorConversionCodes.BGR2GRAY);:将彩色图像转换为灰度图像。addNewPoints():检测是否需要添加新的特征点。Cv2.CalcOpticalFlowPyrLK(gray_prev, gray, points1, ref points2, out status, out err);:使用Lucas-Kanade光流法计算特征点的新位置。acceptTrackedPoint(int i):根据状态和位置信息,决定哪些跟踪点被接受。将跟踪结果画在output图像上,返回output。Swap(ref points2, ref points1); 和 Swap(ref gray_prev, ref gray);:交换points2和points1、gray_prev和gray的引用。

总的来说,这段代码实现了一个简单的视频运动目标跟踪系统。它使用Lucas-Kanade光流法计算特征点的运动轨迹,将跟踪结果实时显示在Windows窗体中。需要注意的是,该代码仅实现了基本的光流跟踪功能,实际应用中可能需要更多的优化和改进,例如处理光照变化、遮挡等问题。

2.C++版本

代码如下(示例):

#include <opencv2/video/video.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
#include <cstdio>using namespace std;
using namespace cv;void tracking(Mat& frame, Mat& output);
bool addNewPoints();
bool acceptTrackedPoint(int i);string window_name = "optical flow tracking";
Mat gray;	    // 当前图片
Mat gray_prev;	// 预测图片
vector<Point2f> points[2];	// point0为特征点的原来位置,point1为特征点的新位置
vector<Point2f> initial;	// 初始化跟踪点的位置
vector<Point2f> features;	// 检测的特征
int maxCount = 500;	        // 检测的最大特征数
double qLevel = 0.01;	    // 特征检测的等级
double minDist = 10.0;	    // 两特征点之间的最小距离
vector<uchar> status;	    // 跟踪特征的状态,特征的流发现为1,否则为0
vector<float> err;int main()
{Mat frame;Mat result;VideoCapture capture("1.avi");if (capture.isOpened())	// 摄像头读取文件开关{capture >> frame;imshow(window_name, frame);waitKey(0);while (true){capture >> frame;if (frame.empty()) break;tracking(frame, result);imshow(window_name, result);if ((char)waitKey(50) == 27){break;}}}return 0;
}//--------------------------------------
// function: tracking
// brief: 跟踪
// parameter: frame	输入的视频帧
//			  output 有跟踪结果的视频帧
// return: void
//--------------------------------------
void tracking(Mat& frame, Mat& output)
{//此句代码的OpenCV3版为:cvtColor(frame, gray, COLOR_BGR2GRAY);//此句代码的OpenCV2版为://cvtColor(frame, gray, CV_BGR2GRAY);frame.copyTo(output);// 添加特征点if (addNewPoints()){goodFeaturesToTrack(gray, features, maxCount, qLevel, minDist);points[0].insert(points[0].end(), features.begin(), features.end());initial.insert(initial.end(), features.begin(), features.end());}if (gray_prev.empty()){gray.copyTo(gray_prev);}// l-k光流法运动估计calcOpticalFlowPyrLK(gray_prev, gray, points[0], points[1], status, err);// 去掉一些不好的特征点int k = 0;for (size_t i = 0; i < points[1].size(); i++){if (acceptTrackedPoint(i)){initial[k] = initial[i];points[1][k++] = points[1][i];}}points[1].resize(k);initial.resize(k);// 显示特征点和运动轨迹for (size_t i = 0; i < points[1].size(); i++){line(output, initial[i], points[1][i], Scalar(0, 0, 255));circle(output, points[1][i], 3, Scalar(0, 255, 0), -1);}// 把当前跟踪结果作为下一此参考swap(points[1], points[0]);swap(gray_prev, gray);
}//-------------------------------------
// function: addNewPoints
// brief: 检测新点是否应该被添加
// parameter:
// return: 是否被添加标志
//-------------------------------------
bool addNewPoints()
{return points[0].size() <= 10;
}//--------------------------------------
// function: acceptTrackedPoint
// brief: 决定哪些跟踪点被接受
// parameter:
// return:
//-------------------------------------
bool acceptTrackedPoint(int i)
{return status[i] && ((abs(points[0][i].x - points[1][i].x) + abs(points[0][i].y - points[1][i].y)) > 2);
}
VideoCapture capture("1.avi");:打开名为"1.avi"的视频文件。
while (true):无限循环,用于处理视频的每一帧。
cvtColor(frame, gray, COLOR_BGR2GRAY);:将彩色图像转换为灰度图像。
goodFeaturesToTrack(gray, features, maxCount, qLevel, minDist);:检测图像中的好的特征点。
calcOpticalFlowPyrLK(gray_prev, gray, points[0], points[1], status, err);:使用Lucas-Kanade光流法计算特征点的新位置。
line(output, initial[i], points[1][i], Scalar(0, 0, 255)); 和 circle(output, points[1][i], 3, Scalar(0, 255, 0), -1);:绘制特征点的轨迹和新位置。
swap(points[1], points[0]); 和 swap(gray_prev, gray);:交换points[1]和points[0]、gray_prev和gray的引用,为下一帧的计算做准备。

这段代码实现了基于Lucas-Kanade光流法的简单目标跟踪系统。在每一帧图像中,它通过检测特征点,并使用光流法计算特征点的运动轨迹,然后在图像上绘制特征点的运动路径,从而实现了目标的跟踪。

3.python版本

import cv2
import numpy as np# 初始化全局变量
gray_prev = None  # 上一帧的灰度图像
points1 = None    # 上一帧的特征点
points2 = None    # 当前帧的特征点
st = None         # 特征点的状态# 判断特征点是否应该被接受
def acceptTrackedPoint(a, b, c):return (c == 1) and ((abs(a[0][0] - b[0][0]) - abs(a[0][1] - b[0][1])) > 2)# 交换两个变量的值
def swap(a, b):return b, a# 跟踪函数
def tracking(frame):global gray_prev, points1, points2, stgray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  # 将彩色图像转换为灰度图像output = frame.copy()# 添加特征点if gray_prev is None:gray_prev = gray.copy()else:# 计算光流points2, st, err = cv2.calcOpticalFlowPyrLK(gray_prev, gray, points1, None)# 去掉一些不好的特征点k = 0for i in range(points2.size):if i >= st.size:breakif acceptTrackedPoint(points1[i], points2[i], st[i]):points1[k] = points1[i]points2[k] = points2[i]k += 1points1 = points1[:k]points2 = points2[:k]# 显示特征点和运动轨迹for (new, old) in zip(points2, points1):a, b = new.ravel()c, d = old.ravel()output = cv2.line(output, (int(a), int(b)), (int(c), int(d)), (0, 0, 255), 1)output = cv2.circle(output, (int(c), int(d)), 3, (0, 255, 0), -1)# 把当前跟踪结果作为下一次参考points1, points2 = swap(points1, points2)gray_prev, gray = swap(gray_prev, gray)return outputif __name__ == "__main__":# 打开视频文件video = cv2.VideoCapture('1.avi')fps = video.get(cv2.CAP_PROP_FPS)  # 获取视频帧率success = Truewhile success:success, frame = video.read()  # 读取视频帧if not success:breakresult = tracking(frame)  # 进行目标跟踪cv2.imshow('result', result)  # 显示结果cv2.waitKey(int(1000 / int(fps)))  # 设置延迟时间,使播放速度与视频原始帧率一致video.release()  # 释放视频文件cv2.destroyAllWindows()  # 关闭所有窗口

这段代码通过光流法实现了视频中运动目标的跟踪。它使用Lucas-Kanade光流法来估计特征点的运动轨迹。首先,它将视频的每一帧转换为灰度图像。然后,它利用光流法计算相邻两帧之间的特征点的运动。接着,通过acceptTrackedPoint函数筛选出好的特征点,并将它们连接起来形成运动轨迹。最终,它在原始视频帧上绘制了特征点的运动轨迹,并通过窗口展示结果。整个过程实现了对视频中运动目标的简单跟踪。

import numpy as np
import cv2# 打开默认摄像头(通常是编号为0的摄像头)
cap = cv2.VideoCapture(0)# ShiTomasi角点检测的参数
feature_params = dict(maxCorners=100,  # 最多返回的角点数qualityLevel=0.3,  # 角点的质量水平minDistance=7,      # 角点之间的最小距离blockSize=7)        # 计算角点检测时的窗口大小# 光流法参数
lk_params = dict(winSize=(15, 15),       # 搜索窗口的大小maxLevel=2,             # 金字塔的最大层数criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))  # 迭代终止条件# 随机生成100个颜色,用于绘制跟踪点的轨迹
color = np.random.randint(0, 255, (100, 3))# 读取视频的第一帧
ret, old_frame = cap.read()
# 将第一帧转换为灰度图像
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# 使用ShiTomasi角点检测方法找到角点
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
# 创建一个和视频帧大小相同的黑色掩码图片
mask = np.zeros_like(old_frame)while True:# 读取视频帧ret, frame = cap.read()# 将当前帧转换为灰度图像frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 计算光流以获取点的新位置p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)# 选择good points(即成功跟踪的点)good_new = p1[st == 1]good_old = p0[st == 1]# 绘制跟踪框和跟踪点的轨迹for i, (new, old) in enumerate(zip(good_new, good_old)):a, b = new.ravel()  # 获取新点的坐标c, d = old.ravel()  # 获取旧点的坐标# 在掩码图片上绘制轨迹mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)# 在当前帧上绘制跟踪点frame = cv2.circle(frame, (int(a), int(b)), 5, color[i].tolist(), -1)# 将轨迹绘制到当前帧上img = cv2.add(frame, mask)# 显示带有跟踪点轨迹的当前帧cv2.imshow('frame', img)# 按下ESC键退出循环k = cv2.waitKey(30) & 0xffif k == 27:break# 更新旧帧和旧点old_gray = frame_gray.copy()p0 = good_new.reshape(-1, 1, 2)# 关闭所有窗口,释放摄像头
cv2.destroyAllWindows()
cap.release()

上述代码实现了一个基于光流法的实时目标跟踪系统。该系统使用了OpenCV的光流法函数来追踪视频帧中的角点。下面是代码的主要步骤和功能总结:

摄像头初始化: 代码使用OpenCV的VideoCapture类初始化摄像头,获取视频帧。角点检测: 使用ShiTomasi角点检测方法在视频的第一帧中找到特征点(角点),这些点将作为跟踪的起始点。光流估计: 利用Lucas-Kanade光流法(cv2.calcOpticalFlowPyrLK函数)计算特征点在下一帧中的位置。特征点筛选: 根据光流法的输出,筛选出成功跟踪的特征点。绘制跟踪结果: 将跟踪点绘制在当前视频帧上,并用线连接跟踪点的轨迹,形成了目标的运动轨迹。循环处理: 通过循环不断读取视频帧,进行光流法跟踪,并在每一帧上绘制跟踪点的轨迹。用户退出: 当用户按下ESC键时,程序退出循环,关闭窗口,释放摄像头资源。

这段代码演示了光流法在实时视频中的应用,能够捕捉目标在连续帧之间的运动轨迹,具有实时性和动态性。在这个例子中,代码使用Lucas-Kanade光流法实现了简单的目标跟踪,可以通过调整检测参数、光流法参数以及绘制效果来适应不同的场景和需求。

总结

提示:这里对文章进行总结:

光流法(Optical Flow)是一种计算图像中像素运动的技术。它基于图像序列中相邻帧之间像素灰度值的变化,通过分析这些变化,推断出像素在图像中的运动情况。光流法常被用于运动目标跟踪、视频压缩、图像稠密匹配等计算机视觉领域的任务。以下是光流法的使用总结和原理介绍:
使用总结:

目标跟踪: 光流法可以用于实时目标跟踪,通过追踪图像中的特征点,了解目标在视频帧之间的运动轨迹。动作分析: 在视频分析中,光流法可用于分析人体、车辆等物体的运动轨迹和动作,从而实现动作识别、行为分析等应用。图像稠密匹配: 光流法可以用于计算两幅图像之间的稠密匹配,即找到两幅图像中每个像素的对应点,通常在立体视觉和结构运动恢复中应用广泛。运动估计: 光流法用于估计图像序列中物体的运动速度和方向,这对于视频压缩和运动估计相关研究非常重要。

原理介绍:

光流法基于以下假设和原理:

空间一致性假设: 在图像的局部区域内,相邻像素的运动是一致的。这意味着,相邻像素的灰度值变化是由相同的运动引起的。亮度恒定假设(Brightness Constancy Assumption): 在短时间内,运动物体的像素灰度值保持不变。这意味着,同一物体上的像素在不同帧之间的灰度值保持恒定,变化的灰度值是由于光照变化或阴影引起的。

基于上述假设,光流法通常使用以下步骤进行计算:

构建光流约束方程: 通过亮度恒定假设,可以得到一个描述相邻帧像素之间关系的方程。光流方程可以通过对图像中每个像素应用亮度恒定假设得到。求解光流方程: 光流方程通常是一个局部的非线性方程组。常见的求解方法有Lucas-Kanade方法、Horn-Schunck方法等。这些方法通过最小化误差函数或优化约束条件来求解像素的运动速度。稠密光流与稀疏光流: 光流法可以得到稠密光流和稀疏光流。稠密光流计算图像中所有像素的运动信息,而稀疏光流只计算选定像素点的运动信息。

总的来说,光流法是一种基于局部运动假设的计算图像运动的方法。然而,它对光照变化和遮挡等情况敏感,因此在实际应用中,通常需要结合其他方法来处理复杂场景。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/159534.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql5.7大限将至升级Mysql 8.0过程记录(未完)

一、前言 时间很快&#xff0c;到2023年10月底&#xff0c;MySQL 5.7就到了它的EOL&#xff08;End of Life&#xff09;&#xff0c;届时将不会提供任何补丁&#xff0c;无法应对潜在的安全风险&#xff1b;是时候和 MySQL 5.7 说再见了&#xff01;&#xff01;&#xff01;&…

C++语言实现网络爬虫详细代码

当然&#xff01;下面是一个用C语言实现的基本网络爬虫的详细代码示例&#xff1a; #include <iostream> #include <string> #include <curl/curl.h> size_t writeCallback(void* contents, size_t size, size_t nmemb, std::string* output) {size_t totalS…

强化科技创新“辐射力”,中国移动的数智化大棋局

作者 | 曾响铃 文 | 响铃说 丝滑流畅的5G连接、每时每刻的数字生活服务、无处不在的智能终端、拟人交流的AI助手、梦幻般的XR虚拟现实、直接感受的裸眼3D…… 不知不觉&#xff0c;那个科幻片中的世界&#xff0c;越来越近。 数智化新世界的“气氛”&#xff0c;由一个个具…

GEE 18:基于GEE平台的土地荒漠化监测与分析【论文复现】

Desertification 1. 研究背景1.1 参考论文1.2 参数获取1.2.1 NDVI1.2.2 Albedo1.2.3 Normalizing indices1.2.4 Calculating the quantitative relationship1.2.5 Calculating DDI2. GEE2.1 数据2.2 GEE code2.2.1 Study region2.2.2 Reomove cloud for Landsat-82.2.3 Calcula…

CISA 彻底改变了恶意软件信息共享:网络安全的突破

在现代网络安全中&#xff0c;战术技术和程序&#xff08;TTP&#xff09;的共享对于防范网络事件至关重要。 因此&#xff0c;了解攻击向量和攻击类型之间的关联如今是让其他公司从其他公司遭受的 IT 事件中受益&#xff08;吸取经验教训&#xff09;的重要一步。 美国主要网…

PyTorch入门教学——使用PyCharm创建一个PyTorch项目

首先需要创建好PyTorch的虚拟环境&#xff0c;步骤&#xff1a;PyTorch入门教学——简介与环境配置-CSDN博客打开PyCharm&#xff0c;新建项目&#xff0c;选择项目的存放位置。选择先前配置的解释器&#xff0c;也就是虚拟环境中的解释器。&#xff08;记住创建的虚拟环境所在…

【Express】服务端渲染(模板引擎 EJS)

EJS&#xff08;Embedded JavaScript&#xff09;是一款流行的模板引擎&#xff0c;可以用于在Express中创建动态的HTML页面。它允许在HTML模板中嵌入JavaScript代码&#xff0c;并且能够生成基于数据的动态内容。 下面是一个详细的讲解和示例&#xff0c;演示如何在Express中…

Linux:Mac VMware Fusion13以及CentOS7安装包

Linux&#xff1a;Mac VMware Fusion13以及CentOS7安装包 1. Mac VMware Fusion132. CentOS7安装包3. 安装 1. Mac VMware Fusion13 下载官网地址&#xff1a;https:www.vmware.com/products/fusion/fusion-evaluation.html 2. CentOS7安装包 注意是m芯片需要使用arm架构的i…

手动下载/安装Xcode的simulator

目录 前言解决方案1.获取simulator包下载地址1.1 Apple后台1.2 手动 2.使用三方下载工具下载3.使用命令安装simulator 前言 Xcode某个版本更新之后不带iOS的Simulator,导致全新下载一个Xcode后没法编译项目.公司的网又很坑,每次断掉点重试都重新下载,导致完全没法下下来.特别影…

论文阅读:Seeing in Extra Darkness Using a Deep-Red Flash

论文阅读&#xff1a;Seeing in Extra Darkness Using a Deep-Red Flash 今天介绍的这篇文章是 2021 年 ICCV 的一篇 oral 文章&#xff0c;主要是为了解决极暗光下的成像问题&#xff0c;通过一个深红的闪光灯补光。实现了暗光下很好的成像效果&#xff0c;整篇文章基本没有任…

Go-Python-Java-C-LeetCode高分解法-第十周合集

前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接&#xff1a;LeetCode-Go-Python-Java-C 欢迎订阅CSDN专栏&#xff0c;每日一题&#xff0c;和博主一起进步 LeetCode专栏 我搜集到了50道精选题&#xff0c;适合速成概览大部分常用算法 突…

FutureTask的测试使用和方法执行分析

FutureTask类图如下 java.util.concurrent.FutureTask#run run方法执行逻辑如下 public void run() {if (state ! NEW ||!RUNNER.compareAndSet(this, null, Thread.currentThread()))return;try {Callable<V> c callable;if (c ! null && state NEW) {V res…

【大数据】Hive SQL语言(学习笔记)

一、DDL数据定义语言 1、建库 1&#xff09;数据库结构 默认的数据库叫做default&#xff0c;存储于HDFS的&#xff1a;/user/hive/warehouse 用户自己创建的数据库存储位置&#xff1a;/user/hive/warehouse/database_name.db 2&#xff09;创建数据库 create (database|…

【教程】使用vuepress构建静态文档网站,并部署到github上

官网 快速上手 | VuePress (vuejs.org) 构建项目 我们跟着官网的教程先构建一个demo 这里我把 vuepress-starter 这个项目名称换成了 howtolive 创建并进入一个新目录 mkdir howtolive && cd howtolive使用你喜欢的包管理器进行初始化 yarn init 这里的问题可以一…

nodejs+vue百鸟全科赏析网站

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

通过示例详细了解ES6导入导出模块

通过示例详细了解ES6导入导出模块 似乎许多开发人员认为 ES6 模块只不过是export、import关键字。事实上&#xff0c;它更加多样化。它拥有强大的功能和鲜为人知的问题。在本文中&#xff0c;我们将使用一些示例来了解这些内容。 示例一 // index.mjs import { default } fr…

深度学习-卷积神经网络

文章目录 应用卷积神经网络卷积处理分类问题 应用 图片分类图片检索图片分割图片风格迁移姿态估计OCR等 卷积神经网络 核概念计算机视觉中处理图片的核大小是通过经验得来的&#xff0c;而深度学习中的权重大小是自己学习出的。卷积VS神经网络&#xff1a;一个是局部观察一个…

【实操】基于ChatGPT构建知识库

前言 最近有些实践&#xff0c;因为后面要去研究fine-tune了&#xff0c;想着记录一下chatgpt向量数据库构建知识库的一些实操经验&#xff0c;不记我很快就忘了&#xff0c;哈哈。 首先&#xff0c;提一下为啥会出现向量数据库这个技术方案&#xff1f; 大家经过实践发现&…

【传输层协议】UDP/TCP结构特点与原理(详解)

文章目录 1. UDP1.1 UDP结构1.2 UDP特点1. 无连接2. 不可靠3. 面向数据报4. 缓冲区5. 大小受限6. 无序性 2. TCP2.1 TCP结构2.2 TCP特点1. 有连接2. 可靠性3. 面向字节流4. 拥塞控制5. 头部开销 2.3 TCP原理1. 确认应答&#xff08;安全机制&#xff09;2. 超时重传&#xff08…

数据结构与算法--其他算法

数据结构与算法--其他算法 1 汉诺塔问题 2 字符串的全部子序列 3 字符串的全排列 4 纸牌问题 5 逆序栈问题 6 数字和字符串转换问题 7 背包问题 8 N皇后问题 暴力递归就是尝试 1&#xff0c;把问题转化为规模缩小了的同类问题的子问题 2&#xff0c;有明确的不需要继续…