使用OpenCV扫描文档

我正在开发类似于此的 Android文档扫描程序。

我搜索了这个,发现这可以用OpenCV实现,所以从OpenCV开始。

我尝试了很多例子从图像中检测文档,但无法检测图像是否有浅色背景。 检查样品图像以进行测试。

样本图像

我正在使用OpenCV Android SDK并使用java代码进行图像处理。 这是代码:

public void scanDocument(Bitmap mBitmap) { Mat mOriginalMat = convertToMat(mBitmap); int mRatio = getRadio(mOriginalMat); Size mSize = getImageFitSize(mOriginalMat, mRatio); Mat resizedMat = resizeMat(mOriginalMat, mSize); Mat colorMat = grayMat(resizedMat, mSize); Mat blurMat = medianBlurMat(colorMat, mSize); Mat thresholdMat = cannyEdgeMat(blurMat, mSize); ArrayList contourList = findContours(thresholdMat, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); double maxArea = 0.0; int maxAreaIdx = -1; Collections.sort(contourList, new Comparator() { @Override public int compare(MatOfPoint lhs, MatOfPoint rhs) { return Double.valueOf(Imgproc.contourArea(rhs)).compareTo(Imgproc.contourArea(lhs)); } }); ArrayList contourListMax = new ArrayList(); for (int idx = 0; idx < contourList.size(); idx++) { MatOfPoint contour = contourList.get(idx); MatOfPoint2f c2f = new MatOfPoint2f(contour.toArray()); MatOfPoint2f approx = new MatOfPoint2f(); double epsilon = Imgproc.arcLength(c2f, true); Imgproc.approxPolyDP(c2f, approx, epsilon * 0.02, true); Point[] points = approx.toArray(); MatOfPoint approxTemp = new MatOfPoint(approx.toArray()); if (points.length == 4 && Imgproc.isContourConvex(approxTemp) && maxArea < Imgproc.contourArea(approxTemp)) { maxArea = Imgproc.contourArea(approxTemp); maxAreaIdx = idx; Point[] foundPoints = sortPoints(points); contourListMax.add(approxTemp); mPointFMap = new HashMap(); mPointFMap.put(0, new PointF((float) foundPoints[0].x + xGap, (float) foundPoints[0].y + yGap)); mPointFMap.put(1, new PointF((float) foundPoints[1].x + xGap, (float) foundPoints[1].y + yGap)); mPointFMap.put(2, new PointF((float) foundPoints[3].x + xGap, (float) foundPoints[3].y + yGap)); mPointFMap.put(3, new PointF((float) foundPoints[2].x + xGap, (float) foundPoints[2].y + yGap)); break; } } Imgproc.drawContours(resizedMat, contourListMax, -1, new Scalar(255, 165, 0), 2); showMatToImageView(resizedMat); } private Mat convertToMat(Bitmap bitmap) { Mat mat = Imgcodecs.imread(mFilePath);// new Mat(bitmap.getWidth(), bitmap.getHeight(), CvType.CV_8UC1); Imgproc.cvtColor(mat, mat, Imgproc.COLOR_BGR2RGB); return mat; } private double getRadio(Mat mat) { double ratio; if (mat.size().width > mat.size().height) ratio = mat.size().height / mMainLayout.getHeight(); else ratio = mat.size().width / mMainLayout.getWidth(); return ratio; } private Size getImageFitSize(Mat mat, double ratio) { int height = Double.valueOf(mat.size().height / ratio).intValue(); int width = Double.valueOf(mat.size().width / ratio).intValue(); return new Size(width, height); } private void showMatToImageView(Mat mat) { final Bitmap bitmap = Bitmap.createBitmap(mat.width(), mat.height(), Bitmap.Config.ARGB_8888); Utils.matToBitmap(mat, bitmap); runOnUiThread(new Runnable() { @Override public void run() { mSourceImageView.setImageBitmap(bitmap); mProgressBar.setVisibility(View.GONE); } }); } private Mat resizeMat(Mat mat, Size size) { Mat resizedMat = new Mat(size, CvType.CV_8UC4); Imgproc.resize(mat, resizedMat, size); return resizedMat; } private Mat grayMat(Mat mat, Size size) { Mat grayMat = new Mat(size, CvType.CV_8UC4); Imgproc.cvtColor(mat, grayMat, Imgproc.COLOR_RGB2GRAY, 4); return grayMat; } private Mat medianBlurMat(Mat mat, Size size) { Mat blurMat = new Mat(size, CvType.CV_8UC4); Imgproc.medianBlur(mat, blurMat, 3); return blurMat; } private Mat cannyEdgeMat(Mat mat, Size size) { if (thresholdVal <= 0) thresholdVal = 200; Mat cannyEdgeMat = new Mat(size, CvType.CV_8UC1); Imgproc.Canny(mat, cannyEdgeMat, thresholdVal * 0.5, thresholdVal, 3, true); return cannyEdgeMat; } private ArrayList findContours(Mat mat, int retrievalMode, int approximationMode) { ArrayList contourList = new ArrayList(); Mat hierarchy = new Mat(); Imgproc.findContours(mat, contourList, hierarchy, retrievalMode, approximationMode); hierarchy.release(); return contourList; } 

我想在透视变换的帮助下检测文档点我将文档转换为直接并进行其他图像过滤。

获得此结果图像。

结果图像

请帮我解决这个问题。