Graphics 计算任意像素图形的边界框

Graphics 计算任意像素图形的边界框,graphics,pixels,bounding-box,aabb,Graphics,Pixels,Bounding Box,Aabb,给定任意像素的连续绘图(例如,在HTML5画布上),是否有比简单地查找轴对齐边界框更有效的算法?您可能能够使用某种二进制搜索,或者在粗网格上采样,然后在更细的网格上采样。此方法的正确性取决于您的图形中是否允许“孔”。只需从左上到右和向下扫描线即可获得y top,其余部分则采用不同方向的类似算法 由Phrogz编辑: 这是一个伪代码实现。包括的优化可确保每个扫描线不会看到先前扫描覆盖的像素: 函数边界框() w=getWidth()#假设图形地址从[0,w]开始 h=getHeight()#假设

给定任意像素的连续绘图(例如,在HTML5画布上),是否有比简单地查找轴对齐边界框更有效的算法?

您可能能够使用某种二进制搜索,或者在粗网格上采样,然后在更细的网格上采样。此方法的正确性取决于您的图形中是否允许“孔”。

只需从左上到右和向下扫描线即可获得y top,其余部分则采用不同方向的类似算法


由Phrogz编辑:

这是一个伪代码实现。包括的优化可确保每个扫描线不会看到先前扫描覆盖的像素:

函数边界框()
w=getWidth()#假设图形地址从[0,w]开始
h=getHeight()#假设图形地址从[0,h]开始
对于y=h-1到0乘以-1#从最后一行向上迭代
对于x=w-1到0乘以-1,迭代整个行
如果pxAt(x,y),那么
maxY=y
断开两个循环
如果maxY==未定义,则#没有像素,没有边界框
返回
对于x=w-1到0乘以-1#从最后一列迭代到第一列
对于y=0到maxY#沿列向下迭代到maxY
如果pxAt(x,y),那么
maxX=x
断开两个循环
对于x=0到maxX#从第一列迭代到maxX
对于y=0到maxY#沿列向下迭代到maxY
如果pxAt(x,y),那么
minX=x
断开两个循环
对于y=0到maxY#向下迭代行,直到maxY
对于x=0到maxX#迭代行,直到maxX
如果pxAt(x,y),那么
minY=y
断开两个循环
返回minX,minY,maxX,maxY
结果(在实践中)与单一像素的暴力算法的性能大致相同,并且随着对象变大,效果会显著提高

演示: 为了好玩,下面是该算法工作原理的可视化表示:






无论你选择以什么顺序做边,你只需要确保你考虑到之前的结果,这样你就不会重复扫描边角。

我不喜欢当前的答案。这是我插入OP网站的代码。在firefox和chrome中速度更快

想法是检查x轴上的所有像素,看看Y轴上是否有点击。如果有,更新Y并增加x,这样我们就可以扫描最大x

function contextBoundingBox(ctx,alphaThreshold){
    if (alphaThreshold===undefined) alphaThreshold = 15;
    var w=ctx.canvas.width,h=ctx.canvas.height;
    var data = ctx.getImageData(0,0,w,h).data;

    let minX=w;
    let maxX=0
    let minY=h
    let maxY=0
    for(let y=0; y<h; y++)
    {
        for(let x=0; x<w; x++)
        {
            if (data[y*w*4 + x*4+3])
            {
                minX = Math.min(minX, x);
                maxX = Math.max(maxX, x);
                minY = Math.min(minY, y);
                maxY = y;
                x=maxX
            }
        }
    }

    return {x:minX,y:minY,maxX:maxX,maxY:maxY,w:maxX-minX,h:maxY-minY};
}
函数contextBoundingBox(ctx,alphaThreshold){
如果(alphaThreshold==未定义)alphaThreshold=15;
var w=ctx.canvas.width,h=ctx.canvas.height;
var data=ctx.getImageData(0,0,w,h).data;
设minX=w;
设maxX=0
设minY=h
设maxY=0

对于(假设y=0;如果图形有任何凹边界部分,二进制搜索很容易失败。这是否回答了您的问题?