Commit 28742594 by 陈皓

init

parent 939d67f6
...@@ -30,8 +30,6 @@ import javax.imageio.ImageIO; ...@@ -30,8 +30,6 @@ import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
...@@ -424,24 +422,6 @@ public class ImgProcService { ...@@ -424,24 +422,6 @@ public class ImgProcService {
} }
/** /**
* 求数组平均数,四舍五入保留一位
*
* @param angelList 数组
* @return 数组平均数
*/
private static double avg(List<Integer> angelList) {
int sum = 0;
for (int i : angelList) {
sum += i;
}
if (sum == 0) {
return 0.0;
}
BigDecimal bigDecimal = new BigDecimal(sum).divide(new BigDecimal(angelList.size()), RoundingMode.HALF_UP);
return bigDecimal.setScale(1, RoundingMode.HALF_UP).doubleValue();
}
/**
* 求数组众数 * 求数组众数
* *
* @param angelList 数组 * @param angelList 数组
...@@ -601,7 +581,7 @@ public class ImgProcService { ...@@ -601,7 +581,7 @@ public class ImgProcService {
String newPath = filePath; String newPath = filePath;
// 3. 黑边处理 // 2. 黑边处理
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
String blackUrl = savePath + "(1)." + ext; String blackUrl = savePath + "(1)." + ext;
Mat aMat = Imgcodecs.imread(newPath); Mat aMat = Imgcodecs.imread(newPath);
...@@ -615,7 +595,7 @@ public class ImgProcService { ...@@ -615,7 +595,7 @@ public class ImgProcService {
aMat.release(); aMat.release();
log.info("黑边处理消耗的时间【{}】", System.currentTimeMillis() - start); log.info("黑边处理消耗的时间【{}】", System.currentTimeMillis() - start);
// 2. 执行纠偏 // 3. 执行纠偏
start = System.currentTimeMillis(); start = System.currentTimeMillis();
String deskerFile = savePath + "(2)." + ext; String deskerFile = savePath + "(2)." + ext;
......
...@@ -11,7 +11,7 @@ import java.util.Random; ...@@ -11,7 +11,7 @@ import java.util.Random;
/** /**
* <p> * <p>
* 去黑边(图像变换时会变更暗,需要进行亮度校正) * 去黑边
* </p> * </p>
* *
* @author chenhao * @author chenhao
......
package com.zq.processing.utils; package com.zq.processing.utils;
import cn.hutool.core.convert.Convert;
import lombok.Cleanup; import lombok.Cleanup;
import org.bytedeco.opencv.opencv_core.Mat; import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Point2f;
import org.bytedeco.opencv.opencv_core.Scalar4i;
import org.bytedeco.opencv.opencv_core.Size; import org.bytedeco.opencv.opencv_core.Size;
import org.bytedeco.opencv.opencv_core.UMat;
import org.bytedeco.opencv.opencv_imgproc.Vec4iVector; import org.bytedeco.opencv.opencv_imgproc.Vec4iVector;
import static org.bytedeco.opencv.global.opencv_core.CV_8UC3; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imread; import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imwrite;
import static org.bytedeco.opencv.global.opencv_imgproc.*; import static org.bytedeco.opencv.global.opencv_imgproc.*;
public class Deskew { public class Deskew {
public static void main(String[] args) { public static void main(String[] args) {
String testImg = "C:/Users/11419/Desktop/Deskew/TestImages/6.png"; String testImg = "C:/Users/11419/Desktop/Deskew/TestImages/4.png";
String resImg = "C:/Users/11419/Desktop/Deskew/TestImages/res.png"; String resImg = "C:/Users/11419/Desktop/Deskew/TestImages/res.png";
long start = System.currentTimeMillis();
@Cleanup @Cleanup
Mat src = imread(testImg); Mat mat = imread(testImg);
System.out.println(getDeskewAngle(mat));
System.out.println(System.currentTimeMillis() - start);
}
public static Integer getDeskewAngle(Mat src) {
// 图片灰度化 // 图片灰度化
@Cleanup @Cleanup
Mat gray = ImageUtil.gray(src); Mat gray = ImageUtil.gray(src);
...@@ -48,8 +57,6 @@ public class Deskew { ...@@ -48,8 +57,6 @@ public class Deskew {
Mat canny = dilate.clone(); Mat canny = dilate.clone();
Canny(dilate, canny, 50, 150); Canny(dilate, canny, 50, 150);
imwrite(resImg, canny);
// 霍夫变换得到线条 // 霍夫变换得到线条
@Cleanup @Cleanup
Vec4iVector lines = new Vec4iVector(); Vec4iVector lines = new Vec4iVector();
...@@ -61,54 +68,87 @@ public class Deskew { ...@@ -61,54 +68,87 @@ public class Deskew {
double maxLineGap = 200; double maxLineGap = 200;
// 霍夫变换,通过步长为1,角度为PI/180来搜索可能的直线 // 霍夫变换,通过步长为1,角度为PI/180来搜索可能的直线
HoughLinesP(canny, lines, 1, Math.PI / 180, threshold, minLineLength, maxLineGap); HoughLinesP(canny, lines, 1, Math.PI / 180, threshold, minLineLength, maxLineGap);
// 计算倾斜角度
List<Integer> angelList = new ArrayList<>();
for (int i = 0; i < lines.size(); i++) {
Scalar4i scalar4i = lines.get(0);
int k = calculateAngle(scalar4i.get(0), scalar4i.get(1), scalar4i.get(2), scalar4i.get(3));
angelList.add(k);
}
if (angelList.isEmpty()) {
return 0;
}
return most(angelList);
} }
public static void getDeskewAngle(String filePath) { /**
@Cleanup * 求数组众数
Mat src = imread(filePath); *
UMat usrc = src.getUMat(CV_8UC3); * @param angelList 数组
* @return 数组众数
*/
private static int most(List<Integer> angelList) {
if (angelList.isEmpty()) {
return 0;
}
int res = 0;
int max = Integer.MIN_VALUE;
Map<Integer, Integer> map = new HashMap<>();
for (int i : angelList) {
map.put(i, map.getOrDefault(i, 0) + 1);
}
for (Integer i : map.keySet()) {
int count = map.get(i);
if (count > max) {
max = count;
res = i;
}
}
return res;
}
// 图片灰度化 /**
@Cleanup * 计算直线的倾斜角
UMat gray = ImageUtil.gray(usrc); */
private static int calculateAngle(double x1, double y1, double x2, double y2) {
if (Math.abs(x2 - x1) < 1e-4) {
return 90;
} else if (Math.abs(y2 - y1) < 1e-4) {
return 0;
} else {
double k = -(y2 - y1) / (x2 - x1);
double res = Math.atan(k) * 57.29577;
return Convert.toInt(Math.round(res));
}
}
// // 高斯模糊(?) /**
// @Cleanup * 图片旋转
// UMat blur = gray.clone(); *
// GaussianBlur(gray, blur, new Size(9, 9), 0); * @param image 输入图片
// // 二值化(?) * @param angle 旋转角度
// @Cleanup * @return 输出图片
// UMat thresh = blur.clone(); */
// threshold(blur, thresh, 0, 255, THRESH_BINARY_INV + THRESH_OTSU); public static Mat rotate(Mat image, int angle) {
int w = image.cols();
int h = image.rows();
@Cleanup // 定义参数
Mat kernel = getStructuringElement(MORPH_RECT, new Size(5, 5)); double scale = 1.0;
// 图片膨胀
UMat erode = gray.clone();
erode(gray, erode, kernel.getUMat(CV_8UC3));
// 图片腐蚀
@Cleanup
UMat dilate = erode.clone();
dilate(erode, dilate, kernel.getUMat(CV_8UC3));
// 边缘检测
@Cleanup @Cleanup
UMat canny = dilate.clone(); Point2f center = new Point2f((float) w / 2, (float) h / 2);
Canny(dilate, canny, 50, 150);
// 霍夫变换得到线条 // 定义旋转矩阵
@Cleanup @Cleanup
Vec4iVector lines = new Vec4iVector(); Mat rotationMatrix = getRotationMatrix2D(center, -angle, scale);
//累加器阈值参数,小于设置值不返回
int threshold = 30;
//最低线段长度,低于设置值则不返回
double minLineLength = 0;
//间距小于该值的线当成同一条线
double maxLineGap = 200;
// 霍夫变换,通过步长为1,角度为PI/180来搜索可能的直线
HoughLinesP(canny.getMat(CV_8UC3), lines, 1, Math.PI / 180, threshold, minLineLength, maxLineGap);
// 旋转矩阵
Mat rotatedImage = new Mat();
warpAffine(image, rotatedImage, rotationMatrix, new Size(w, h));
return rotatedImage;
} }
......
mvn install:install-file -Dfile=./opencv-460.jar -DgroupId=org.opencv -DartifactId=opencv -Dversion=4.6.0 -Dpackaging=jar
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment