功能需求: 消除机器人激光雷达生成的图片上的噪点。类似于美图秀秀的去水印,将某一片的像素改成图片背景色
整体思路
- 将图片转换成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