android中图像锐化的颜色矩阵

Posted

技术标签:

【中文标题】android中图像锐化的颜色矩阵【英文标题】:Color Matrix for Image Sharpening in android 【发布时间】:2015-12-09 09:25:21 【问题描述】:

我有一个使用颜色矩阵在 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);

现在我的问题是图像的锐化。这些似乎没有颜色矩阵。请帮忙。

我尝试使用here 中的代码锐化图像,但处理时间太长,而且我不知道应该将哪些有效值传递给sharpenImage(Bitmap src, double weight) 方法的权重参数。

【问题讨论】:

【参考方案1】:

可能为时已晚,但我只是想分享一种快速锐化图像的方法。

 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));

您也可以将它们直接应用到没有空白的位图上,它快速简单,效果很好!

【讨论】:

如何根据滑块值改变矩阵值?【参考方案2】:

在这里改进第一个答案,添加一个搜索栏(滑块)来改变图像的清晰度。

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;


我不得不根据我的项目对其进行一些修改。我没有在方法中使用卷积矩阵,而是在方法中声明了它。我们将取而代之的是 seekbar 的 changed 变量。

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() 方法中定义的卷积矩阵中使用它。

【讨论】:

【参考方案3】:

这是我用搜索栏用于色温的值。 (你让他们对我提出的一个问题发表评论)

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));

【讨论】:

以上是关于android中图像锐化的颜色矩阵的主要内容,如果未能解决你的问题,请参考以下文章

数字图像处理图像边缘锐化之微分运算

Python图像锐化及边缘检测(RobertsPrewittSobelLapllacianCannyLOG)

中值滤波与图像锐化

中值滤波与图像锐化

请教高手,关于拉普拉斯算子做图像锐化

图像的锐化