首先导入依赖库
implementation 'com.quickbirdstudios:opencv:3.4.4-contrib'
使用相关方法前需要先对opencv进行初始化,初始化之后才能调用其内部函数
//初始化结果
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this)
{
@Override
public void onManagerConnected(int status)
{
super.onManagerConnected(status);
if (status == LoaderCallbackInterface.SUCCESS)
{
Log.d("控制台调试1", "OpenCV library init success");
}
}
};
//开始初始化
private void initOpenCV()
{
if (!OpenCVLoader.initDebug())
{
Log.d("控制台调试1", "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, mLoaderCallback);
}
else
{
Log.d("控制台调试1", "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
标定棋盘格,标准象棋棋盘cvSize是(7,7)
相机标定部分代码,开始校准前需要先将棋盘格打印出来,并在各个角度对其进行拍摄(拍摄20张左右)。
/**
* 内参、畸变参数获取
*/
public void getCalibratorParams()
{
//内参
Mat mCameraMatrix = new Mat();
//畸变参数
Mat mDistortionCoefficients = new Mat();
Log.i("视觉识别测试", "calibarator: 发现与绘制棋盘格");
//标定文件位置(拍摄好的棋盘格图片放置到特定位置)
String path = GlobalConstant.BLOCK_CHECK_MEDIA_SAVE_LOCAL_PATH;
File resourceFile = new File(path);
File dir = new File(path + "处理后/");
if (!dir.exists())
{
dir.mkdirs();
}
if (!resourceFile.exists() || resourceFile.length() == 0)
{
ToastUtils.show("文件不存在!");
return;
}
//校准棋盘格 内角点数量(横向)
int numCornersHor = 7;
//校准棋盘格 内角点数量(纵向)
int numCornersVer = 7;
//校准棋盘格 正方形边长(厘米)
float mSquareSize = 2.2f;
File[] files = resourceFile.listFiles();
ArrayList<Mat> objectPoints = new ArrayList<>(); //角点位于物体坐标平面
ArrayList<Mat> imagePoints = new ArrayList<>();
MatOfPoint3f obj = new MatOfPoint3f();
try
{
for (int i = 1; i <= numCornersHor; i++)
{
for (int j = 1; j <= numCornersVer; j++)
{
//厘米度量
obj.push_back(new MatOfPoint3f(new Point3((double) j * mSquareSize, (double) i * mSquareSize, 0.0)));
}
}
}
catch (Exception e)
{
Log.i("视觉识别测试", "calibarator崩溃点1: " + e.getMessage());
}
List<Mat> mCornersBuffer = new ArrayList<>();
// 发现棋盘格与绘制
Size s = new Size();
try
{
for (File file : files)
{
if (file.isFile())
{
Log.i("视觉识别测试", "calibarator: image file:" + file.getName());
Mat image = Imgcodecs.imread(path + file.getName());
s = image.size();
Mat gray = new Mat();
Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGRA2GRAY); //灰度处理
Imgproc.threshold(gray, gray, 100, 255, Imgproc.THRESH_TOZERO);
Imgcodecs.imwrite(path + "处理后/" + "二值化" + file.getName(), gray);
MatOfPoint2f corners = new MatOfPoint2f(); //角向量已经检测到的标记角。对于每个标记,它的四个角被提供
/*
* gray 灰度图
* size 每行每列内角点,正常7*7
* corners 存储角点位置的数组指针
* 定义额外滤波步长以帮助寻找角点
*/
boolean ret = Calib3d.findChessboardCorners(gray, new Size(numCornersHor, numCornersVer), corners, Calib3d.CALIB_CB_ADAPTIVE_THRESH | Calib3d.CALIB_CB_FILTER_QUADS);
Log.i("视觉识别测试", "calibrator1");
if (ret)
{
Imgproc.cornerSubPix(gray, corners, new Size(11, 11), new Size(-1, -1), new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER, 30, 0.1));
Log.i("视觉识别测试", "calibrator2");
/*
* image 欲绘制的图像,彩色
* size 每行每列内角点,正常7*7
* corners 存储角点位置的数组指针
* ret 是否成功找到角点
*/
Calib3d.drawChessboardCorners(gray, new Size(numCornersHor, numCornersVer), corners, ret);
Log.i("视觉识别测试", "calibrator3");
imagePoints.add(corners);
objectPoints.add(obj);
mCornersBuffer.add(corners.clone());
Log.i("视觉识别测试", "calibrator4");
Imgcodecs.imwrite(path + "处理后/" + "棋盘绘制" + file.getName(), gray);
Log.i("视觉识别测试", "calibrator5");
}
}
}
}
catch (Exception e)
{
Log.i("视觉识别测试", "calibarator崩溃点2: " + e.getMessage());
}
try
{
Log.i("视觉识别测试", "calibarator: 相机矫正");
// 相机校正
Mat.eye(3, 3, CvType.CV_64FC1).copyTo(mCameraMatrix);
mCameraMatrix.put(0, 0, 1.0);
mCameraMatrix.put(1, 1, 1.0);
ArrayList<Mat> rvecs = new ArrayList<>();
ArrayList<Mat> tvecs = new ArrayList<>();
/*
* objects: 棋盘格坐标系,由棋盘格真是坐标生成,以左上角为顶点建立,Z为0。
* imagePoints: 图片识别到的角点坐标,与objectPoints中的值一一对应。
* cameraMatrix: 相机内参
* distCoeffs: 相机畸变
* rvec: 标定板坐标系到相机坐标系的旋转向量,可用cv::Rodrigues()变为旋转矩阵
* tvec: 标定板坐标系到相机坐标系的旋转矩阵
* */
Calib3d.calibrateCamera(objectPoints, mCornersBuffer, s, mCameraMatrix, mDistortionCoefficients, rvecs, tvecs, 0);
Log.i("视觉识别测试", "calibarator内参: " + mCameraMatrix.dump());
Log.i("视觉识别测试", "calibarator畸变参: " + mDistortionCoefficients.dump());
ToastUtils.show("镜头参数获取完成!");
}
catch (Exception e)
{
Log.i("视觉识别测试", "calibarator崩溃点3: " + e.getMessage());
}
}