【问题标题】:Finding if a single rgb value falls within a threshold of any rgb value in an array - javascript查找单个 rgb 值是否落在数组中任何 rgb 值的阈值内 - javascript
【发布时间】:2021-02-25 03:06:22
【问题描述】:

对于创建一个函数以将单个 RGB 值与 RGB 值数组进行比较并确定它是否在阈值范围内,我将不胜感激。这是使用 HTML5 canvas 元素在 vanilla javascript 中完成的。

我的第一次尝试:

var colorArray = [  //rgb values to search through
[212, 35, 96],
[200, 200, 150],
[100, 100, 75]
];

var threshold = 15;   //the threshold

//Given a canvas with an image drawn on it
var pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height); // get the canvas pixel data

for(var row = 0; row < canvas.height; row++){   //stepping through the pixels

    for (var col = 0, index = 0, colorTotal = 0; col < canvas.width; col++){
        
        index = (col + (row * canvas.width)) * 4;
        colorTotal = pixelData.data[index] + pixelData.data[index + 1] + pixelData.data[index + 2];  //add the rgb values of the current pixel

        for(var i = 0, pixelColorTotal = 0, result = 0; i < colorArray.length; i++){   //stepping through the colorArray

            pixelColorTotal = colorArray[i] [0] + colorArray[i] [1] + colorArray[i] [2];  //add the rgb values of the current array element
            result = Math.abs(colorTotal - pixelColorTotal);  //find the difference between the color totals

            if(result < threshold){
               //..do something we've breached the threshold
            }
        }
    }
}

这效果不太好,因为例如:[255, 0, 50] 和 [50, 255, 0] 甚至不接近相同的颜色,但它们会超出阈值。

我的第二次尝试:

var colorArray = [  //rgb values to search through
[212, 35, 96],
[200, 200, 150],
[100, 100, 75]
];

var threshold = 15;   //the threshold

//Given a canvas with an image drawn on it
var pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height); // get the canvas pixel data

for(var row = 0; row < canvas.height; row++){   //stepping through the pixels

    for (var col = 0, index = 0; col < canvas.width; col++){
        
        index = (col + (row * canvas.width)) * 4;

        for(var i = 0, result = 0; i < colorArray.length; i++){   //stepping through the colorArray

            result = Math.abs(pixelData.data[index] - colorArray[i] [0]);   //load red difference
            if(result >= threshold){       //check the red channel to see if it exceeds threshold

                result = Math.abs(pixelData.data[index + 1] - colorArray[i] [1]);   //load green difference
                if(result >= threshold){       //check the green channel to see if it exceeds threshold

                     result = Math.abs(pixelData.data[index + 2] - colorArray[i] [2]);   //load blue difference
                     if(result >= threshold){       //check the green channel to see if it exceeds threshold

                         //do something we have passed all the threshold checks

                     }

                }
            }
        }
    }
}

这样更好,但效率很低。

有没有更好的想法?感谢阅读。

【问题讨论】:

    标签: javascript arrays canvas threshold


    【解决方案1】:

    我不是 100% 确定你想要什么,所以如果我走错了方向,请告诉我。

    function withinThreshold(colorArr, inputArr, threshold){
        let maxThreshold = threshold;
        let minThreshold = threshold * -1;
        for(var i = 0; i < colorArr.length; i++){
            let rDiff = colorArr[i][0] - inputArr[0];
            let gDiff = colorArr[i][1] - inputArr[1];
            let bDiff = colorArr[i][2] - inputArr[2];
            if(rDiff > minThreshold && rDiff < maxThreshold &&
               gDiff > minThreshold && gDiff < maxThreshold &&
               bDiff > minThreshold && gDiff < maxThreshold){
                 return i
            }
        }
        return -1
    }
    
    var colorArray = [  //rgb values to search through
        [212, 35, 96],
        [200, 200, 150],
        [100, 100, 75]
    ];
    var threshold = 15;
    
    for(var row = 0; row < canvas.height; row++){
        for (var col = 0; col < canvas.width; col++){
            let pixel = ctx.getImageData(row, col, 1, 1);
            let match = withinThreshold(colorArray, pixel, threshold);
            if(match === -1){
                console.log('no match found');
            }else{
                console.log('match found! index:',match);
            }
            // I made it like indexOf, it will return the matching index of colorArr.
            // You can simplify it like this:
            /*
                if(match > -1){
                    console.log('match found');
                }
            */
        }
    }
    

    也不要忘记 getImageData 很可能会返回 4 位数组 [r,g,b,a],除非您将设置更改为不允许 alpha。

    我也做了它,所以它单独抓取它需要的像素数据。这样,将来您可以将其细化到特定位置,而无需检查所有内容。只需将 rowcanvas.width 更改为 10 和 20。这样您就可以只保存更改区域的处理。您也可以使用 colcanvas.height 来进一步缩小它。

    我制作了一些画布渲染引擎,因此遇到了性能问题,不得不进行大量优化。

    【讨论】:

    • 我和你一样计算了差异。快多了。我认为我对 Math.abs 的使用减慢了它的速度。实际上,用户选择图像的活动区域。 colorArray 变量填充了该区域的突出颜色。 colorArray 不与图像本身进行比较,而是与处理图像的结果进行比较。在结果中,我使用 alpha 通道来标记像素是否会被进一步处理。我们在这里讨论的代码是我可以用来过滤第一级结果的方法之一。现在进行实验已经足够快了。感谢发帖
    • @lucyPa,有人回答了吗?
    猜你喜欢
    • 1970-01-01
    • 2022-06-22
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多