组合RGB二进制图像的问题

时间:2011-01-20 12:39:44

标签: java image-processing binary masking edge-detection

我正在进行边缘检测,它将检测每个RGB通道的边缘,然后将它们组合起来以将其显示为最终输出。我现在有一个问题,结合三个,因为它没有显示我二进制图像,而是它有一些颜色。我检查了RGB的每个二进制图像,它工作正常,给出了黑白图像。更清楚,以下是代码:

private void processActionPerformed(java.awt.event.ActionEvent evt) {                                        
        width = inputimage.getWidth(null);
        height = inputimage.getHeight(null);

        inputbuff = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

        Graphics r = inputbuff.getGraphics();
        r.drawImage(inputimage, 0, 0, null);
        r.dispose();

        process_red = new int[width * height];
        process_green = new int[width * height];
        process_blue = new int[width * height];
        process_grey = new int[width * height];
        process_rgb = new int[width * height];
        process_combine = new int[width * height];

        for (int i = 0; i < 256; i++) {
            freq_red[i] = freq_green[i] = freq_blue[i] = freq_grey[i] = 0;
        }

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                int clr = inputbuff.getRGB(y, x);

                int red = (clr & 0x00ff0000) >> 16;
                int green = (clr & 0x0000ff00) >> 8;
                int blue = clr & 0x000000ff;
                int grey = (11 * red + 16 * green + 5 * blue) / 32;

                freq_red[red] += 1;
                freq_green[green] += 1;
                freq_blue[blue] += 1;
                freq_grey[grey] += 1;
            }
        }

        int threshold = 150;
        for (int i = 0; i < 256; i++) {
            freq_red[i] = applyThreshold(threshold, freq_red[i]);
            freq_green[i] = applyThreshold(threshold, freq_green[i]);
            freq_blue[i] = applyThreshold(threshold, freq_blue[i]);
            freq_grey[i] = applyThreshold(threshold, freq_grey[i]);
        }

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                int clr = inputbuff.getRGB(y, x);

                int red = (clr & 0x00ff0000) >> 16;
                int green = (clr & 0x0000ff00) >> 8;
                int blue = clr & 0x000000ff;
                int grey = (11 * red + 16 * green + 5 * blue) / 32;

                red = freq_red[red];
                green = freq_green[green];
                blue = freq_blue[blue];
                grey = freq_grey[grey];


                int alpha = 0xff000000;
            int combine = alpha | (red <<16) |(green <<8)|blue;

                process_red[x * height + y] = (0xFF<<24)|(red<<16)|(red<<8)|red;
                process_green[x * height + y] = (0xFF<<24)|(green<<16)|(green<<8)|green;
                process_blue[x * height + y] = (0xFF<<24)|(blue<<16)|(blue<<8)|blue;
                process_grey[x * height + y] = (0xFF<<24)|(grey<<16)|(grey<<8)|grey;
                process_rgb[x * height + y] = clr;
                process_combine[x * height + y] = combine;

            }
        }

        image_red = new JFrame().createImage(new MemoryImageSource(width, height, process_red, 0, width));
        image_green = new JFrame().createImage(new MemoryImageSource(width, height, process_green, 0, width));
        image_blue = new JFrame().createImage(new MemoryImageSource(width, height, process_blue, 0, width));
        image_grey = new JFrame().createImage(new MemoryImageSource(width, height, process_grey, 0, width));
        image_rgb = new JFrame().createImage(new MemoryImageSource(width, height, process_rgb, 0, width));
        image_combine = new JFrame().createImage(new MemoryImageSource(width, height, process_combine, 0, width));

        buff_red = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
        buff_green = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
        buff_blue = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
        buff_grey = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
        buff_rgb = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);
        buff_combine = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB);

        graph_red = buff_red.getGraphics();
        graph_green = buff_green.getGraphics();
        graph_blue = buff_blue.getGraphics();
        graph_grey = buff_grey.getGraphics();
        graph_rgb = buff_rgb.getGraphics();
        graph_combine = buff_combine.getGraphics();

        graph_red.drawImage(image_red, 0, 0, null);
        graph_green.drawImage(image_green, 0, 0, null);
        graph_blue.drawImage(image_blue, 0, 0, null);
        graph_grey.drawImage(image_grey, 0, 0, null);
        graph_rgb.drawImage(image_rgb, 0, 0, null);
        graph_combine.drawImage(image_combine, 0, 0, null);

        graph_red.dispose();
        graph_green.dispose();
        graph_blue.dispose();
        graph_grey.dispose();
        graph_rgb.dispose();
        graph_combine.dispose();


        repaint();
}   

我怀疑问题在于alpha值:

int alpha = 0xff000000;
int combine = alpha | (red <<16) | (green <<8)|blue;

然而,当我删除alpha值时,它不会显示任何内容。谁能帮帮我吗?提前谢谢!

1 个答案:

答案 0 :(得分:0)

我猜测freq_red等是字节数组。如果是这样,那么你会被byte sign extension咬伤。

尝试替换此

red = freq_red[red];
green = freq_green[green];
blue = freq_blue[blue];
grey = freq_grey[grey];

用这个:

red = freq_red[red] & 0xFF;
green = freq_green[green] & 0xFF;
blue = freq_blue[blue] & 0xFF;
grey = freq_grey[grey] & 0xFF;

更新:由于所有临时图像(graph_red等),您的方法比需要的时间长。您可以通过定义这样的方法来避免它们:

private BufferedImage wrapPixelArray(int width,
                                     int height,
                                     int[] process) {
    DataBuffer db = new DataBufferInt(process, width * height);
    SampleModel sm =
        new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, width, height, MASK);
    WritableRaster wr =
        Raster.createWritableRaster(sm, db, null);
    return new BufferedImage(RGB, wr, false, null);
}

private static final int[] MASK = {0xFF0000, 0xFF00, 0xFF}; 
private static final ColorModel RGB =
    new DirectColorModel(32, MASK[0], MASK[1], MASK[2]);