如何检测位图中的红色像素



android中的getPixels()是上下左右读取像素,还是左右上下读取像素?基本上是按行还是按列读取。如果我想知道图片中哪个地方的红色值更高,我可以这样做吗(我假设它是按列读取的)

        Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
        imgTakenPhoto.setImageBitmap(thumbnail);
        int[] pixels = new int[thumbnail.getHeight()*thumbnail.getWidth()];
        thumbnail.getPixels( pixels, 0, thumbnail.getWidth(), 0, 0, thumbnail.getWidth(), thumbnail.getHeight());
        Colered[] color = new Colered[pixels.length];
        int length = pixels.length;
        int width = thumbnail.getWidth();
        int height = thumbnail.getHeight();
        for(int i=0; i<pixels.length;i++){
            color[i] = new Colered(getRed(pixels[i]),getBlue(pixels[i]),getGreen(pixels[i]));
            System.out.print(color[i].red + " ");
        }
        int indice=-1;
        int greatest = -1;
        for(int i=0;i<length-1;i++){
            if(color[i].red> greatest){
                greatest = color[i].red;
                indice = i;
            }

        } 
       public static int getRed(int color){
    return (color >> 16) & 0xFF;
   }

您的代码查找"最红"像素,即具有最高红色值的像素。我认为那不是你真正需要的,但如果我错了请纠正我。

你也把事情复杂化了。让我们从一个Bitmap和两个循环开始:

int redThreshold = 200; // adjust this to your needs
List<int[]> redPixels = new ArrayList<>(); // redPixels.get(int)[0] = x, redPixels.get(int)[1] = y
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
for(int x = 0; x  < thumbnail.getWidth(); x++) // x is row
    for(int y = 0; y < thumbnail.getHeight(); y++) // y is col
        if(Color.red(thumbnail.getPixel(x, y)) > redThreshold) {
            redPixels.add(new int[]{x, y});
            System.out.println(String.format("Pixel at (%d, %d) has a red value exceeding our threshold of %d!", x, y, redThreshold);
        }

正如@Eliseo在他的评论中暗示的那样,根据你的实际需要,你可能需要检查其他两种颜色是否也低于某个阈值,因为这将拾取白色(r=255,g=255,b=255是白色!)。

那么,我们如何寻找视觉红色呢?你和我看到都会同意的东西就是"红色"。我们要确保红色的值与绿色或蓝色的值有一个合适的比例;蓝色和绿色都在一个阈值之内,否则我们会捕捉到粉色和橙色。像这样:

int thresholdRatio = 2;
int threshold = 15;
List<int[]> redPixels = new ArrayList<>();
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
for(int x = 0; x < thumbnail.getWidth(); x++)
    for(int y = 0; y < thumbnail.getHeight(); y++) {
        Color color = thumbnail.getPixel(x, y);
        int r = Color.red(color);
        int g = Color.green(color);
        int b = Color.blue(color);
        if((r > (Math.max(g, b) * thresholdRatio)) && (Math.abs(g - b) < threshold)) {
            redPixels.add(new int[]{x, y});
            System.out.println(String.format("Pixel at (%d, %d) has a red value more than %d times the max(green, blue) value, and the green and blue value are also within %d points!", x, y, thresholdRatio, threshold);
       }
    }

这将捕捉非常浅和非常深的红色阴影。如果您需要捕捉非常特定的红色色调,可以添加天花板和地板阈值。

想要可视化哪些像素被捕获?如果位图是可变的,则可以。

Random rand = new Random();
Color getRandomColor() {
    int[] rgb = new int[3];
    for(int i = 0; i < rgb.length; i++) {
        rgb[i] = rand.nextInt(256);
    }
    return Color.rgb(rgb[0], rgb[1], rgb[2]);
}
boolean transformRedPixels(Bitmap bm, List<int[]> redPixels) {
    for(int[] coords : redPixels) {
        bm.setPixel(coords[0], coords[1], getRandomColor()); // This will set each pixel caught to a new random color
    }
    return bm.isMutable();
}

让我知道这是否符合你的需要。快乐编码:)

最新更新