gpt4 book ai didi

java - 使用OpenCV扫描文档

转载 作者:行者123 更新时间:2023-12-02 16:37:41 29 4
gpt4 key购买 nike

我正在使用类似于this的Android文档扫描仪。

我搜索了一下,发现可以使用OpenCV来实现,因此从OpenCV开始。

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

sample image

我正在使用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<MatOfPoint> contourList = findContours(thresholdMat, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
double maxArea = 0.0;
int maxAreaIdx = -1;
Collections.sort(contourList, new Comparator<MatOfPoint>() {
@Override
public int compare(MatOfPoint lhs, MatOfPoint rhs)
{
return Double.valueOf(Imgproc.contourArea(rhs)).compareTo(Imgproc.contourArea(lhs));
}
});

ArrayList<MatOfPoint> 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<MatOfPoint> findContours(Mat mat, int retrievalMode, int approximationMode)
{
ArrayList<MatOfPoint> contourList = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(mat, contourList, hierarchy, retrievalMode, approximationMode);
hierarchy.release();

return contourList;
}

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

获取此结果图像。

result image

请帮助我解决此问题。

最佳答案

您的问题是在资源非常有限的 Realm 。我实际上已经将您的代码粘贴到上面,因为我什至不知道从哪里开始。但是,您还没有包括此行Point[] foundPoints = sortPoints(points);中使用的 sortPoints()函数, thresholdVal xGap yGap 整数。他们是如何初始化的?通过共享其余代码,您将为我带来极大的帮助。谢谢。

关于java - 使用OpenCV扫描文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50699893/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com