【问题标题】:How do I blur an image if given x and y coordinates in Java?如果在 Java 中给定 x 和 y 坐标,如何模糊图像?
【发布时间】:2017-04-04 14:50:25
【问题描述】:

下面的代码是一个图像处理例程。 x 和 y 表示构成图像的所有像素的坐标。基本情况如下:

  • x, y - 每个像素的坐标。
  • imgH, imgW - 图像的高度和宽度,以像素为单位
  • r, g, b - 每个像素的红色、绿色和蓝色级别

代码使用双 for 循环对图像中的每个像素进行处理。我想在这个 for 循环中做的是对于每个像素,我想平均 8 个周围像素的 r、g、b 值,并将其平均为中心像素的值。这将产生模糊图像的效果。有人可以帮我吗?

    protected void proc_17() {
    info = "";
    for (int y = 0; y < imgH; y++) {
        for (int x = 0; x < imgW; x++) {
            int xNext = (x+1) % imgW;
            int yNext = (y+1) % imgH;
            float r = (imgOld.getR(xNext, yNext) + imgOld.getR(xNext, yNext)) / 8;
            float g = (imgOld.getG(xNext, yNext) + imgOld.getG(xNext, yNext)) / 8;
            float b = (imgOld.getB(xNext, yNext) + imgOld.getB(xNext, yNext)) / 8;
            imgNew.setR(x, y, r);
            imgNew.setG(x, y, g);
            imgNew.setB(x, y, b);
        }
    }
}

【问题讨论】:

  • 您将需要循环两次,一次用于计算新值,一次用于应用它们。否则将使用一些已经模糊的像素进行计算
  • 为什么不用imgOld.getR(xNext, yNext) / 4;替换(imgOld.getR(xNext, yNext) + imgOld.getR(xNext, yNext)) / 8;
  • 除以 4 只是将每个像素的 RGB 值相除,使它们变低,这反过来又使图像变暗,因为值被均匀地减小。
  • 是的,但是您正在将此调用 imgOld.getR(xNext, yNext) 返回的值添加到自身,因为您再次进行了完全相同的调用。然后你将它除以 8。本质上,你正在做的是:(2 * imgOld.getR(xNext, yNext)) / 8;

标签: java image for-loop image-processing pixels


【解决方案1】:

平滑和/或平均通常使用对称非零矩阵的卷积来完成,该矩阵只有非负元素(权重)且总和等于 1。通常的 4 邻域平滑矩阵如下所示:

0.0 0.1 0.0
0.1 0.6 0.1
0.0 0.1 0.0

8-邻居:

0.05 0.10 0.05
0.10 0.20 0.10
0.05 0.10 0.05
  • 如果权重总和为 1,则结果的大小将与输入相同。
  • 对称矩阵不会移动结果...
  • 矩阵的分辨率将为您提供平滑的距离

现在您也可以就地执行此操作,因此不需要额外的图像存储空间:

0.50 0.25
0.25 0.00

然后:

0.00 0.25
0.25 0.50

正如您所见,矩阵不是居中也不是对称的,因此结果发生了偏移,但偏移是相反的并且相互否定。代码如下所示:

for (y=0;y<ys-1;y++)
 for (x=0;x<xs-1;x++)
  pixel[y][x]=(2*pixel[y][x]+pixel[y+1][x]+pixel[y][x+1])/4;

for (y=ys-1;y>0;y--)
 for (x=xs-1;x>0;x--)
  pixel[y][x]=(2*pixel[y][x]+pixel[y-1][x]+pixel[y][x-1])/4;

您必须分别处理每个像素的r,g,b 粗略。 xs,ys 是图像分辨率,pixel[][] 是图像的直接像素访问。您还必须处理边界像素,以便使用不同的矩阵平滑它们或将结果图像从每侧缩小一个像素(取决于您的需要)。权重导致乘以 2 和除以 4,这可以通过位移操作来实现速度(以防编译器自己不这样做)

为了增加平滑的强度,你可以循环几次。

for (i=0;i<smooth_strength;i++)
 {
 for (y=0;y<ys-1;y++)
  for (x=0;x<xs-1;x++)
   pixel[y][x]=(2*pixel[y][x]+pixel[y+1][x]+pixel[y][x+1])/4;

 for (y=ys-1;y>0;y--)
  for (x=xs-1;x>0;x--)
   pixel[y][x]=(2*pixel[y][x]+pixel[y-1][x]+pixel[y][x-1])/4;
 }

更多想法请看:

【讨论】:

    猜你喜欢
    • 2016-02-02
    • 2019-03-03
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 2015-03-02
    • 1970-01-01
    • 2019-06-22
    • 1970-01-01
    相关资源
    最近更新 更多