我正在尝试渲染相机预览帧上的最大轮廓。这是我的代码:
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
previewSize = cameraConfigUtil.cameraInstance.getParameters().getPreviewSize();
Mat srcMat = new Mat(previewSize.height, previewSize.width, CvType.CV_8UC3);
srcMat.put(0, 0, data);
rect = ImageCorrection.getLargestContour(data, previewSize.height, previewSize.width);
android.graphics.Rect rectangle = new android.graphics.Rect();
rectangle.left = rect.x;
rectangle.top = rect.y;
rectangle.right = rect.x + rect.width;
rectangle.bottom = rect.y + rect.height;
mOverlay.clear();
BarcodeGraphic graphic = new BarcodeGraphic(mOverlay);
mOverlay.add(graphic);
graphic.updateItem(rectangle);
Imgproc.rectangle(srcMat, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(255, 0, 0, 255), 3);
Utils.matToBitmap(srcMat, bitmap);
}
它会检测轮廓但是当我将其添加到叠加层时,框不会放在文档上,并且边界矩形看起来更小。我正在使用预览框架中的原始数据。我错过了什么?基本上,检测到的最大轮廓与实际预览尺寸无关。
public static Rect getLargestContour(byte[] data, int height, int width) {
Mat srcMat = new Mat(height, width, CvType.CV_8UC3);
srcMat.put(0, 0, data);
Mat imgSource = new Mat(srcMat.size(), CvType.CV_8UC1);
Imgproc.cvtColor(srcMat, imgSource, Imgproc.COLOR_RGB2GRAY, 4);
Imgproc.GaussianBlur(imgSource, imgSource, new org.opencv.core.Size(5, 5), 0);
Imgproc.Canny(imgSource, imgSource, 50, 50);
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
Imgproc.cvtColor(imgSource, srcMat, Imgproc.COLOR_GRAY2RGB, 4);
double maxArea = -1;
Log.d("size", Integer.toString(contours.size()));
MatOfPoint temp_contour;
MatOfPoint2f approxCurve = new MatOfPoint2f();
for (MatOfPoint contour : contours) {
double contourarea = Imgproc.contourArea(contour);
if (contourarea > 0
&& contourarea > maxArea) {
//check if this contour is a square
MatOfPoint2f new_mat = new MatOfPoint2f(contour.toArray());
int contourSize = (int) contour.total();
MatOfPoint2f approxCurve_temp = new MatOfPoint2f();
Imgproc.approxPolyDP(new_mat, approxCurve_temp, contourSize * 0.05, true);
if (approxCurve_temp.total() == 4) {
maxArea = contourarea;
approxCurve = approxCurve_temp;
}
}
}
MatOfPoint points = new MatOfPoint(approxCurve.toArray());
return Imgproc.boundingRect(points);
}
这是opencv正在考虑的图像尺寸。
答案 0 :(得分:1)
所以终于找到了问题: 在这里
Mat srcMat = new Mat(height, width, CvType.CV_8UC3);
srcMat.put(0, 0, data);
我将YUV类型的数据放在一个CV_8U3的Mat中。它应该是CV_8U1。
Mat srcMat = new Mat(height, width, CvType.CV_8UC1);
srcMat.put(0, 0, data);
我们不需要将其转换为GRAYSCALE:
Mat imgSource = new Mat(srcMat.size(), CvType.CV_8UC1);
Imgproc.cvtColor(srcMat, imgSource, Imgproc.COLOR_RGB2GRAY, 4);