如果你不想做额外的面具,你必须实现布尔函数,如果在椭圆形(与一般的椭圆式用法):
https://math.stackexchange.com/a/434482/
然后你可以彩色像素只有满足该等式。下面我附C++例子(我应该很容易将其转换为蟒蛇):
bool ifInEllipse(cv::Size _axes, float _angle, cv::Point _center, cv::Point _point)
{
_angle =CV_PI/180*_angle;
float cosine = cos(_angle);
float sine = sin(_angle);
float res1 = (_point.x - _center.x)*cosine + (_point.y - _center.y)*sine;
res1 = res1*res1;
float res2 = (_point.x - _center.x)*sine - (_point.y - _center.y)*cosine;
res2 = res2*res2;
float a = _axes.width;
float b = _axes.height;
return ((res1/(a*a)) + (res2/(b*b))) < 1;
}
与实施例一用法:
cv::Mat A1,A2, B1,B2, AA,BB;
A1 = cv::Mat::zeros(500, 500, CV_8UC1);
A2 = cv::Mat::zeros(500, 500, CV_8UC1);
cv::Point center1(200, 200);
cv::Size axes1(100, 50);
float angle1 =30;
cv::ellipse(A1, center1, axes1, angle1, 0, 360,cv::Scalar(255,255,255),-1);
B1 = cv::Mat::zeros(500, 500, CV_8UC1);
B2 = cv::Mat::zeros(500, 500, CV_8UC1);
for(int i=0;i<500;i++)
{
for(int j=0;j<500;j++)
{
if(ifInEllipse(axes1,angle1,center1,cv::Point(i,j)))
{
B1.at<uchar>(j, i) = 255;
}
}
}
cv::Point center2(350, 300);
cv::Size axes2(60, 120);
float angle2 = -45;
cv::ellipse(A2, center2, axes2, angle2, 0, 360, cv::Scalar(255, 255, 255), -1);
B2 = cv::Mat::zeros(500, 500, CV_8UC1);
for (int i = 0; i<500; i++)
{
for (int j = 0; j<500; j++)
{
if (ifInEllipse(axes2, angle2, center2, cv::Point(i, j)))
{
B2.at<uchar>(j, i) = 255;
}
}
}
AA = cv::Mat::zeros(500, 500, CV_8UC1);
BB = cv::Mat::zeros(500, 500, CV_8UC1);
cv::bitwise_and(A1, A2,AA);
for (int i = 0; i<500; i++)
{
for (int j = 0; j<500; j++)
{
if (ifInEllipse(axes1, angle1, center1, cv::Point(i, j)))
{
if (ifInEllipse(axes2, angle2, center2, cv::Point(i, j)))
{
BB.at<uchar>(j, i) = 255;
}
}
}
}
结果:
我真的不看你如何能做得比你的计划更快。我唯一能想到的是,你不需要计算整个图像上的掩码,而只需要在椭圆被绑定的矩形中......而且我会用布尔掩码/逻辑去使用,而不是使用0, 1,2值。 – Julien
你应该使用该方法,但是如果你想要,你可以重载'__and__'和'__or__'运算符,所以你可以使用'&'和'|' – 0TTT0
@ 0TTT0'&'和'|'已经适用于布尔口罩... – Julien