2016/7/16
在一次提取发光管的中心线程序中,由于我们只拍到了断续而弯曲的发光管,所以无法使用光带中心线提取的方法进行提取。
在此背景下,我想到了拟合。之前有学过直线拟合的方法,名为最小二乘法。其基本步骤如下:
(1) 设需要拟合的直线为y=a*x+b。
(2) 首先选取进行拟合的点集,选取方法可以为阈值分割,模板匹配等,设最后选出的点集为。
(3) 求该点集到直线的距离平方和,
(4) 对Sum分别求关于x,y的偏导函数。
(5) 根据偏导求出该距离平方和最小时的a,b值即为拟合的曲线的参数。
为了与之后的二次曲线拟合做对比,我写了下直线拟合的函数,先从源图像中根据阈值分割选取拟合点集(这里我认为灰度值超过45即被选取),再根据上述步骤计算a,b的值。源代码如下:
/*输入为三通道图像*/
/*对图像中的亮点进行直线拟合*/
void cvLineFit1D(IplImage* src_getin)
{
IplImage*src =cvCloneImage(src_getin);
IplImage*image_threshold = cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,image_threshold,CV_BGR2GRAY);
cvThreshold(image_threshold,image_threshold,45,255,CV_THRESH_BINARY);
cvShowImage("cvLineFit1D[Threshold]",image_threshold);
//设拟合的二次曲线方程为y=ax+b;
//先求出各点到拟合直线上的距离的平方和;
//求出使得该平方和最小的a,b的值 ;
long long int k1=0;
long long int k2=0;
long long int k3=0;
long long int k4=0;
long long int k5=0;
long long int k6=0;
for (inti=0;i<image_threshold->height;i++)
{
for (intj=0;j<image_threshold->width;j++)
{
if(cvGetReal2D(image_threshold,i,j)==255)
{
k1+=2*i*i;
k2+=2*i;
k3+=2*i*j;