光流法检测材料和目标的微变形区域,计算像素位移和应力应变

光流法的前提假设:

(1)相邻帧之间的亮度保持恒定,不适合现实光照环境下测试;

(2)相邻视频帧的取帧时间连续,相邻帧之间物体的运动比较“微小”,检测目标属于微变形,微运动;

(3)保持空间一致性;即,同一子图像的像素点具有相同的运动。

应用场景:

(1)物体在运动,相机是静止的;

(2)相机在运动,物体是静止的;

(3)两者都在运动;

本实验是在第一种情况下实现的。

光流法用于目标检测的原理:给图像中的每个像素点赋予一个速度矢量,这样就形成了一个运动矢量场。在某一特定时刻,图像上的点与三维物体上的点一一对应,这种对应关系可以通过投影来计算得到。根据各个像素点的速度矢量特征,可以对图像进行动态分析。如果图像中没有运动目标,则光流矢量在整个图像区域是连续变化的。当图像中有运动物体时,目标和背景存在着相对运动。运动物体所形成的速度矢量必然和背景的速度矢量有所不同,如此便可以计算出运动物体的位置。需要提醒的是,利用光流法进行运动物体检测时,计算量较大,无法保证实时性和实用性。

光流法用于目标跟踪的原理:

(1)对一个连续的视频帧序列进行处理;

(2)针对每一个视频序列,利用一定的目标检测方法,检测可能出现的前景目标;

(3)如果某一帧出现了前景目标,找到其具有代表性的关键特征点(可以随机产生,也可以利用角点来做特征点);

(4)对之后的任意两个相邻视频帧而言,寻找上一帧中出现的关键特征点在当前帧中的最佳位置,从而得到前景目标在当前帧中的位置坐标;

(5)重复(2)~(4)步骤,实现目标的跟踪;

用于光流计算的关键点和关键特征区域可以由广泛的选择,选取角点特征后,通过跟踪角点实现光流计算进而实现跟踪目标;选取目标对象区域中的某一子区域的灰度特征,计算相关系数求得该区域在下一帧中的最佳位置实现目标跟踪;也可以根据目标颜色特征实现跟踪。大多数算法一般都是基于两个关键的假设条件实现目标跟踪,一个是颜色一致假设;一个是微小运动假设。

calcOpticalFlowFarneback(prev_gray, gray, flowdata, 0.5, 3, 15, 3, 5, 1.2, 0);

//BGR渐变色

void drawOpticalFlowHF(const Mat &flowdata, Mat& image, int step) {

	vector<float> v1;
	vector<float> v2;
	
	
	for (int row = 0; row < image.rows; row++) {
		for (int col = 0; col < image.cols; col++) {
			const Point2f fxy = flowdata.at<Point2f>(row, col);
			v1.push_back(fxy.x);
			v2.push_back(fxy.y);
		}
	}
	vector<float>::iterator biggest = max_element(begin(v1), end(v1));
	cout << "Max element is " << *biggest << "at position " << distance(begin(v1), biggest) << endl;

	auto smallest = std::min_element(begin(v1), end(v1));
	cout << "min element is " << *smallest << " at position " << distance(begin(v1), smallest) << endl;

	vector<float>::iterator biggest2 = max_element(begin(v2), end(v2));
	cout << "Max element is " << *biggest2 << "at position " << distance(begin(v2), biggest2) << endl;

	auto smallest2 = std::min_element(begin(v2), end(v2));
	cout << "min element is " << *smallest2 << " at position " << distance(begin(v2), smallest2) << endl;
	float r, g, b;
	test_num = *biggest;
	for (int row = 0; row < image.rows; row++) {
		for (int col = 0; col < image.cols; col++) {
			const Point2f fxy = flowdata.at<Point2f>(row, col);
			//v1.push_back(fxy.x);
			//v2.push_back(fxy.y);
			if (fxy.x > 0 || fxy.y > 0) {	
			
				if ((4.35682-abs(fxy.x))>3 && abs(fxy.x)<4.35682)
				{
					//B、G、R根据极值求出对应格式
				}
				else if ((4.35682 - abs(fxy.x))>2.4 && (4.35682 - abs(fxy.x))<3)
				{

				//B、G、R根据极值求出对应格式
					
				}
				else if ((4.35682 - abs(fxy.x))>1.8 &&(4.35682 - abs(fxy.x))<2.4)
				{
                                    //B、G、R根据极值求出对应格式
					
				}
				else if ((4.35682 - abs(fxy.x))>1.2 && (4.35682 - abs(fxy.x))<1.8)
				{
                                    //B、G、R根据极值求出对应格式
					
				}
				else
				{

                                    //B、G、R根据极值求出对应格式
				}
				line(image, Point(col, row), Point(cvRound(col + fxy.x), cvRound(row + fxy.y)), Scalar(b*255, g*255, r*255), 2, 8, 0);
				//circle(image, Point(col, row), 2, Scalar(b * 255, g * 255, r * 255), -1);
			}
			/*else if (fxy.x > 3 || fxy.y > 3) {
				line(image, Point(col, row), Point(cvRound(col + fxy.x), cvRound(row + fxy.y)), Scalar(0, 255, 0), 2, 8, 0);
				//circle(image, Point(col, row), 2, Scalar(0, 255, 0), -1);
			}*/

		}
	}
	
}

测试结果:

 


 

posted @ 2021-04-19 19:38  code_witness  阅读(206)  评论(0编辑  收藏  举报