我通过协方差矩阵生成了连通分量区域的椭圆:
//initialize distribution of points
int num = blob.size();
float arr[num][2];
for(int i=0; i<num; i++)
{
arr[i][1] = blob[i].first; //row index, y
arr[i][0] = blob[i].second; //column index, x
}
//calculate covariance matrix
cv::Mat mat = cv::Mat(num, 2, CV_32FC1, &arr);
cv::Mat cov, mean;
cv::calcCovarMatrix( mat, cov, mean, CV_COVAR_NORMAL | CV_COVAR_ROWS);
cov = cov / (mat.rows - 1);
//calculate eigen problem
cv::Mat eigVec = cv::Mat(2, 2, CV_32FC1);
cv::Mat eigVal = cv::Mat(1, 2, CV_32FC1);
cv::eigen( cov, eigVal, eigVec);
// cout << eigVec << endl;
//calculate the major and minor axes
float alpha = sqrt( eigVal.at<double>(0,0) ) * sqrt(chisquare_val);
float beta = sqrt( eigVal.at<double>(0,1) ) * sqrt(chisquare_val);
//calcualte the angle.
double angle = atan2( eigVec.at<double>(0,1), eigVec.at<double>(0,0) ) * 180 / M_PI;
return cv::RotatedRect( cv::Point2f(mean.at<double>(0,0), mean.at<double>(0,1)),
cv::Size2f(alpha, beta), angle);
现在,我需要通过以下公式计算每个像素到椭圆的距离:
X = cos(θ)(x-xc)+ sin(θ)(y-yc)
Y = -sin(θ)(x-xc)+ cos(θ)(y-yc)
dist =(X /α)^ 2 +(Y /β)^ 2
其中θ是旋转角度,xc,yc是中心坐标, α是半长轴(始终是最大轴),β是半短轴
这是我的实施:
double distance(cv::RotatedRect &ellipse, cv::Point &point)
{
double center_x = ellipse.center.x;
double center_y = ellipse.center.y;
double alpha = ellipse.size.width / 2; //semi-major axes
double beta = ellipse.size.height / 2; //semi-minor axes
double angle = ellipse.angle; //rotation angle
double p_x = point.x;
double p_y = point.y;
double new_x = (p_x - center_x) * cos(angle) + (p_y - center_y) * sin(angle);
double new_y = (p_x - center_x) * (-sin(angle)) + (p_y - center_y) * cos(angle);
double result = (pow(new_x, 2.0) / pow(alpha, 2.0)) + (pow( new_y, 2.0) / pow(beta, 2.0));
return result;
}
我用图像测试了这段代码。它适用于水平椭圆,如: the grey area covers the points that within the ellipse
但代码在垂直椭圆上失败,输出如下:the gray area should cover the ellipse perfectly
那么,有人可以告诉我问题是什么以及为什么用垂直椭圆计算距离失败了?