Android-OpenCV修改图片中某一块的像素

功能需求: 消除机器人激光雷达生成的图片上的噪点。类似于美图秀秀的去水印,将某一片的像素改成图片背景色

整体思路

  • 将图片转换成Mat
  • 修改矩阵中某一部分的像素值
  • 将修改后的Mat转成Bitmap

一、将图片转成Mat

1.知道图片的存储路径

//path为图片的存储路径
 Mat mat1;
 mat1= Imgcodecs.imread(path,Imgcodecs.IMREAD_UNCHANGED);

2.仅有图片的Bitmap对象

Mat mat=new Mat();
Utils.bitmapToMat(bitmap,src);

注:Utils为OpenCv库里面的类

二、修改矩阵中某一部分的像素

问题假设:
已知整体图片的矩阵 dtsMat,要修改从第startCol列到endCol列,从startRow行到endRow行的矩形区域的像素。即相对于图片坐标为(startCol,startRow)(endCol,endRow)。
需要理解一点,第几行对应的是Y轴坐标,第几列对应的是X轴坐标。

第一步:得到该矩形区域的矩阵的指针,即使java对象

Mat mat=dtsMat.submat(startRow,endRow,startCol,endCol);

需要注意的边界检测:

//保证去噪的区域不超过图片的宽高,并且endXXX必须大于等于startXXX,不然会导致出错
                    startRow=startRow<0?0:startRow;
                    startRow=startRow>dtsMat.rows()?dtsMat.rows():startRow;
                    endRow=endRow<0?0:endRow;
                    endRow=endRow>dtsMat.rows()?dtsMat.rows():endRow;
                    startCol=startCol<0?0:startCol;
                    startCol=startCol>dtsMat.cols()?dtsMat.cols():startCol;
                    endCol=endCol<0?0:endCol;
                    endCol=endCol>dtsMat.cols()?dtsMat.cols():endCol;
                    if (startRow>endRow){
                        int row=startRow;
                        startRow=endRow;
                        endRow=row;
                    }
                    if (startCol>endCol){
                        int col=startCol;
                        startCol=endCol;
                        endCol=col;
                    }

第二步:将三通道的矩阵转成单通道的灰度图,再获取像素数组,代码如下:

/**
     * 修改图片某一块像素
     * @param mat
     */
    private void dealWithMat(Mat mat){
        try {
            Mat gray=new Mat();
            Imgproc.cvtColor(mat,gray,Imgproc.COLOR_BGR2GRAY);
            int w=gray.cols();      //多少列
            int h=gray.rows();      // 多少行
            byte[] data=new byte[w*h];
            gray.get(0,0,data);
            Logger.e("-----:"+ Arrays.toString(data));
            int pv=0;
            for (int i=0;i<data.length;i++){
                pv=data[i]&0xff;
                if (pv!=17&pv!=-1){
                    pv=-1;
                }
                data[i]=(byte)pv;
            }
            gray.put(0,0,data);
            Imgproc.cvtColor(gray,mat,Imgproc.COLOR_GRAY2BGR);
        }catch (UnsatisfiedLinkError e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

for循环里面的表示是将矩形里所有除了黑色以外的颜色全部变成白色, 17表示黑色,-1表示白色

经过这一番处理之后,我们之前的dtsMat矩阵就去噪成功了。

三、将Mat变成Bitmap

Bitmap bitmap=Bitmap.createBitmap(dtsMat.width(),dtsMat.height(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dtsMat,bitmap);

然而需要注意的是,因为Mat默认像素排列顺序是BGR格式,但是Bitmap是RGB排列,如果中间没有经过转换那么显示的图片就会颜色错乱。

Mat RGB转BGR

  
   Mat mat1=new Mat();
   //先将BRGMat转成RGB格式,再转换成图片
   Imgproc.cvtColor(mat,mat1,Imgproc.COLOR_BGR2RGB);
   mat.release();

End

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值