java图像矫正_Java基于opencv—透视变换矫正图像

更新时间:2023-06-08 23:37:53 阅读: 评论:0

java图像矫正_Java基于opencv—透视变换矫正图像
很多时候我们拍摄的照⽚都会产⽣⼀点畸变的,就像下⾯的这张图
虽然不是很明显,但还是有⼀点畸变的,⽽我们要做的就是把它变成下⾯的这张图
效果看起来并不是很好,主要是四个顶点找的不准确,会有⼀些偏差,⽽且矫正后产⽣的⽬标图是倒着的,哪位好⼼⼈给说说为啥
因为我也没有测试畸变很⼤的图像,也不能保证⽅法适⽤于每个图像,这⾥仅提供我的思路供⼤家参考。
思路:
我们最重要的就是找到图像的四个顶点,有利⽤hough直线,求直线交点确定四个顶点,有采⽤寻找轮廓确定四个顶点等等;今天我提供的思路,也是采⽤寻找轮廓的⽅法,⽤approxPolyDP函数,对图像轮廓点进⾏多边形拟合,可以得到⼤概的⼀个这样的图
可以看到图像的四个顶点处,都有⼩⽩点。接下来我们要做的就是把这些点归类,即划分出四个区域[左上,右上,右下,左下];我采⽤的是利⽤opencv的寻找轮廓,得到最⼤轮廓,然后⽣成最⼩外接矩形,确定四个顶点的⼤致位置;然后设置⼀个阀值,与上图中的点集合求距离,⼤于阀值的舍弃,⼩于的保留,可以得到如下的图像
这样所有的点集都落到了四个区域,利⽤矩形中,对⾓线距离最⼤,确定四个顶点的位置,发现效果并不是很好,如下图
到此四个顶点的位置⼤概的确定了,就只需要根据输⼊和输出点获得图像透视变换的矩阵,然后透视变换;
我们把思路再理⼀下:
1、寻找图像的四个顶点的坐标(重要)
思路: 1、canny描边 2、寻找最⼤轮廓 3、对最⼤轮廓点集合逼近,得到轮廓的⼤致点集合 4、把点击划分到四个区域中,即左上,右上,左下,右下 5、根据矩形中,对⾓线最长,找到矩形的四个顶点坐标
2、根据输⼊和输出点获得图像透视变换的矩阵
3、透视变换
我们来跟着思路实现⼀下代码
1、canny描边
/**
* canny算法,边缘检测
*
* @param src
* @return
*/
高铁能带香水吗public static Mat canny(Mat src) {
Mat mat = src.clone();
Imgproc.Canny(src, mat, 60, 200);
HandleImgUtils.saveImg(mat, "C:/Urs/admin/Desktop/opencv/open/x/canny.jpg");
return mat;
}
2、寻找最⼤轮廓;的日记
煎元宵3、对最⼤轮廓点集合逼近,得到轮廓的⼤致点集合(代码中有很多冗余,后期会进⾏优化)
/**
网络怎么连接
* 利⽤函数approxPolyDP来对指定的点集进⾏逼近 精确度设置好,效果还是⽐较好的
*
* @param cannyMat
*/
public static Point[] uApproxPolyDPFindPoints(Mat cannyMat) {
全脑开发课程List contours = new ArrayList();
Mat hierarchy = new Mat();
测孕纸准确率高吗// 寻找轮廓
Imgproc.findContours(cannyMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE, new Point(0, 0));
// 找出匹配到的最⼤轮廓
double area = Imgproc.(0)).area();
int index = 0;
// 找出匹配到的最⼤轮廓
for (int i = 0; i < contours.size(); i++) {
提解double tempArea = Imgproc.(i)).area();
if (tempArea > area) {
area = tempArea;
index = i;
}
}
MatOfPoint2f approxCurve = new MatOfPoint2f();
MatOfPoint2f matOfPoint2f = new (index).toArray());
/
/ 原始曲线与近似曲线之间的最⼤距离设置为0.01,true表⽰是闭合的曲线
Imgproc.approxPolyDP(matOfPoint2f, approxCurve, 0.01, true);
Point[] points = Array();
return points;
}
获取四个顶点的参照点
/**
* 获取四个顶点的参照点,返回Point数组[左上,右上,右下,左下] 思路: 我们可以把四个点分成两部分,左部分,右部分
* 左部分:⾼的为左上,低的为左下(⾼低是以⼈的视觉) 右部分同理 ⾸先我们找到最左和最右的位置,以它们的两个中间为分界点,* 靠左的划分到左部分,靠右的划分到右部分 如果⼀个区域有三个或更多,哪个⽐较靠近分界线,划分到少的那个区域
*
* @param cannyMat
* @return
*/
public static Point[] findReferencePoint(Mat cannyMat) {
RotatedRect rect = findMaxRect(cannyMat);
Point[] referencePoints = new Point[4];
rect.points(referencePoints);
double minX = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE;
for (int i = 0; i < referencePoints.length; i++) {
referencePoints[i].x = Math.abs(referencePoints[i].x); referencePoints[i].y = Math.abs(referencePoints[i].y);
minX = referencePoints[i].x < minX ? referencePoints[i].x : minX; maxX = referencePoints[i].x > maxX ? referencePoints[i].x : maxX; }
double center = (minX + maxX) / 2;
List leftPart = new ArrayList();
List rightPart = new ArrayList();
// 划分左右两个部分
for (int i = 0; i < referencePoints.length; i++) {
if (referencePoints[i].x < center) {
leftPart.add(referencePoints[i]);
} el if (referencePoints[i].x > center) {
rightPart.add(referencePoints[i]);
} el {
if (leftPart.size() < rightPart.size()) {
leftPart.add(referencePoints[i]);
} el {
rightPart.add(referencePoints[i]);
}
}
}
double minDistance = 0;
int minIndex = 0;
if (leftPart.size() < rightPart.size()) {
// 左部分少
minDistance = (0).x - center;
minIndex = 0;
for (int i = 1; i < rightPart.size(); i++) {
if ((i).x - center < minDistance) {
minDistance = (i).x - center;
minIndex = i;
}
}
leftPart.ve(minIndex));
} el if (leftPart.size() > rightPart.size()) {
// 右部分少
minDistance = center - (0).x;
minIndex = 0;
for (int i = 1; i < leftPart.size(); i++) {
if (center - (0).x < minDistance) {
minDistance = center - (0).x;
minIndex = i;
}
}
rightPart.ve(minIndex));
}
if ((0).y < (1).y) {
referencePoints[0] = (0);
referencePoints[3] = (1);
}
if ((0).y < (1).y) {
referencePoints[1] = (0);
referencePoints[2] = (1);
}
return referencePoints;
}
4、把点击划分到四个区域中,即左上,右上,右下,左下(效果还可以) /**
* 把点击划分到四个区域中,即左上,右上,右下,左下
*
* @param points
* 逼近的点集
* @param referencePoints
游子吟的翻译

本文发布于:2023-06-08 23:37:53,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/906519.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:顶点   轮廓   划分
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图