04_OpenCv像素取反

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gzx110304/article/details/82941278

OpenCv像素取反

一.Mat像素取反

1.将bitmap对象转换为mat对象
2.通过Mat对象的cols()方法和rows()方法,获取图片的宽高
3.获取图片的通道数
4.分配一个字节数组,其长度为图片的通道数
5.循环遍历Mat对象的对应行列上的像素信息
6.取出对应行列上的像素信息,赋给字节数组
7.通过遍历字节数组,对图片的每一个通道都进行取反
8.将取反后的像素重新设置回Mat对象

//1.将bitmap对象转换为mat对象
Mat src = new Mat();
Utils.bitmapToMat(bitmap, src);
//2.通过Mat对象的cols()方法和rows()方法,获取图片的宽高
int width = src.cols();
int height = src.rows();
//3.获取图片的通道数
int cnum = src.channels();
//4.分配一个字节数组,其长度为图片的通道数
byte[] bgra = new byte[cnum];
//5.循环遍历Mat对象的对应行列上的像素信息
for(int row=0; row<height; row++) {
  for(int col=0; col<width; col++) {
      //6.取出对应行列上的像素信息,赋给字节数组
      src.get(row, col, bgra);
      //7.对图片的每一个通道都进行取反
      for(int i=0; i<cnum; i++) {
          bgra[i] = (byte) (255 - bgra[i]&0xff);
      }
      //8.将取反后的像素重新设置回Mat对象
      src.put(row, col, bgra);
  }
}
//9.将像素取反后的Mat对象转换为Bitmap对象
Utils.matToBitmap(src, bitmap);

二.Bitmap像素取反

1.在android中通过Bitmap去操作像素的时候,必须保证Bitmap对象的isMutable属性为true,否则抛出java.lang.IllegalStateException
2.开辟像素缓冲区(int数组),其长度为(bitmap的宽度 * bitmap的高度)
3.将所有像素取到缓冲区中
4.通过pixel遍历每一个像素,并对每一个像素进行取反
a = (pixel>>24)&0xff;
r = (pixel>>16)&0xff;
g = (pixel>>8)&0xff;
b = (pixel)&0xff;

r = 255-r;
g = 255-g;
b = 255-b;

pixel = ((a&0xff)<<24) | ((r&0xff)<<16) | ((g&0xff)<<8) | (b&0xff);
5.将取反后的像素缓冲区重新设置给Bitmap对象

int width = bitmap.getWidth();
int height = bitmap.getHeight();

//1.开辟像素缓冲区(int数组),其长度为(bitmap的宽度 * bitmap的高度)
int[] pixels = new int[width * height];
//2.将所有像素取到缓冲区中
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
//3.通过pixel遍历每一个像素,并对每一个像素进行取反
int a = 0, r = 0, g = 0, b = 0;
for(int i=0; i<pixels.length; i++) {
  int pixel = pixels[i];
  a = (pixel >> 24) & 0xff;
  r = (pixel >> 16) & 0xff;
  g = (pixel >> 8) & 0xff;
  b = pixel & 0xff;

  a = 255 - a;
  r = 255 - r;
  g = 255 - g;
  b = 255 - b;

  pixel = ((a&0xff) << 24) | ((r&0xff) << 16) | ((g&0xff) << 8) | (b&0xff);
  pixels[i] = pixel;
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);

三.按位取反

Core.bitwise_not(src, dst)

Mat src = new Mat();
Utils.bitmapToMat(temp, src);
Core.bitwise_not(src, src);
Utils.matToBitmap(src, temp);

四.减法取反

通过将一个纯白色的矩阵与待取反的矩阵相减,也能实现取反

Mat src = new Mat();
Utils.bitmapToMat(bitmap, src);
Mat white = new Mat(src.size(), src.type(), Scalar.all(255));
Core.subtract(white, src, src);
Utils.matToBitmap(src, bitmap);

五.总结

1.遍历Bitmap中像素的正确方法是,先开辟缓冲区取出像素数组之后,进行像素操作,再重新设回到Bitmap中,不要尝试通过Bitmap.getPixel(x,y)和Bitmap.setPixel(x,y)进行像素操作
2.在android中,不要尝试直接遍历Mat对象中的每一个像素

猜你喜欢

转载自blog.csdn.net/gzx110304/article/details/82941278