Java 无法获取透视图以获取正确的转换
已经尝试了在网上找到的所有选项。 坐标是正确的。向量的阶数相等。 我错过了什么Java 无法获取透视图以获取正确的转换,java,android,opencv,image-processing,perspective,Java,Android,Opencv,Image Processing,Perspective,已经尝试了在网上找到的所有选项。 坐标是正确的。向量的阶数相等。 我错过了什么 public void cropBtn(View view) { List<Point> corners=new ArrayList<>(); for (int i=0;i<4;i++) corners.add(new Point(cropPanel.corners[i].x,cropPanel.corners[i].y)); List<
public void cropBtn(View view) {
List<Point> corners=new ArrayList<>();
for (int i=0;i<4;i++)
corners.add(new Point(cropPanel.corners[i].x,cropPanel.corners[i].y));
List<Point> target=new ArrayList<>();
target.add(new Point(cropPanel.left,cropPanel.top));
target.add(new Point(cropPanel.right,cropPanel.top));
target.add(new Point(cropPanel.right,cropPanel.bottom));
target.add(new Point(cropPanel.left,cropPanel.bottom));
Mat trans=Imgproc.getPerspectiveTransform(Converters.vector_Point2f_to_Mat(corners), Converters.vector_Point2f_to_Mat(target));
Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8SC1);
Utils.bitmapToMat(bitmap, src);
Mat dst = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8SC1);
Imgproc.warpPerspective(src, dst, trans, dst.size());
Utils.matToBitmap(dst, bitmap);
image.setImageBitmap(bitmap);
cropPanel.reset();
}
public void cropBtn(视图){
列表角点=新的ArrayList();
对于(int i=0;i我认为您得到了错误的分数。因此,我建议尝试以下代码:
MatOfPoint2f thisContour2f = new MatOfPoint2f();
MatOfPoint2f approxContour2f = new MatOfPoint2f();
contours.get(maxI).convertTo(thisContour2f, CvType.CV_32FC2); // here contours is a List of MatOfPoint which you get from ImgProc.findContours() method.
Imgproc.approxPolyDP(thisContour2f, approxContour2f, Imgproc.arcLength(thisContour2f, true) * 0.01, true); // Approximates a polygonal curve(s) with the specified precision. since you have to detect document which is rectangle , you need to find four points
if (approxContour2f.size().height == 4) { // since we are detecting rectangle , check wether contours has 4 points
MatOfPoint2f rotatedMat = new MatOfPoint2f(contours.get(maxI).toArray());
RotatedRect boundingBox = Imgproc.minAreaRect(rotatedMat); // find RotatedRect from contours
double[] temp_double; // find four points
temp_double = approxContour2f.get(0, 0);
Point p1 = new Point(temp_double[0], temp_double[1]);
temp_double = approxContour2f.get(1, 0);
Point p2 = new Point(temp_double[0], temp_double[1]);
temp_double = approxContour2f.get(2, 0);
Point p3 = new Point(temp_double[0], temp_double[1]);
temp_double = approxContour2f.get(3, 0);
Point p4 = new Point(temp_double[0], temp_double[1]);
List<Point> source = new ArrayList<>();
source.add(p1);
source.add(p2);
source.add(p3);
source.add(p4);
Mat startM = Converters.vector_Point2f_to_Mat(source);
` Mat result = warp(mRgba, startM, boundingBox.boundingRect()); // mrgba is a original mat
}
MatOfPoint2f thisContour2f=新的MatOfPoint2f();
MatOfPoint2f ApproxOnTour2F=新的MatOfPoint2f();
contours.get(maxI).convertTo(thisContour2f,CvType.cv32fc2);//这里是从ImgProc.findContours()方法获得的MatOfPoint列表。
Imgproc.approxPolyDP(thisContour2f,ApproxOnTour2f,Imgproc.arcLength(thisContour2f,true)*0.01,true);//以指定精度近似多边形曲线。由于必须检测矩形文档,因此需要找到四个点
如果(approxContour2f.size().height==4){//因为我们正在检测矩形,请检查轮廓是否有4个点
MatOfPoint2f rotatedMat=新的MatOfPoint2f(courts.get(maxI.toArray());
RotatedRect boundingBox=Imgproc.minareRect(rotatedMat);//从等高线查找RotatedRect
double[]temp_double;//找到四个点
temp_double=approxContour2f.get(0,0);
点p1=新点(温度双精度[0],温度双精度[1]);
temp_double=approxContour2f.get(1,0);
点p2=新点(温度双精度[0],温度双精度[1]);
temp_double=approxContour2f.get(2,0);
点p3=新点(温度双精度[0],温度双精度[1]);
temp_double=approxContour2f.get(3,0);
点p4=新点(温度双精度[0],温度双精度[1]);
列表源=新的ArrayList();
来源.添加(p1);
来源:add(p2);
来源.添加(p3);
来源.增加(第4页);
Mat startM=转换器。矢量点2f到Mat(源);
`Mat result=warp(mRgba,startM,boundingBox.boundingRect());//mRgba是原始Mat
}
现在,您可以从下面的warp()函数透视它:
public Mat warp(Mat inputMat, Mat startM, Rect rect) {
int resultWidth = rect.width;
int resultHeight = rect.height;
Point ocvPOut4, ocvPOut1, ocvPOut2, ocvPOut3;
ocvPOut1 = new Point(0, 0);
ocvPOut2 = new Point(0, resultHeight);
ocvPOut3 = new Point(resultWidth, resultHeight);
ocvPOut4 = new Point(resultWidth, 0);
Mat outputMat = new Mat(resultWidth, resultHeight, CvType.CV_8UC4);
List<Point> dest = new ArrayList<Point>();
dest.add(ocvPOut1);
dest.add(ocvPOut2);
dest.add(ocvPOut3);
dest.add(ocvPOut4);
Mat endM = Converters.vector_Point2f_to_Mat(dest);
Mat perspectiveTransform = Imgproc.getPerspectiveTransform(startM, endM);
Imgproc.warpPerspective(inputMat, outputMat, perspectiveTransform, new Size(resultWidth, resultHeight), Imgproc.INTER_CUBIC);
return outputMat;
}
public Mat-warp(Mat-inputMat、Mat-startM、Rect-Rect){
int resultWidth=rect.width;
int resultHeight=rect.height;
点ocvPOut4、ocvPOut1、ocvPOut2、ocvPOut3;
ocvPOut1=新点(0,0);
ocvPOut2=新点(0,结果右侧);
ocvPOut3=新点(结果宽度、结果宽度);
ocvPOut4=新点(结果宽度,0);
Mat outputMat=新Mat(结果宽度、结果宽度、CvType.CV_8UC4);
List dest=new ArrayList();
目的地添加(ocvPOut1);
目的地添加(ocvPOut2);
目的地添加(ocvPOut3);
目的地添加(ocvPOut4);
Mat endM=转换器。向量点2f到Mat(dest);
Mat perspectiveTransform=Imgproc.getPerspectiveTransform(startM,endM);
Imgproc.warpPerspective(输入框、输出框、透视变换、新大小(resultWidth、ResultWight)、Imgproc.INTER_立方体);
返回输出矩阵;
}
希望能有所帮助!!经过几个小时的努力,终于找到了问题所在
就在这里发吧。也许能帮到我这种情况的人
问题是:我使用了视图的坐标。并且需要位图的坐标。这使得扭曲行为完全疯狂。因此,刚刚将视图坐标转换为位图。现在它非常完美:
float xRatio=(float)bitmap.getWidth()/cropPanel.getWidth();
float yRatio=(float)bitmap.getHeight()/cropPanel.getHeight();
for (int i=0;i<4;i++)
corners.add(new Point(cropPanel.corners[i].x*xRatio,cropPanel.corners[i].y*yRatio);
List<Point> target=new ArrayList<>();
target.add(new Point(0,0));
target.add(new Point(bitmap.getWidth(),0));
target.add(new Point(bitmap.getWidth(),bitmap.getHeight()));
target.add(new Point(0,bitmap.getHeight()));
float xRatio=(float)bitmap.getWidth()/cropPanel.getWidth();
float yRatio=(float)bitmap.getHeight()/cropPanel.getHeight();
对于(In i=0;In您打印出在代码中的点的坐标),在这个场景中,代码> >角>代码>,并将它们添加到问题中。在C++ OpenCV中,当将小的点列表转换成垫时,有时会有一些模糊性。在java中没有API可以直接提供这些点作为列表而不是转换为MAT?例如:位图/视图大小(9241353)角点({382483},{858578},{6561292},{1011152})目标({60,60},{864,60},{8641293},{601293})