在 Java 中逐渐随机地将彩色图像更改为灰度图像?

Gradually and randomly change colored image to grayscale in Java?

我做了一些研究并找到了一些线索,但我需要帮助确定将彩色图像转换为灰度图像的最佳方法。虽然有很多快速转换的例子,但我正在寻找渐进和随机的转换。因此,我希望显示一张图像,随着时间的推移,它会变成从图像表面的 0-100% 到随机像素的灰度图像。

我不需要完整的代码,只需要一些方法,也许这会引导我朝着正确的方向前进。

我的一个想法是让具有不同灰度的图像交换进出。这是我能做的最好的吗?没有实时转换?

谢谢大家。这就是我所拥有的以及它到目前为止所做的......

import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.util.*;

public class Color2GrayscaleImage{
  public static void main(String args[])throws IOException{

    Scanner input= new Scanner(System.in);

    System.out.println("What percent of the image do you want grayscaled?");

    int percentCover=input.nextInt();
    double per=(percentCover/100);
    BufferedImage img = null;
    File f = null;

    try{
      f = new File("media/mini0n.jpg");
      img = ImageIO.read(f);
    }catch(IOException e){
      System.out.println(e);
    }

    //get image width and height
    int width = img.getWidth();
    int height = img.getHeight();

System.out.println(width+"x"+height+". "+width*height+ " total pixels.");

    //convert entire image to grayscale
    //for(int y = 0; y < height; y++){
      //for(int x = 0; x < width; x++){
        //int p = img.getRGB(x,y);
        int num;
        for (num=0; num<5; num++){
        //randomly select pixels to be converted to grayscale
      for(int heightY = 0; heightY < height*(1+per); heightY++){
      for(int widthX = 0; widthX < width*(1+per); widthX++){

    Random random=new Random();
    int x= random.nextInt((width));
      int y= random.nextInt((height));

        int p = img.getRGB(x,y);

        int a = (p>>24)&0xff;
        int r = (p>>16)&0xff;
        int g = (p>>8)&0xff;
        int b = p&0xff;

        //calculate average
        int avg = (r+g+b)/3;

        //replace RGB value with avg
        p = (a<<24) | (avg<<16) | (avg<<8) | avg;

        img.setRGB(x, y, p);

        }
   }
    //write image
    try{
      f = new File("media/altered/new_IMAGE"+num+".jpg");
      ImageIO.write(img, "jpg", f);
    }catch(IOException e){
      System.out.println(e);
    }}
   num++;
  }
}

https://www.dropbox.com/s/uf9plmmrepvxfqi/gradual.jpg?dl=0

我理解的思路是渐进灰度化;即逐渐收敛到灰度图像。这可以通过收敛到它来实现;一个收敛问题。

如果数量大于收敛值我们减少;如果它更小,我们增加。

在第一个循环中我们找到平均值(收敛值)。

  int[] avg=new int[pix.length];
  for(i=0; i<wc; i++)
    for(j=0; j<hc; j++) {
      int p=bim.getRGB(i, j);
      int p1=(p&0x00ff0000)>>16, p2=(p&0x0000ff00)>>8, p3=p&0x000000ff;
      avg[i+j*wc]=(p1+p2+p3)/3;
    }

在第二个循环中我们执行收敛:

我们increase/decrease三个颜色分量中的每一个直到全部收敛:在这种情况下你可以选择10的小步长。

如果该值落在一个收敛单位内(例如小于 10),我们将该值设置为收敛值。如果所有像素都发生这种情况,我们就达到了灰度级。

boolean f1=false, f2=false, f3=false;
while(true) {
    f1=false; f2=false; f3=false;
    for(i=0; i<wc; i++)
    for(j=0; j<hc; j++) {
      int p=bim.getRGB(i, j);
      int p1=(p&0x00ff0000)>>16, p2=(p&0x0000ff00)>>8, p3=p&0x000000ff;
      if(p1>avg[i+j*wc]+10) { p1-=10; if(p1<avg[i+j*wc]) p1=avg[i+j*wc]; f1=true; }
      else if(p1<avg[i+j*wc]-10) { p1+=10; if(p1>avg[i+j*wc]) p1=avg[i+j*wc]; f1=true; }
      if(p2>avg[i+j*wc]+10) { p2-=10; if(p2<avg[i+j*wc]) p2=avg[i+j*wc]; f2=true; }
      else if(p2<avg[i+j*wc]-10) { p2+=10; if(p2>avg[i+j*wc]) p2=avg[i+j*wc]; f2=true; }
      if(p3>avg[i+j*wc]+10) { p3-=10; if(p3<avg[i+j*wc]) p3=avg[i+j*wc]; f3=true; }
      else if(p3<avg[i+j*wc]-10) { p3+=10; if(p3>avg[i+j*wc]) p3=avg[i+j*wc]; f3=true; }
      bim.setRGB(i, j, 0xff000000|(p1<<16)|(p2<<8)|p3);
    }
    if(f1 || f2 || f3) ; else   {    System.err.println("no change"); break; }
}