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

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

你可能感兴趣的:(SLAM建图-Android,opencv,android,bitmap)