最小二乘直线拟合opencv动态显示

最小二乘直线拟合opencv动态显示_第1张图片

#include 
#include 


/*
函数功能:创建随机散点,x以固定步长step递增,y则随机动态分布
输入@img:原始彩图
输入@w:图宽
输入@h:图高
输入@step:步长
输入@min:生成随机数的最小值
输入@max:生成随机数的最大值
返回:生成的所有散点
备注:2020.4.18
*/
std::vector createRandPoints(cv::Mat& img, int w, int h, double k, int step, int min, int max)
{
	img = cv::Mat::zeros(h, w, CV_8UC3);
	std::vector points;
	k = -(double)img.rows / img.cols;
	//k = - k / 20;
	//srand(0);
	//int a = -20, b = 20;
	for (int i = 0; i < img.cols; i += step)
	{
		cv::Point p;
		p.x = i;
		p.y = k * p.x + img.rows - rand() % (max - min) + min;
		if (p.y > 0 && p.y < img.rows)
		{
			points.push_back(p);
			cv::circle(img, p, 2, cv::Scalar(0, 0, 255), -1);
		}
	}

	return points;
}

/*
函数功能:最小二乘直线拟合--计算a,b参数,直线方程为:y=ax+b
输入@points:所有散点
输出@a,b:直线方程参数
备注:2020.4.18
*/
void leaseSquares(std::vector points, double &a, double &b)
{
	//double a = 0, b = 0;
	double x1 = 0, x2 = 0;
	double y1 = 0, y2 = 0;
	int n = points.size();
	for (int i = 0; i < n; i++)
	{
		
		x1 += points[i].x;
		y1 += points[i].y;
		x2 += pow(points[i].x, 2);
		y2 += points[i].x * points[i].y;

	}

	a = (double)(n * y2 - x1 * y1) / (n * x2 - x1 * x1);
	b = (double)(x2 * y1 - x1 * y2) / (n * x2 - x1 * x1);
	
}

/*
函数功能:显示拟合直线结果
输入@img:图像
输入@a,b:直线方程参数
备注:2020.4.18
*/
void showLineFitting(cv::Mat& img, double a, double b)
{
	cv::Point p1, p2;
	p1.x = 0;
	p1.y = b;
	p2.x = img.cols;
	p2.y = a * p2.x + b;
	cv::line(img, p1, p2, cv::Scalar(0, 255, 0), 2);
}

void onTrackbarslide(int pos, void*)
{
	//std::cout << pos << std::endl;
	cv::Mat src;
	std::vector points = createRandPoints(src, 1280, 720, 0.5, 5, -10-pos, 10+pos);
	double a, b;
	leaseSquares(points, a, b);
	showLineFitting(src, a, b);

	cv::imshow("Line", src);
}

void main()
{
	//cv::Mat src;
	//std::vector points = createRandPoints(src, 1280, 720, 1, 5, -30, 30);
	//double a, b;
	//leaseSquares(points, a, b);
	//showLineFitting(src, a, b);

	cv::namedWindow("Line", cv::WINDOW_AUTOSIZE);
	int position = 0;
	cv::createTrackbar("Line", "Line", &position, 100, onTrackbarslide);

	//cv::imshow("Line", src);
	cv::waitKey(0);
	
	
}

 

 

 

你可能感兴趣的:(Opencv,图像处理)