You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java黑白图像像素识别异常:所有像素被判定为白色问题排查

问题分析与修复

核心问题

代码中所有像素被误判为白色,主要由以下三个错误导致:

1. getRGB坐标参数顺序错误

在counter()方法的循环中,你传递给getRGB的参数是tog[i][j-1], tog[i][j],但循环结束后j=2,此时tog[i][j]指向未初始化的数组第三列,且getRGB的正确参数顺序是x坐标在前,y坐标在后,应该使用tog[i][0](x)和tog[i][1](y)。

2. DDA算法中坐标填充逻辑错误

原代码中while循环里的i变量逻辑完全多余,会导致坐标填充混乱。实际上每个像素点只需要填充数组的第0列(x)和第1列(y),不需要切换i的值。

3. TYPE_BYTE_BINARY图像的像素判断方式

BufferedImage.TYPE_BYTE_BINARY是1位黑白图像,其getRGB返回的ARGB值中,黑色为0xFF000000,白色为0xFFFFFFFF。直接判断像素值是否等于0xFFFFFFFF更准确,避免位运算的错误。

修复后的代码

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class W3_Img_Process_Class_Only extends JPanel {
    int[][] tog;
    int step;
    String inTitle = "L1";
    int imageCount = 0;
    int[] x = new int[2], y = new int[2];
    int[] black = new int[2];
    int clr;
    int flag = 0;

    private BufferedImage master;
    private BufferedImage blackWhite;

    public W3_Img_Process_Class_Only() {
        try {
            // 替换为你的图片路径
            master = ImageIO.read(new File("your_image_path.png"));
            blackWhite = new BufferedImage(master.getWidth(), master.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
            Graphics2D g2d = blackWhite.createGraphics();
            g2d.drawImage(master, 0, 0, this);
            g2d.dispose();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        this.addMouseListener(new MouseListener() {
            int[] isFirstEmpty;

            @Override
            public void mouseClicked(MouseEvent e1) {
                int[] temp = new int[3];
                temp[0] = e1.getX();
                temp[1] = e1.getY();
                clr = blackWhite.getRGB(temp[0], temp[1]);
                // 直接判断是否为白色
                temp[2] = (clr == 0xFFFFFFFF) ? 255 : 0;

                if (isFirstEmpty == null) {
                    isFirstEmpty = temp;
                    x[0] = temp[0];
                    y[0] = temp[1];
                    black[0] = temp[2];
                } else {
                    x[1] = temp[0];
                    y[1] = temp[1];
                    black[1] = temp[2];
                    isFirstEmpty = null;
                    flag = 1;
                }

                if (flag == 1) {
                    System.out.printf("X1: %d & Y1: %d (255 if white): %d\t", x[0], y[0], black[0]);
                    System.out.printf("X2: %d & Y2: %d (255 if white): %d\n", x[1], y[1], black[1]);
                    counter();
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        });
    }

    private void counter() {
        if (flag != 1) return;

        int dx = x[1] - x[0];
        int dy = y[1] - y[0];
        step = Math.abs(dx) > Math.abs(dy) ? Math.abs(dx) : Math.abs(dy);
        System.out.println("Steps: " + step);

        float Xinc = dx / (float) step;
        float Yinc = dy / (float) step;

        tog = new int[step][3];
        // 初始化第一个点
        tog[0][0] = x[0];
        tog[0][1] = y[0];
        tog[0][2] = (black[0] == 255) ? 1 : 0;
        System.out.printf("%d %d %d\n", tog[0][0], tog[0][1], tog[0][2]);

        float xt = x[0], yt = y[0];
        for (int j = 1; j < step; j++) {
            xt += Xinc;
            yt += Yinc;
            // 直接填充x和y坐标,无需多余的i变量
            tog[j][0] = Math.round(xt); // 使用round避免坐标截断误差
            tog[j][1] = Math.round(yt);
        }

        // 遍历所有点,判断颜色
        for (int i = 0; i < step; i++) {
            int px = tog[i][0];
            int py = tog[i][1];
            System.out.printf("%d %d ", px, py);

            clr = blackWhite.getRGB(px, py);
            // 判断是否为白色,是则标记1,否则0
            int mark = (clr == 0xFFFFFFFF) ? 1 : 0;
            tog[i][2] = mark;
            System.out.println(mark);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension size = super.getPreferredSize();
        if (master != null) {
            size = new Dimension(master.getWidth(), master.getHeight());
        }
        return size;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (master != null) {
            int x = (getWidth() - master.getWidth()) / 2;
            int y = (getHeight() - master.getHeight()) / 2;
            g.drawImage(blackWhite, x, y, this);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new JFrame("Image Process");
            frame.add(new W3_Img_Process_Class_Only());
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

修复说明

  • 修正getRGB参数:使用tog[i][0](x坐标)和tog[i][1](y坐标)传递给getRGB,确保坐标正确。
  • 简化DDA填充逻辑:移除多余的i变量,直接循环填充每个点的x和y坐标,同时使用Math.round避免浮点截断导致的坐标误差。
  • 优化像素判断:直接对比getRGB返回值与0xFFFFFFFF(白色),逻辑更清晰准确,避免位运算错误。
  • 添加main方法:补充程序入口,方便直接运行测试。

内容的提问来源于stack exchange,提问作者Arpan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:25:19