java - 如何从图像中删除宽度未知的边框

标签 java android image-processing

我正在尝试构建一个可以从图像中删除单色边框的程序。

边框始终为白色,但左右边框的宽度可能与上下边框的宽度不同。所以我要提取的图像位于源图像的中心。

所以我想从下图中提取绿色矩形。

enter image description here

目前我不知道如何开始解决这个问题。

更新

所以最终 calsign 的代码 fragment 和一些改进解决了我的问题。我意识到内部图像周围的边框可能不是完全单一的颜色,而是会略有不同。这会导致某些图像留下小边框的行为。

我通过用一个阈值比较两种颜色的颜色距离来改进两个像素颜色的比较,从而解决了这个问题。当距离低于阈值时,颜色将被同等处理。

public Bitmap cropBorderFromBitmap(Bitmap bmp) {
            //Convenience variables
    int width = bmp.getWidth();
    int height = bmp.getHeight();

    int[] pixels = new int[height * width];

    //Load the pixel data into the pixels array
    bmp.getPixels(pixels, 0, width, 0, 0, width, height);

    int length = pixels.length;

    int borderColor = pixels[0];

    //Locate the start of the border
    int borderStart = 0;
    for(int i = 0; i < length; i ++) {

        // 1. Compare the color of two pixels whether they differ
        // 2. Check whether the difference is significant    
        if(pixels[i] != borderColor && !sameColor(borderColor, pixels[i])) {
            Log.i(TAG,"Current Color: " + pixels[i]);                   
            borderStart = i;
            break;
        }
    }

    //Locate the end of the border
    int borderEnd = 0;
    for(int i = length - 1; i >= 0; i --) {
        if(pixels[i] != borderColor && !sameColor(borderColor, pixels[i])) {
            Log.i(TAG,"Current Color: " + pixels[i]);
            borderEnd = length - i;
            break;
        }
    }

    //Calculate the margins
    int leftMargin = borderStart % width;
    int rightMargin = borderEnd % width;
    int topMargin = borderStart / width;
    int bottomMargin = borderEnd / width;

    //Create the new, cropped version of the Bitmap
    bmp = Bitmap.createBitmap(bmp, leftMargin, topMargin, width - leftMargin - rightMargin, height - topMargin - bottomMargin);
    return bmp;
}

private boolean sameColor(int color1, int color2){
    // Split colors into RGB values
    long r1 = (color1)&0xFF;
    long g1 = (color1 >>8)&0xFF;
    long b1 = (color1 >>16)&0xFF;

    long r2 = (color2)&0xFF;
    long g2 = (color2 >>8)&0xFF;
    long b2 = (color2 >>16)&0xFF;

    long dist = (r2 - r1) * (r2 - r1) + (g2 - g1) * (g2 - g1) + (b2 - b1) *(b2 - b1);

    // Check vs. threshold 
    return dist < 200;
}

最佳答案

也许不是使用 API 寻找解决方案的最佳方法,而是想到的方法:直接修改图像的像素。

您可以使用getPixels() 获取位图 的像素|然后用 createBitmap() 创建一个新的、裁剪过的 Bitmap .然后,这只是找到边界尺寸的问题。

您可以通过访问位于位置 0 的像素找到边框的颜色,然后将该值(int)与每个后续像素的值进行比较直到你到达边界(不是那种颜色的像素)。只需一点数学知识,就可以做到。

下面是一些演示这一点的简单代码:

private void cropBorderFromBitmap(Bitmap bmp) {
    int[] pixels;
    //Load the pixel data into the pixels array
    bmp.getPixels(pixels, 0, width, 0, 0, width, height);

    //Convenience variables
    int width = bmp.getWidth();
    int height = bmp.getHeight();
    int length = pixels.length;

    int borderColor = pixels[0];

    //Locate the start of the border
    int borderStart;
    for(int i = 0; i < length; i ++) {
        if(pixels[i] != borderColor) {
            borderStart = i;
            break;
        }
    }

    //Locate the end of the border
    int borderEnd;
    for(int i = length - 1; i >= 0; i --) {
        if(pixels[i] != borderColor) {
            borderEnd = length - i;
            break;
        }
    }

    //Calculate the margins
    int leftMargin = borderStart % width;
    int rightMargin = borderEnd % width;
    int topMargin = borderStart / width;
    int bottomMargin = borderEnd / width;

    //Create the new, cropped version of the Bitmap
    bmp = createBitmap(bmp, leftMargin, topMargin, width - leftMargin - rightMargin, height - topMargin - bottomMargin);
}

这是未经测试的并且缺乏错误检查(例如,如果宽度为 0 怎么办?),但它应该作为概念验证。

编辑:我刚刚意识到我未能完成 getPixels() 方法。测试您的代码的奇迹……它现在已修复。

关于java - 如何从图像中删除宽度未知的边框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12253739/

相关文章:

android - 如何在Android国际象棋游戏中制作动画

java - cvHaarDetectObjects() 方法有什么作用?

java - 如何点击购物车页面中的更新按钮 - Url ="http://live.guru99.com/"

java - 使用 UnicastReceivingChannelAdapter 进行 UDP 处理以创建发布-订阅 channel

android - 建筑时的gradle版本APK

android - 深层链接空字符串参数

java - 如何创建由 jmx 公开并通过 jconsole 访问的性能计数器?

java - 附加到 Java 进程时 gdb 挂起

python - 在CNN代码中添加图像增强功能以​​提高准确性

python-3.x - 数字化热图并将像素映射到值