- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我认为之前有人问过这个问题,但我没有找到解决我的问题的示例或解决方案。我是 opencv 的新手,我想使用 OpenCV CameraPreview 进行纸张检测。在我的示例应用程序中,我使用带有静态初始化的 opencv 3.0.0。我知道对象识别可以通过以下步骤完成:
我现在的问题是我可以巧妙地模糊图像,但我不知道如何找到轮廓和矩形并用半透明颜色填充它们。
这是我当前的 onCameraFrame 函数:
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat input = inputFrame.rgba();
Mat output = input.clone();
Imgproc.Canny(input, output, 50, 50);
Imgproc.blur(output, output,new Size(5,5));
//Find Contours
//Search for biggest Contour/Rectangle
//Fill Rectangle with half transparent Color
return output;
}
谁能帮我解决纸张检测的问题并有android/java的代码示例?谢谢
最佳答案
以下代码来自Open Note Scanner我正在开发的应用程序,您可以使用它来查找更多信息。
函数 findDocument 将返回一个 Quadrilateral 对象,该对象封装了一个带有轮廓的 MatOfPoint 和一个带有各个点的 Point[]。您可以调用它并使用返回的对象调用 Imgproc.drawContours() 来完成您的图像。
所有代码都是以 this excellent tutorial from pyimagesearch 为基础编写的
注意:这是从我的代码中快速移植的方法,它没有语法错误,但我没有测试它。
package com.todobom.opennotescanner.views;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
public class detectDocument {
/**
* Object that encapsulates the contour and 4 points that makes the larger
* rectangle on the image
*/
public static class Quadrilateral {
public MatOfPoint contour;
public Point[] points;
public Quadrilateral(MatOfPoint contour, Point[] points) {
this.contour = contour;
this.points = points;
}
}
public static Quadrilateral findDocument( Mat inputRgba ) {
ArrayList<MatOfPoint> contours = findContours(inputRgba);
Quadrilateral quad = getQuadrilateral(contours);
return quad;
}
private static ArrayList<MatOfPoint> findContours(Mat src) {
double ratio = src.size().height / 500;
int height = Double.valueOf(src.size().height / ratio).intValue();
int width = Double.valueOf(src.size().width / ratio).intValue();
Size size = new Size(width,height);
Mat resizedImage = new Mat(size, CvType.CV_8UC4);
Mat grayImage = new Mat(size, CvType.CV_8UC4);
Mat cannedImage = new Mat(size, CvType.CV_8UC1);
Imgproc.resize(src,resizedImage,size);
Imgproc.cvtColor(resizedImage, grayImage, Imgproc.COLOR_RGBA2GRAY, 4);
Imgproc.GaussianBlur(grayImage, grayImage, new Size(5, 5), 0);
Imgproc.Canny(grayImage, cannedImage, 75, 200);
ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
Imgproc.findContours(cannedImage, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
hierarchy.release();
Collections.sort(contours, new Comparator<MatOfPoint>() {
@Override
public int compare(MatOfPoint lhs, MatOfPoint rhs) {
return Double.valueOf(Imgproc.contourArea(rhs)).compareTo(Imgproc.contourArea(lhs));
}
});
resizedImage.release();
grayImage.release();
cannedImage.release();
return contours;
}
private static Quadrilateral getQuadrilateral(ArrayList<MatOfPoint> contours) {
for ( MatOfPoint c: contours ) {
MatOfPoint2f c2f = new MatOfPoint2f(c.toArray());
double peri = Imgproc.arcLength(c2f, true);
MatOfPoint2f approx = new MatOfPoint2f();
Imgproc.approxPolyDP(c2f, approx, 0.02 * peri, true);
Point[] points = approx.toArray();
// select biggest 4 angles polygon
if (points.length == 4) {
Point[] foundPoints = sortPoints(points);
return new Quadrilateral(c, foundPoints);
}
}
return null;
}
private static Point[] sortPoints(Point[] src) {
ArrayList<Point> srcPoints = new ArrayList<>(Arrays.asList(src));
Point[] result = { null , null , null , null };
Comparator<Point> sumComparator = new Comparator<Point>() {
@Override
public int compare(Point lhs, Point rhs) {
return Double.valueOf(lhs.y + lhs.x).compareTo(rhs.y + rhs.x);
}
};
Comparator<Point> diffComparator = new Comparator<Point>() {
@Override
public int compare(Point lhs, Point rhs) {
return Double.valueOf(lhs.y - lhs.x).compareTo(rhs.y - rhs.x);
}
};
// top-left corner = minimal sum
result[0] = Collections.min(srcPoints, sumComparator);
// bottom-right corner = maximal sum
result[2] = Collections.max(srcPoints, sumComparator);
// top-right corner = minimal diference
result[1] = Collections.min(srcPoints, diffComparator);
// bottom-left corner = maximal diference
result[3] = Collections.max(srcPoints, diffComparator);
return result;
}
}
关于Android OpenCV 纸张检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31310315/
我正在尝试在我的 1.0 polymer 元素之一中实现纸张 slider ... 我得到的错误是: Uncaught TypeError: this.has
我还是 Vaadin 的新手,我正在尝试使用 Vaadin 14 实现 @polymenr/paper-slider 组件。 我已经下载了项目https://github.com/berndhopp/
我还是 Vaadin 的新手,我正在尝试使用 Vaadin 14 实现 @polymenr/paper-slider 组件。 我已经下载了项目https://github.com/berndhopp/
我正在尝试像这样实现页面 curl : 我遵循了这个例子:http://codepen.io/anon/pen/fpjoa 如果我创建新的 PHP 和 CSS 文件并从上面的链接复制粘贴代码,结果是正
我是一名优秀的程序员,十分优秀!