图片中的绿色通道不正确

时间:2018-11-04 17:00:49

标签: java image

我的程序的目标是使图像变亮。这样做的方式是:

  1. 检查像素的rgb频道
  2. 找到所有b / w的最高rgb值
  3. 找到使该通道的值达到255的乘数
  4. 它将乘数应用于所有通道

代码:

package Assign_4_B;

import Media.*;                  // for Picture and Sound etc.
import java.awt.*;               // for Color objects and methods
import static java.lang.Math.*;  // for math constants and functions
import static java.awt.Color.*;  // for Color constants


/** This class ...
  *
  * @author <your name>
  * @version 1.0 (<date>)                                                        */

public class Brighten {
    private PictureDisplayer display;
    private Picture pic;

    public Brighten ( ) {
      display = new PictureDisplayer();
      pic = new Picture();
      display.placePicture(pic);
      display.waitForUser();
      normIntensity(pic);
      display.close();   
    }; // constructor

    private int maxChannel(Pixel p){
      int red;
      int blue;
      int green;

      red = p.getRed();
      blue = p.getBlue();
      green = p.getGreen();

      if((red >= blue) && (red >= green)){
        return red;
      }
      else if ((blue >= red) && (blue >= green)){
        return blue;
      }
      else {return green;}
      }


    private void normIntensity (Picture img){
      Pixel a;
      int r;
      int b;
      int g;
      int hv;
      int multi;


      while(img.hasNext()){
        a = img.next();

        hv = maxChannel(a);
        multi = 255 / hv;

        r = a.getRed();
        b = a.getBlue();
        g = a.getGreen();

        a.setRed(multi * r);
        a.setBlue(multi * b);
        a.setGreen(multi * g);
      } 
    };

    public static void main ( String[] args ) { Brighten s = new Brighten(); };   
} // <className>

我的代码中的问题是它弄乱了绿色通道的值。

如果初始图像是这样的:enter image description here

我想要的结果是:enter image description here

它最终将像这样:enter image description here

它只会做那么多,直到给我这个错误代码:

java.lang.ArithmeticException: / by zero
    at Assign_4_B.Brighten.normIntensity(Brighten.java:59)
    at Assign_4_B.Brighten.<init>(Brighten.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:267)

1 个答案:

答案 0 :(得分:0)

概念错误是您正在分别计算每个像素的最大通道。为了执行Histogram Equalization的简单形式,您必须计算所有个像素的最大值。

这些类似乎来自该库:https://www.cosc.brocku.ca/sites/all/files/documentation/Brock_packages/Media/Picture.html但我尚未使用此库,因此可能需要对下面的代码进行一些调整,但它应该大致像这样工作:

(在评论后更新:)

import java.util.Iterator;

// for Picture and Sound etc.
import Media.Picture;
import Media.PictureDisplayer;
import Media.Pixel;

/**
 * This class ...
 *
 * @author <your name>
 * @version 1.0 (<date>)
 */

public class Brighten
{
    private PictureDisplayer display;
    private Picture pic;

    public Brighten()
    {
        display = new PictureDisplayer();
        pic = new Picture();
        display.placePicture(pic);
        display.waitForUser();
        normIntensity(pic);
        display.close();
    }; // constructor

    private int maxChannel(Picture img)
    {
        Pixel m;
        int red;
        int blue;
        int green;

        int max = 0;

        while (img.hasNext())
        {
            m = img.next();

            red = m.getRed();
            blue = m.getBlue();
            green = m.getGreen();

            if ((red >= blue) && (red >= green) && (red >= max))
            {
                max = red;
            }
            if ((blue >= red) && (blue >= green) && (blue >= max))
            {
                max = blue;
            }
            if ((green >= red) && (green >= blue) && (green >= max))
            {
                max = green;
            }
        }
        return max;
    }

    private void normIntensity(Picture img)
    {
        // Compute the maximum value of any channel over ALL pixels:
        int max = maxChannel(img);

        // Nothing to do if the image is all black...
        if (max == 0)
            return;

        // Compute the multiplier. This should probably be a double value:
        double multi = 255.0 / max;

        // Use the multiplier to scale all pixels
        Iterator<Pixel> iterator = img.iterator();
        while (iterator.hasNext())
        {
            Pixel a = iterator.next();

            int r = a.getRed();
            int g = a.getGreen();
            int b = a.getBlue();

            a.setRed((int) (multi * r));
            a.setGreen((int) (multi * g));
            a.setBlue((int) (multi * b));
        }
    };

    public static void main(String[] args)
    {
        Brighten s = new Brighten();
    };
} // <className>