在 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++;
}
}
我理解的思路是渐进灰度化;即逐渐收敛到灰度图像。这可以通过收敛到它来实现;一个收敛问题。
如果数量大于收敛值我们减少;如果它更小,我们增加。
在第一个循环中我们找到平均值(收敛值)。
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; }
}
我做了一些研究并找到了一些线索,但我需要帮助确定将彩色图像转换为灰度图像的最佳方法。虽然有很多快速转换的例子,但我正在寻找渐进和随机的转换。因此,我希望显示一张图像,随着时间的推移,它会变成从图像表面的 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++;
}
}
我理解的思路是渐进灰度化;即逐渐收敛到灰度图像。这可以通过收敛到它来实现;一个收敛问题。
如果数量大于收敛值我们减少;如果它更小,我们增加。
在第一个循环中我们找到平均值(收敛值)。
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; }
}