2016-05-06 7 views
2

Мне было рекомендовано отделить этот вопрос от другого. Вот оригинал:Как применить маску изображения в оттенках серого к изображению rgb в java

How to change white background for black

После некоторых процессов изображения я получаю бинарное изображение, но границы так трудно, поэтому я применить фильтр Гаусса, чтобы получить мягкий один. В результате получается изображение в оттенках серого. Мне нужно применить это изображение как маску для другого, ни один из них не имеет альфа-канала, поэтому смешивание цветов должно выполняться без этого значения. Я использую Marvin Framework, чтобы сделать работу, но Марвин не имеет плагин для него, поэтому я один код, это он:

@Override public void process(MarvinImage _imageIn, MarvinImage _imageOut, MarvinAttributes attrOut, MarvinImageMask _mask, boolean previewMode) { 

    MarvinImage mask = _imageIn; 
    MarvinImage image = _imageOut; 

    for(int y=0; y<mask.getHeight(); y++){ 
     for(int x=0; x<mask.getWidth(); x++){ 

      //ya que está en grayscale, los 3 valores son los mismos 
      int r1 = mask.getIntComponent0(x, y); 
      int g1 = mask.getIntComponent1(x, y); 
      int b1 = mask.getIntComponent2(x, y); 

      int r2 = image.getIntComponent0(x, y); 
      int g2 = image.getIntComponent1(x, y); 
      int b2 = image.getIntComponent2(x, y); 

      //al color de salida, le asignamos la luminicencia de la imagen mascara 
      int r = 0, g = 0, b = 0; 
      if(r1 > 0 || r2 > 0){ 
       r = r1*r2/Math.max(r1, r2); 
      } 

      if(g1 > 0 || g2 > 0){ 
       g = g1*g2/Math.max(g1, g2); 
      } 

      if(b1 > 0 || b2 > 0){ 
       b = b1*b2/Math.max(b1, b2); 
      } 

      image.setIntColor(x, y, r, g, b); 
     } 
    } 
} 

Но этот код имеет небольшую ошибку, что я не мог решить. Когда изображение rgb имеет белый цвет, результат цвета не сочетается очень хорошо, он не становится темнее. То, что я ищу, - это то, что можно достичь с помощью gimp, где есть изображение с двумя слоями, нижнее - изображение rgb, а верхнее - маска в оттенках серого, затем в этом слое мы используем цвет функции для альфы, используя белый цвет как цель. Результат следующий:

Gimp mix

Уит алгоритм следующий:

Algorithm mix

разница довольно obious. Вот два оригинальных изображений для тестирования:

Color image Grayscale mask

ответ

0

Вам просто нужно сделать альфа сочетание изображения с маской. В основном пиксель выходного изображения:

output_image (х, у) = input_image (х, у) * PI + mask_image (х, у) * PM

Где ПИ и ТЧ являются процент ввода и маскировать изображения в выходном пикселе, соответственно. ПИ + РМ = 1 (100%)

Пример:

Для черных пикселей в маске:

РМ = 1 - (grayscalePixel/255) → 1 - (0/255) = 1

Для белых пикселей:

РМ = 1 - (grayscalePixel/255) → 1 - (255/255) = 0

Для серого пикселя:

РМ = 1 - (grayscalePixel/255) → 1 - (127/255) = 0.5

Наконец:

PI = 1 - ПМ;

ВЫВОД 1:

enter image description here

Исходный код:

public class GrayScaleMask { 

    public GrayScaleMask(){ 

     MarvinImage image = MarvinImageIO.loadImage("./res/grayscaleMask_input.png"); 
     MarvinImage mask = MarvinImageIO.loadImage("./res/grayscaleMask_mask.png"); 
     grayscaleMask(image.clone(), image, mask); 
     MarvinImageIO.saveImage(image, "./res/grayscaleMask_output.png"); 
    } 

    private void grayscaleMask(MarvinImage image, MarvinImage imageOut, MarvinImage mask){ 
     int r1,r2,g1,g2,b1,b2; 
     double maskGray, factorMask, factorImage; 
     for(int y=0; y<image.getHeight(); y++){ 
      for(int x=0; x<image.getWidth(); x++){ 
       r1 = image.getIntComponent0(x, y); 
       g1 = image.getIntComponent1(x, y); 
       b1 = image.getIntComponent2(x, y); 
       r2 = mask.getIntComponent0(x, y); 
       g2 = mask.getIntComponent1(x, y); 
       b2 = mask.getIntComponent2(x, y); 
       maskGray = (r2*0.21)+(g2*0.72)+(b2*0.07); 
       factorMask = 1-(maskGray/255); 
       factorImage = 1-factorMask; 
       imageOut.setIntColor(x, y, (int)(r1*factorImage+r2*factorMask), 
              (int)(g1*factorImage+g2*factorMask), 
              (int)(b1*factorImage+b2*factorMask)); 

      } 
     } 
    } 

    public static void main(String[] args) { 
     new GrayScaleMask(); System.exit(0); 
    } 
} 

ВЫВОД 2:

Вы можете затемнить маски J усть перед объединением его:

r2 = (int)(r2*0.3); 
    g2 = (int)(g2*0.3); 
    b2 = (int)(b2*0.3); 
    imageOut.setIntColor(x, y, (int)((r1*factorImage+r2*factorMask)), 
           (int)((g1*factorImage+g2*factorMask)), 
           (int)((b1*factorImage+b2*factorMask))); 

enter image description here

+0

You алгоритм, кажется, сделать градиент более линейным, но все же были некоторые серый вместо черного –

+0

я пытался сделать игру wuth свой алгоритм, но я пошел на factorMask, неправильный путь. Это то, чего я хочу. Спасибо за ваше время. –