Цветовая матрица для повышения резкости изображения в Android

У меня есть класс, который использует цветовую матрицу, чтобы добавить эффекты изображения на ImageView. У меня есть несколько цветовых матриц для контраста, экспозиции, температуры и насыщенности. Пример:

public static Bitmap changeContrast(Bitmap bmp, float contrast)
{
    ColorMatrix cm = new ColorMatrix(new float[]
            {
                    contrast, 0, 0, 0, 0,
                    0, contrast, 0, 0, 0,
                    0, 0, contrast, 0, 0,
                    0, 0, 0, 1, 0
            });

    return getBitmapFromColorMatrix(cm, bmp);
}

Теперь моя проблема - повышение резкости изображения. Кажется, для них нет цветовой матрицы. Пожалуйста помоги.

Я попытался повысить резкость изображения с помощью кода, но это занимает слишком много времени для обработки, и я не знаю, какие допустимые значения должны быть переданы в весовой параметр sharpenImage(Bitmap src, double weight) метод.

3 ответа

Возможно, уже слишком поздно, но я просто хотел бы поделиться быстрым способом повышения резкости изображения.

 public static Bitmap doSharpen(Bitmap original, float[] radius) {  
      Bitmap bitmap = Bitmap.createBitmap(
              original.getWidth(), original.getHeight(),
              Bitmap.Config.ARGB_8888);

          RenderScript rs = RenderScript.create(yourContext);

          Allocation allocIn = Allocation.createFromBitmap(rs, original);
          Allocation allocOut = Allocation.createFromBitmap(rs, bitmap);

          ScriptIntrinsicConvolve3x3 convolution
              = ScriptIntrinsicConvolve3x3.create(rs, Element.U8_4(rs));
          convolution.setInput(allocIn);
          convolution.setCoefficients(radius);
          convolution.forEach(allocOut);

          allocOut.copyTo(bitmap);       
          rs.destroy();   

          return bitmap;                   

}

И вот 3 различных типа резкости, которые я создал:

// low
private static void loadBitmapSharp() {
    float[] sharp = { -0.60f, -0.60f, -0.60f, -0.60f, 5.81f, -0.60f,
            -0.60f, -0.60f, -0.60f };
//you call the method above and just paste the bitmap you want to apply it and the float of above
    yourbitmap = doSharpen(getbitmap, sharp));
}

// medium
private static void loadBitmapSharp1() {
    float[] sharp = { 0.0f, -1.0f, 0.0f, -1.0f, 5.0f, -1.0f, 0.0f, -1.0f,
            0.0f

    }; 
//you call the method above and just paste the bitmap you want to apply it and the float of above
    yourbitmap = doSharpen(getbitmap, sharp));
}

// high
private static void loadBitmapSharp2() {
    float[] sharp = { -0.15f, -0.15f, -0.15f, -0.15f, 2.2f, -0.15f, -0.15f,
            -0.15f, -0.15f
    };
 //you call the method above and just paste the bitmap you want to apply it and the float of above
    yourbitmap = doSharpen(getbitmap, sharp));
}

Вы также можете применить их непосредственно к растровому изображению без пустот, это быстро и просто, и есть хорошие результаты!

Улучшение первого ответа здесь, добавление панели поиска (ползунка) для изменения резкости изображения.

      public Bitmap doSharpen(Bitmap original, float multiplier) {
    float[] sharp = { 0, -multiplier, 0, -multiplier, 5f*multiplier, -multiplier, 0, -multiplier, 0};
    Bitmap bitmap = Bitmap.createBitmap(
            original.getWidth(), original.getHeight(),
            Bitmap.Config.ARGB_8888);

    RenderScript rs = RenderScript.create(MainActivity.this);

    Allocation allocIn = Allocation.createFromBitmap(rs, original);
    Allocation allocOut = Allocation.createFromBitmap(rs, bitmap);

    ScriptIntrinsicConvolve3x3 convolution
            = ScriptIntrinsicConvolve3x3.create(rs, Element.U8_4(rs));
    convolution.setInput(allocIn);
    convolution.setCoefficients(sharp);
    convolution.forEach(allocOut);

    allocOut.copyTo(bitmap);
    rs.destroy();

    return bitmap;

}

Пришлось немного доработать по своему проекту. Вместо того, чтобы использовать матрицу свертки в методе, я объявил ее внутри метода. Вместо этого мы возьмем измененную переменную панели поиска.

      sharpnessSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            Bitmap sharpenedBitmap = doSharpen(btmp,(float)i);
            imageV.setImageBitmap(sharpenedBitmap);
        }

Внутри setOnSeekBarChangeListener мы получаем измененное значение, которое является int i, и передаем его с помощью метода doSharpen, чтобы его можно было использовать в матрице свертки, которая определена внутри метода doSharpen().

Вот значения, которые я использовал для цветовой температуры с помощью панели поиска. (вы задали их в комментарии к одному вопросу, который я задал)

public static Bitmap doTemperature(Bitmap bmp, float temp){

     ColorMatrix cm = new ColorMatrix(new float[]
             {
             1, 0, 0, temp, 0,
             0, 1, 0, temp/2, 0,
             0, 0, 1, temp/4, 0,
             0, 0, 0, 1, 0

             });

     Bitmap ret = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
     Canvas canvas = new Canvas(ret);
     Paint paint = new Paint();
     paint.setColorFilter(new ColorMatrixColorFilter(cm));
     canvas.drawBitmap(bmp, 0, 0, paint);
     return ret;
 }
//you call it with this method
private void loadBitmapTemp() {
    //private Seekbar temp_value; 
    temp_value = (SeekBar) findViewById(R.id.temp_value);
    temp_value.setMax(100);
    temp_value.setProgress(50);

    int progressTemp = temp_value.getProgress();
    progressTemp -= 50;
    float temp = (float) progressTemp / 220;
    progress_text.setVisibility(View.VISIBLE);
    progress_text.setText(" " + progressTemp * 2);
    yourBitmap = doTemperature(getbitmap, temp));
}
Другие вопросы по тегам