java - 如何获取黑白图像的像素值?

标签 java image-processing getpixel

我使用 java Swing 和 JAI 在 netbeans 平台上制作应用程序。在此我想进行图像处理。我使用 X 射线枪捕获 .tiff 黑白图像。之后我想绘制那个黑白图像的直方图。因此,要绘制直方图,首先我们必须获得灰度或黑白图像的像素值。然后我们可以使用这个像素值绘制直方图。那么,我怎样才能得到黑白图像的这个像素值呢?

最佳答案

如果您使用 java.awt.image.BufferedImage,这应该有效。

既然你想创建一个直方图,我想你会遍历所有的像素。有返回单个像素值的方法。

int getRGB(int x, int y)

但是,由于循环会发生,我想你会想要使用这个:

int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) 

获取数组后,使用:

int alpha = (pixels[i] >> 24) & 0x000000FF;
int red = (pixels[i] >> 16) & 0x000000FF;
int green = (pixels[i] >>8 ) & 0x000000FF;
int blue = pixels[i] & 0x000000FF;

提取 channel 数据。不确定变量是否可以声明为字节(我们只使用数组中整数的一个字节,尽管字节是有符号的并且发生了不同的算术 - 二进制补码形式),但你可以将它们声明为短。

然后对这些值进行一些数学计算,例如:

int average = (red + green + blue) / 3;

这将返回像素的平均值,为您提供一个可以在简单的亮度直方图中使用的点。

编辑:

关于柱状图的制作,我用过这个类。它将您想要的直方图图像作为其 setImage(BufferedImage image) 方法的参数。使用 updateHistogram() 进行数组填充。绘图数据在 paintComponent(Graphics g) 中。我必须承认,它很草率,尤其是在计算偏移量时,但它可以很容易地简化。

这是全类:

class HistogramCtrl extends JComponent
{
    BufferedImage m_image;
    int[] m_histogramArray = new int[256];  //What drives our histogram
    int m_maximumPixels;
    public HistogramCtrl(){
        m_maximumPixels = 0;
        for(short i = 0; i<256; i++){
            m_histogramArray[i] = 0;
        }
    }

    void setImage(BufferedImage image){
        m_image = image;
        updateHistogram();
        repaint();
    }

    void updateHistogram(){
        if(m_image == null) return;

        int[] pixels = m_image.getRGB(0, 0, m_image.getWidth(), m_image.getHeight(), null, 0, m_image.getWidth());
        short currentValue = 0;
        int red,green,blue;
        for(int i = 0; i<pixels.length; i++){           
                red = (pixels[i] >> 16) & 0x000000FF;
                green = (pixels[i] >>8 ) & 0x000000FF;
                blue = pixels[i] & 0x000000FF;
                currentValue = (short)((red + green + blue) / 3); //Current value gives the average //Disregard the alpha
                assert(currentValue >= 0 && currentValue <= 255);   //Something is awfully wrong if this goes off...
                m_histogramArray[currentValue] += 1;    //Increment the specific value of the array
        }

        m_maximumPixels = 0;    //We need to have their number in order to scale the histogram properly
        for(int i = 0; i < m_histogramArray.length;i++){    //Loop through the elements
            if(m_histogramArray[i] > m_maximumPixels){  //And find the bigges value
                m_maximumPixels = m_histogramArray[i];
            }
        }
    }

    protected void paintComponent(Graphics g){
        assert(m_maximumPixels != 0);

        Rectangle rect = g.getClipBounds();

        Color oldColor = g.getColor();
        g.setColor(new Color(210,210,210));
        g.fillRect((int)rect.getX(), (int)rect.getY(), (int)rect.getWidth(), (int)rect.getHeight());
        g.setColor(oldColor);

        String zero = "0";
        String thff = "255";

        final short ctrlWidth = (short)rect.getWidth();
        final short ctrlHeight = (short)rect.getHeight();

        final short activeWidth = 256;
        final short activeHeight = 200;

        final short widthSpacing = (short)((ctrlWidth - activeWidth)/2);
        final short heightSpacing = (short)((ctrlHeight - activeHeight)/2);

        Point startingPoint = new Point();
        final int substraction = -1;
        startingPoint.x = widthSpacing-substraction;
        startingPoint.y = heightSpacing+activeHeight-substraction;

        g.drawString(zero,widthSpacing-substraction - 2,heightSpacing+activeHeight-substraction + 15);
        g.drawString(thff,widthSpacing+activeWidth-substraction-12,heightSpacing+activeHeight-substraction + 15);

        g.drawLine(startingPoint.x, startingPoint.y, widthSpacing+activeWidth-substraction, heightSpacing+activeHeight-substraction);
        g.drawLine(startingPoint.x,startingPoint.y,startingPoint.x,heightSpacing-substraction);

        double factorHeight = (double)activeHeight / m_maximumPixels;   //The height divided by the number of pixels is the factor of multiplication for the other dots

        Point usingPoint = new Point(startingPoint.x,startingPoint.y);

        usingPoint.x+=2;    //I want to move this two points in order to be able to draw the pixels with value 0 a bit away from the limit
        Point tempPoint = new Point();
        for(short i = 0; i<256; i++){
            tempPoint.x = usingPoint.x;
            tempPoint.y = (int)((heightSpacing+activeHeight-substraction) - (m_histogramArray[i] * factorHeight));
            if((i!=0 && (i % 20 == 0)) || i == 255){
                oldColor = g.getColor();
                g.setColor(oldColor.brighter());
                //Draw horizontal ruler sections
                tempPoint.x = widthSpacing + i;
                tempPoint.y = heightSpacing+activeHeight-substraction+4;
                g.drawLine(tempPoint.x,tempPoint.y,widthSpacing + i,heightSpacing+activeHeight-substraction-4);

                if(i <= 200){
                    //Draw vertical ruler sections
                    tempPoint.x = widthSpacing - substraction - 3;
                    tempPoint.y = heightSpacing+activeHeight-substraction-i;
                    g.drawLine(tempPoint.x,tempPoint.y,widthSpacing - substraction + 4, heightSpacing+activeHeight-substraction-i);
                }
                tempPoint.x = usingPoint.x;
                tempPoint.y = usingPoint.y;

                g.setColor(oldColor);
            }
            g.drawLine(usingPoint.x, usingPoint.y, tempPoint.x, tempPoint.y);
            usingPoint.x++; //Set this to the next point
        }
    }
}

关于java - 如何获取黑白图像的像素值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10123366/

相关文章:

C# 如何将我的 getPixel/SetPixel 颜色处理转换为 Lockbits?

java - 二叉树节点计数的递归方法

java - 如何在 sessionCreated 方法中检索用户输入的数据

image - 位图文件的哪一部分是元数据?

python - numpy 矢量化/更高效的 for 循环

android - 使用 getPixel() 方法提取的巨大负值

c++ - OpenCV 从 Mat 图像中获取像素 channel 值

java - 从字符串中分离出特定的单词

java - 仅当缓存值不早于当前值时如何更新项目

opencv - 手部实时追踪