Python 多点椭球方程
我有大量的像素颜色(96000种不同的颜色): 我想得到某种数学定义的概率区域,如: 我现在看到的主要障碍是——谷歌上的所有方法都主要是关于可视化和二维空间,但没有一种算法可以找到方程的系数,比如: a1x2+b1y2+c1y2+a2xy+b2xz+c2yz+a3x+b3y+c3z=0 对于我来说,用python实现它太难了( 无论如何,我只想确定某个像素是否或多或少位于我的底色中 我尝试使用scikit集群实现它,但由于只有一个集群,所以失败了 可能是一组数据。创建一个数组2563个元素 表示每个像素颜色似乎是错误的 我想知道是否有一种简单的方法来确定这个点簇的边界? 或者,也许我只是想得太多了,有点像OpenCVPython 多点椭球方程,python,algorithm,scipy,Python,Algorithm,Scipy,我有大量的像素颜色(96000种不同的颜色): 我想得到某种数学定义的概率区域,如: 我现在看到的主要障碍是——谷歌上的所有方法都主要是关于可视化和二维空间,但没有一种算法可以找到方程的系数,比如: a1x2+b1y2+c1y2+a2xy+b2xz+c2yz+a3x+b3y+c3z=0 对于我来说,用python实现它太难了( 无论如何,我只想确定某个像素是否或多或少位于我的底色中 我尝试使用scikit集群实现它,但由于只有一个集群,所以失败了 可能是一组数据。创建一个数组2563个元素
cv2.inRange()函数?这可以通过椭球多项式的优化和拟合来解决。但是,我将从几何方法开始,它要快得多:
p0 = sum (p[i]) / n // average
i = { 0,1,2,3,...,n-1 } // of all points
如果点密度不均匀,则使用边界框中心更安全。因此,找到xmin,ymin,zmin,xmax,ymax,zmax
,它们之间的中间就是你的中心pa = p[j];
|p[j]-p0| >= |p[i]-p0| // max
i = { 0,1,2,3,...,n-1 } // of all points
pa-p0
垂直于其他半轴所在的平面。因此,找到距离该平面p0
最远的点:
pb = p[j];
|p[j]-p0| >= |p[i]-p0| // max
dot(pa-p0,p[j]-p0) == 0 // but inly if inside plane
i = { 0,1,2,3,...,n-1 } // from all points
请注意,点积的结果可能不是精确的零,因此最好针对以下内容进行测试:
|dot(pa-p0,p[j]-p0)| <= 1e-3
FinalRadius := 0
for i := 0 to Amount:
vecRadius := (3DPoints[i] - vecFoci1) + (3DPoints[i] - vecFoci2)
FinalRadius := Max(FinalRadius, Length(vecRadius))
因此,找到这样一个点:
pc = p[j];
|p[j]-p0| >= |p[i]-p0| // max
dot(pa-p0,p[j]-p0) == 0 // but inly if inside plane
dot(pb-p0,p[j]-p0) == 0 // and perpendicular also to b semi-axis
i = { 0,1,2,3,...,n-1 } // from all points
(pa-p0),(pb-p0),(pc-p0)
是椭球体的基向量(可以使用叉积使其垂直)。它们的大小为半径。p0
为中心。也可以使用此参数方程:
a=pa-p0;
b=pb-p0;
c=pc-p0;
p(u,v) = p0 + a*cos(u)*cos(v)
+ b*cos(u)*sin(v)
+ c*sin(u);
u = < -0.5*PI , +0.5*PI >
v = < 0.0 , 2.0*PI >
a=pa-p0;
b=pb-p0;
c=pc-p0;
p(u,v)=p0+a*cos(u)*cos(v)
+b*cos(u)*sin(v)
+c*sin(u);
u=<-0.5*PI,+0.5*PI>
v=<0.0,2.0*PI>
O(n)
,其结果可作为优化和拟合的起点,以在不损失精度的情况下加速优化和拟合。如果要进一步提高精度,请参阅:
这基本上与您的任务相似,但仅在2D中可能会给您带来一些想法。有一种方法可以找到仅基于两个焦点的非完美对称椭球体。 也许这对获得大量分数有好处。 至少,它非常简单(基于某种随机搜索):
查看3个变量。特征向量将给出椭圆的主轴。与您尝试做的事情类似的常见事情称为“主成分分析”。从三维数据生成3个正交向量(主成分)这总结了数据在各个方向上的变化。它们是一个椭圆的轴,看起来像上面的那个。@samgak,MattTimmermans,工作几乎完美无瑕。我只是没能在绘图上画出这些特征向量,但它们似乎是正确的:哦,我从来没想过可以很容易地绕一个椭球(和O(n))!但似乎我有一些离群数据,纯几何方法不会返回想要的结果。也许近似搜索会帮助我,但我不确定是否能够实现它。:)但你的第五段真的很精彩!我将使用从PCA获得的这些特征向量,然后围绕p0构建一个椭球。即使存在旋转,也不难检查椭球内是否存在其他像素。非常感谢!)我的数学真的很差…@Xobotun你可以稍微改变一下搜索公式,使之更符合你的需要。您没有指定椭球体的确切属性,所以我只展示了几何方法。例如,如果希望椭球体覆盖75%的点,可以将所有点转换为找到的椭球体的坐标系,然后重新缩放为立方体。然后缩小bbox,直到它只覆盖75%的点,重新缩放并重新计算a、b、c大小。。。您可以做任何事情(添加方程式、更改点积阈值角度等…)@Xobotun当你提到颜色时,这意味着你正在做一些基于概率的颜色量化,还有其他的方法,例如,请看:但由于我没有关于你的问题的背景信息,我可能是在错误的方向上假设…我想StackOverflow最好能更详细地问我的问题抽象术语多于具体术语。我提出这个问题的原因是为了提取看起来像我皮肤的像素:我们大学的科学顾问(简单地说是老师)让我们中的一些人完成了一项任务,通过过滤给定的图像来加速Viola-Jones人脸检测算法。当我告诉他过滤看起来像皮肤的区域的想法时,他说:“嗯,可能有用。”。现在我正试图发展这个想法,并测量检测人脸所需的时间。@Xobotun不是该领域的专家,但我的直觉告诉我HSV颜色空间比RGB更好。此外,在HSV中,您可以部分忽略V值,从而使您的问题成为2D而不是3D,请参阅以获取一些想法。
3DPoints - Array of some Amount of points
vecCenter - average of 3DPoints
AngleCosine - cos of angle between two vectors
RandomOrder(3DPoints)
vecFocus := (0, 0, 0)
for i := 0 to Amount:
vecRadius := 3DPoints[i] - vecCenter
// Change vecRadius direction to parallel if it's not
if AngleCosine(vecFocus, vecRadius) < 0 then
vecRadius *= -1
vecFocus += (vecRadius - vecFocus) / Amount
FinalRadius := 0
for i := 0 to Amount:
vecRadius := (3DPoints[i] - vecFoci1) + (3DPoints[i] - vecFoci2)
FinalRadius := Max(FinalRadius, Length(vecRadius))