OpenCv Android常用的图像操作

项目中使用OpenCv Android SDK(版本4.5.4)进行图像处理,支持的操作很全且效果佳,对于其中的一些图像操作方法记录如下:
  • Mat与Bitmap

Mat是OpenCv中用来存储图像信息的内存对象,内部还包括图像的宽、高、类型、维度、大小、深度等信息。

int width = srcMat.cols();
int height = srcMat.rows();
int dims = srcMat.dims(); //维度
int channels = srcMat.channels();
int depth = srcMat.depth();
int type = srcMat.type();

Bitmap是Android在RGB上的色彩空间,与Mat对象相似。

//一顿Mat操作后可转换到Android Bitmap对象
Bitmap dstBitmap = Bitmap.createBitmap(dstMat.width(), dstMat.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, dstBitmap);
  • 加载本地图像
String path = Environment.getExternalStorageDirectory().getPath() + File.separator + "test.png";
//本地载入
Mat srcMat = Imgcodecs.imread(path);
//Android Resource载入
Mat srcMat = Utils.loadResource(context, R.drawable.test, Imgcodecs.IMREAD_COLOR);          
  • 图像缩放
double ratio = (input_shape * 1.0) / Math.max(imgWH[0], imgWH[1]); //[h,w]数组
Size newSize = new Size(Math.round(imgWH[1] * ratio), Math.round(imgWH[0] * ratio));
//缩放成新的大小
Imgproc.resize(srcMat, dstMat, newSize);
  • 图像翻转与镜像
//根据第三个参数flipCode可实现图像的垂直、水平以及同时垂直镜像翻转
Core.flip(dstMat, dstMat, 1); //水平翻转镜像,resize后再处理翻转较快
  • 图像裁剪
Rect rect = new Rect((int) (rectF.left), (int) (rectF.top), (int) (rectF.right - rectF.left), (int) (rectF.bottom - rectF.top));
//根据Rect区域裁剪生成新的Mat对象
Mat cropMat = new Mat(bgrMat, rect);
  • 图像边界扩充
Scalar padColor = new Scalar(0, 0, 0);
//填充类型borderType参数,CONSTANT代表用固定像素值填充
Core.copyMakeBorder(dstMat, dstMat, 0, dh, 0, dw, Core.BORDER_CONSTANT, padColor);
  • 颜色格式转化
//获取YUV NV21格式数据
Mat yuvMat = new Mat(imgWH[0] * 3 / 2, imgWH[1], CvType.CV_8UC1);
yuvMat.put(0, 0, yuvData);
Mat bgrMat = new Mat();
Imgproc.cvtColor(yuvMat, bgrMat, Imgproc.COLOR_YUV2BGR_NV21);

//本地默认读取的是BGR格式图片,最后转换成RGB格式
Imgproc.cvtColor(dstMat, dstMat, Imgproc.COLOR_BGR2RGB);

//生成灰度图
Imgproc.cvtColor(srcMat, grayMat, Imgproc.COLOR_BGR2GRAY);
  • 通道分离
//从Mat分离出每个像素对应的R,G.B三个通道值进行像素归一化处理
ArrayList<Mat> mats = new ArrayList<>(dstMat.channels());
Core.split(dstMat, mats); //通道分离
outImage.rewind();
for (int i = 0; i < mats.size(); i++) {
	Mat channelMat = mats.get(i);
    byte[] data = new byte[channelMat.width() * channelMat.height() * channelMat.channels()];
    channelMat.get(0, 0, data);
    int pixelValue;
    for (int j = 0; j < data.length; j++) {
		pixelValue = data[j] & 0xff;
        outImage.putFloat(pixelValue / 255.0f);
	}
	channelMat.release();
}
  • 图像像素值统计
//截取ROI区域内的所有像素进行均值和标准差计算
Mat rangeMat = new Mat(dstMat, new Range(0, 8), new Range(0, 8));
MatOfDouble means = new MatOfDouble();
MatOfDouble stddevs = new MatOfDouble();
Core.meanStdDev(rangeMat, means, stddevs);
  • 像素归一化
    将像素值经过处理后限制在一定范围内,方便后续数据处理。
//线性归一化到(0, 1)区间
Core.normalize(dstMat, dstMat, 0, 1, Core.NORM_MINMAX);
  • 读取视频流
VideoCapture capture = new VideoCapture();
String path = Environment.getExternalStorageDirectory().getPath() + File.separator + "output.mp4";
capture.open(path);
while (capture.isOpened()) {
	Mat frameMat = new Mat();
	boolean ret = capture.read(frameMat);
	if (ret) {
		//做业务处理
	}
}

猜你喜欢

转载自blog.csdn.net/qq_23069607/article/details/124497319