opencv4 cpp曲面拟合填补之最小二乘法拟合三次曲面(含代码)

void surfaceFitting3(IN cv::Mat mask, IN cv::Mat height, OUT cv::Mat & factor) const
{
	if (!(mask.depth() == CV_8UC1 && height.depth() == CV_16SC1))return;
	Mat left_hand = Mat::zeros(Size(10, 10), CV_64FC1);
	Mat right_hand = Mat::zeros(Size(1, 10), CV_64FC1);
	short z;
	for (int i = 0;i < mask.rows;++i) {
		for (int j = 0;j < mask.cols;++j) {
			if (mask.ptr<uchar>(i)[j] == 255) {
				z = height.ptr<short>(i)[j];
				left_hand.ptr<double>(0)[0] += pow(i, 6);
				left_hand.ptr<double>(1)[0] = left_hand.ptr<double>(0)[1] += pow(i, 3)*pow(j, 3);
				left_hand.ptr<double>(2)[0] = left_hand.ptr<double>(0)[2] += pow(i, 5)*j;
				left_hand.ptr<double>(3)[0] = left_hand.ptr<double>(0)[3] += pow(i, 4)*pow(j, 2);
				left_hand.ptr<double>(4)[0] = left_hand.ptr<double>(0)[4] += pow(i, 5);
				left_hand.ptr<double>(5)[0] = left_hand.ptr<double>(0)[5] += pow(i, 3)*pow(j, 2);
				left_hand.ptr<double>(6)[0] = left_hand.ptr<double>(0)[6] += pow(i, 4)*j;
				left_hand.ptr<double>(7)[0] = left_hand.ptr<double>(0)[7] += pow(i, 4);
				left_hand.ptr<double>(8)[0] = left_hand.ptr<double>(0)[8] += pow(i, 3)*j;
				left_hand.ptr<double>(9)[0] = left_hand.ptr<double>(0)[9] += pow(i, 3);
				left_hand.ptr<double>(1)[1] += pow(j, 6);
				left_hand.ptr<double>(2)[1] = left_hand.ptr<double>(1)[2] += pow(i, 2)*pow(j, 4);
				left_hand.ptr<double>(3)[1] = left_hand.ptr<double>(1)[3] += i*pow(j, 5);
				left_hand.ptr<double>(4)[1] = left_hand.ptr<double>(1)[4] += pow(i, 2)*pow(j, 3);
				left_hand.ptr<double>(5)[1] = left_hand.ptr<double>(1)[5] += pow(j, 5);
				left_hand.ptr<double>(6)[1] = left_hand.ptr<double>(1)[6] += i*pow(j, 4);
				left_hand.ptr<double>(7)[1] = left_hand.ptr<double>(1)[7] += i*pow(j, 3);
				left_hand.ptr<double>(8)[1] = left_hand.ptr<double>(1)[8] += pow(j, 4);
				left_hand.ptr<double>(9)[1] = left_hand.ptr<double>(1)[9] += pow(j, 3);
				left_hand.ptr<double>(2)[2] += pow(i, 4)*pow(j, 2);
				left_hand.ptr<double>(3)[2] = left_hand.ptr<double>(2)[3] += pow(i, 3)*pow(j, 3);
				left_hand.ptr<double>(4)[2] = left_hand.ptr<double>(2)[4] += pow(i, 4)*j;
				left_hand.ptr<double>(5)[2] = left_hand.ptr<double>(2)[5] += pow(i, 2)*pow(j, 3);
				left_hand.ptr<double>(6)[2] = left_hand.ptr<double>(2)[6] += pow(i, 3)*pow(j, 2);
				left_hand.ptr<double>(7)[2] = left_hand.ptr<double>(2)[7] += pow(i, 3)*j;
				left_hand.ptr<double>(8)[2] = left_hand.ptr<double>(2)[8] += pow(i, 2)*pow(j, 2);
				left_hand.ptr<double>(9)[2] = left_hand.ptr<double>(2)[9] += pow(i, 2)*j;
				left_hand.ptr<double>(3)[3] += pow(i, 2)*pow(j, 4);
				left_hand.ptr<double>(4)[3] = left_hand.ptr<double>(3)[4] += pow(i, 3)*pow(j, 2);
				left_hand.ptr<double>(5)[3] = left_hand.ptr<double>(3)[5] += i*pow(j, 4);
				left_hand.ptr<double>(6)[3] = left_hand.ptr<double>(3)[6] += pow(i, 2)*pow(j, 3);
				left_hand.ptr<double>(7)[3] = left_hand.ptr<double>(3)[7] += pow(i, 2)*pow(j, 2);
				left_hand.ptr<double>(8)[3] = left_hand.ptr<double>(3)[8] += i*pow(j, 3);
				left_hand.ptr<double>(9)[3] = left_hand.ptr<double>(3)[9] += i*pow(j, 2);
				left_hand.ptr<double>(4)[4] += pow(i, 4);
				left_hand.ptr<double>(5)[4] = left_hand.ptr<double>(4)[5] += pow(i, 2)*pow(j, 2);
				left_hand.ptr<double>(6)[4] = left_hand.ptr<double>(4)[6] += pow(i, 3)*j;
				left_hand.ptr<double>(7)[4] = left_hand.ptr<double>(4)[7] += pow(i, 3);
				left_hand.ptr<double>(8)[4] = left_hand.ptr<double>(4)[8] += pow(i, 2)*j;
				left_hand.ptr<double>(9)[4] = left_hand.ptr<double>(4)[9] += pow(i, 2);
				left_hand.ptr<double>(5)[5] += pow(j, 4);
				left_hand.ptr<double>(6)[5] = left_hand.ptr<double>(5)[6] += i*pow(j, 3);
				left_hand.ptr<double>(7)[5] = left_hand.ptr<double>(5)[7] += i*pow(j, 2);
				left_hand.ptr<double>(8)[5] = left_hand.ptr<double>(5)[8] += pow(j, 3);
				left_hand.ptr<double>(9)[5] = left_hand.ptr<double>(5)[9] += pow(j, 2);
				left_hand.ptr<double>(6)[6] += pow(i, 2)*pow(j, 2);
				left_hand.ptr<double>(7)[6] = left_hand.ptr<double>(6)[7] += pow(i, 2)*j;
				left_hand.ptr<double>(8)[6] = left_hand.ptr<double>(6)[8] += i*pow(j, 2);
				left_hand.ptr<double>(9)[6] = left_hand.ptr<double>(6)[9] += i*j;
				left_hand.ptr<double>(7)[7] += pow(i, 2);
				left_hand.ptr<double>(8)[7] = left_hand.ptr<double>(7)[8] += i*j;
				left_hand.ptr<double>(9)[7] = left_hand.ptr<double>(7)[9] += i;
				left_hand.ptr<double>(8)[8] += pow(j, 2);
				left_hand.ptr<double>(9)[8] = left_hand.ptr<double>(8)[9] += j;
				left_hand.ptr<double>(9)[9] += 1;
				right_hand.ptr<double>(0)[0] += pow(i, 3)*z;
				right_hand.ptr<double>(1)[0] += pow(j, 3)*z;
				right_hand.ptr<double>(2)[0] += pow(i, 2)*j*z;
				right_hand.ptr<double>(3)[0] += i*pow(j, 2)*z;
				right_hand.ptr<double>(4)[0] += pow(i, 2)*z;
				right_hand.ptr<double>(5)[0] += pow(j, 2)*z;
				right_hand.ptr<double>(6)[0] += i*j*z;
				right_hand.ptr<double>(7)[0] += i*z;
				right_hand.ptr<double>(8)[0] += j*z;
				right_hand.ptr<double>(9)[0] += z;
			}
		}
	}
	solve(left_hand, right_hand, factor);
}

#define DEF_DGM_I(x,y,a,b,c,d,e,f,g,h,i,j) a*x*x*x+b*y*y*y+c*x*x*y+d*x*y*y+e*x*x+f*y*y+g*x*y+h*x+i*y+j;
void mendSurface3(IN cv::Mat mask, IN cv::Mat factor, OUT cv::Mat & height) const
{
	if (!(mask.depth() == CV_8UC1 && factor.depth() == CV_64FC1 && height.depth() == CV_16SC1
		&& factor.size() == Size(1, 10) && mask.size() == height.size()))return;
	double a = factor.ptr<double>(0)[0], b = factor.ptr<double>(1)[0],
		c = factor.ptr<double>(2)[0], d = factor.ptr<double>(3)[0],
		e = factor.ptr<double>(4)[0], f = factor.ptr<double>(5)[0],
		g = factor.ptr<double>(6)[0], h = factor.ptr<double>(7)[0],
		i = factor.ptr<double>(8)[0], j = factor.ptr<double>(9)[0];
	for (int _row = 0;_row < mask.rows;++_row) {
		for (int _col = 0;_col < mask.cols;++_col) {
			if (mask.ptr<uchar>(_row)[_col] == 255) {
				double hT = DEF_DGM_I(_row, _col, a, b, c, d, e, f, g, h, i, j);
				height.ptr<short>(_row)[_col] = static_cast<short>(hT);
			}
		}
	}
}
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenCV中提供了函数fitLine()来实现最小二乘法拟合直线。 使用方法如下: 1. 导入必要的库和模块: ```python import cv2 import numpy as np ``` 2. 准备数据: 我们需要提供一些点的坐标,用于拟合直线。这些点可以是图像中的像素点,也可以是其他任意坐标系中的点。 ```python # 生成一些随机点 points = np.random.randint(0, 200, (10, 2)) ``` 3. 拟合直线: 使用fitLine()函数来拟合直线,该函数需要传入一些参数: - points:需要拟合的点的坐标。 - distType:点到直线的距离类型,可以选择CV_DIST_L1, CV_DIST_L2或CV_DIST_L12。 - param:累加器分辨率与rho的比值,一般取值为1。 - reps:在一条直线上的最小点数,一般取值为0。 - aeps:角度的最小精度,一般取值为0.01度。 ```python # 使用fitLine()函数拟合直线 vx, vy, x, y = cv2.fitLine(points, cv2.DIST_L2, 0, 0.01, 0.01) ``` 4. 绘制直线: 得到直线的参数后,我们可以使用这些参数来绘制直线。可以使用cv2.line()函数来实现。 ```python # 绘制直线 lefty = int((-x*vy/vx) + y) righty = int(((200-x)*vy/vx)+y) cv2.line(img, (199,righty), (0,lefty), (0,255,0), 2) ``` 完整代码如下: ```python import cv2 import numpy as np # 生成一些随机点 points = np.random.randint(0, 200, (10, 2)) # 使用fitLine()函数拟合直线 vx, vy, x, y = cv2.fitLine(points, cv2.DIST_L2, 0, 0.01, 0.01) # 绘制直线 img = np.zeros((200, 200, 3), dtype=np.uint8) lefty = int((-x*vy/vx) + y) righty = int(((200-x)*vy/vx)+y) cv2.line(img, (199,righty), (0,lefty), (0,255,0), 2) cv2.imshow("Fit Line", img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 运行结果如下图所示: ![拟合直线结果](https://img-blog.csdnimg.cn/20210622152054570.png)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值