测试工具类

devA
yuxue 5 years ago
parent d264764bea
commit 19575f5e9b

@ -1,19 +1,25 @@
package com.yuxue.util;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.MatVector;
import org.bytedeco.javacpp.opencv_core.RotatedRect;
import org.bytedeco.javacpp.opencv_core.Scalar;
import org.bytedeco.javacpp.opencv_core.Size;
import org.bytedeco.javacpp.opencv_ml.ANN_MLP;
import org.bytedeco.javacpp.opencv_ml.SVM;
import org.bytedeco.javacpp.opencv_imgcodecs;
import org.bytedeco.javacpp.opencv_imgproc;
import com.google.common.collect.Maps;
import com.yuxue.constant.Constant;
/**
@ -23,38 +29,55 @@ import com.google.common.collect.Maps;
*/
public class ImageUtil {
private static SVM svm = SVM.create();
private static ANN_MLP ann=ANN_MLP.create();
private static String DEFAULT_BASE_TEST_PATH = "D:/PlateDetect/temp/";
public static void loadSVM(String path) {
svm.clear();
svm=SVM.load(path);
}
// 加载ann配置文件 图像转文字的训练库文件
public static void loadModel(String path) {
ann.clear();
ann = ANN_MLP.load(path);
}
// 车牌定位处理步骤该map用于表示步骤图片的顺序
private static Map<String, Integer> debugMap = Maps.newLinkedHashMap();
static {
// debugMap.put("result", 99);
debugMap.put("gaussianBlur", 0); // 高斯模糊
debugMap.put("gray", 1); // 图像灰度化
debugMap.put("sobel", 2); // Sobel 算子
debugMap.put("threshold", 3); //图像二值化
debugMap.put("morphology", 4); // 图像闭操作
debugMap.put("contours", 5); // 提取外部轮廓
debugMap.put("result", 6); // 原图处理结果
debugMap.put("crop", 7); // 切图
debugMap.put("resize", 8); // 切图resize
debugMap.put("char_threshold", 9); //
debugMap.put("yuantu", 0); // 高斯模糊
debugMap.put("gaussianBlur", 1); // 高斯模糊
debugMap.put("gray", 2); // 图像灰度化
debugMap.put("sobel", 3); // Sobel 算子
debugMap.put("threshold", 4); //图像二值化
debugMap.put("morphology", 5); // 图像闭操作
debugMap.put("contours", 6); // 提取外部轮廓
debugMap.put("screenblock", 7); // 提取外部轮廓
debugMap.put("result", 8); // 原图处理结果
debugMap.put("crop", 9); // 切图
debugMap.put("resize", 10); // 切图resize
debugMap.put("char_threshold", 11); //
// debugMap.put("char_clearLiuDing", 10); // 去除柳钉
// debugMap.put("specMat", 11);
// debugMap.put("chineseMat", 12);
// debugMap.put("char_auxRoi", 13);
// 加载训练库文件
//loadModel(Constant.DEFAULT_ANN_PATH);
//loadSVM(Constant.DEFAULT_SVM_PATH);
}
public static void main(String[] args) {
String filename = DEFAULT_BASE_TEST_PATH + "test.jpg";
// String filename = DEFAULT_BASE_TEST_PATH + "test01.jpg";
String tempPath = DEFAULT_BASE_TEST_PATH + System.currentTimeMillis() + "/";
FileUtil.createDir(tempPath); // 创建文件夹
FileUtil.renameFile(filename, tempPath + "000_yuantu.jpg");
String tempPath = DEFAULT_BASE_TEST_PATH + "test/";
String filename = tempPath + "/100_yuantu.jpg";
Mat inMat = opencv_imgcodecs.imread(filename);
@ -66,6 +89,12 @@ public class ImageUtil {
Mat sobel = ImageUtil.sobel(grey, debug, tempPath);
Mat threshold = ImageUtil.threshold(sobel, debug, tempPath);
Mat morphology = ImageUtil.morphology(threshold, debug, tempPath);
MatVector contours = ImageUtil.contours(inMat, morphology, debug, tempPath);
// ImageUtil.rgb2Hsv(inMat, debug, tempPath);
}
@ -133,7 +162,6 @@ public class ImageUtil {
opencv_imgproc.Sobel(inMat, grad_y, SOBEL_DDEPTH, 0, 1, 3, SOBEL_SCALE, SOBEL_DELTA, opencv_core.BORDER_DEFAULT);
opencv_core.convertScaleAbs(grad_y, abs_grad_y);
// Total Gradient (approximate)
opencv_core.addWeighted(abs_grad_x, SOBEL_X_WEIGHT, abs_grad_y, SOBEL_Y_WEIGHT, 0, dst);
if (debug) {
@ -143,7 +171,6 @@ public class ImageUtil {
}
/**
* 256 1 0
* @param inMat
@ -161,9 +188,6 @@ public class ImageUtil {
}
/**
* 使
* @param inMat
@ -205,12 +229,96 @@ public class ImageUtil {
if (debug) {
// 将轮廓描绘到原图
opencv_imgproc.drawContours(src, contours, -1, new Scalar(0, 0, 255, 255));
// 输出带轮廓的原图
opencv_imgcodecs.imwrite(tempPath + (debugMap.get("contours") + 100) + "_contours.jpg", src);
}
return contours;
}
/**
*
* @param src
* @param matVector
* @param debug
* @param tempPath
* @return
*/
final static float DEFAULT_ERROR = 0.6f;
final static float DEFAULT_ASPECT = 3.75f;
public static final int DEFAULT_VERIFY_MIN = 3;
public static final int DEFAULT_VERIFY_MAX = 20;
public static final int DEFAULT_ANGLE = 30; // 角度判断所用常量
public static Vector<Mat> screenBlock(Mat src, MatVector contours, Boolean debug, String tempPath){
MatVector rects = new MatVector();
// Vector<RotatedRect> rects = new Vector<RotatedRect>();
for (int i = 0; i < contours.size(); ++i) {
// RotatedRect 该类表示平面上的旋转矩形,有三个属性: 矩形中心点(质心); 边长(长和宽); 旋转角度
RotatedRect mr = opencv_imgproc.minAreaRect(contours.get(i));
float angle = Math.abs(mr.angle());
if (verifySizes(mr)) {
// rects.add(mr);
// 判断旋转角度 ±30°
if (angle <= DEFAULT_ANGLE) {
rects.put(mr);
// 旋转角度
Mat rotmat = opencv_imgproc.getRotationMatrix2D(mr.center(), angle, 1);
Mat img_rotated = new Mat();
opencv_imgproc.warpAffine(src, img_rotated, rotmat, src.size()); // CV_INTER_CUBIC
}
}
}
if (debug) {
// 将轮廓描绘到原图
opencv_imgproc.drawContours(src, rects, -1, new Scalar(0, 0, 255, 255));
// 输出带轮廓的原图
opencv_imgcodecs.imwrite(tempPath + (debugMap.get("screenblock") + 100) + "_screenblock.jpg", src);
}
return null;
}
/**
* minAreaRect
* @param mr
* @return
*/
private static boolean verifySizes(RotatedRect mr) {
// China car plate size: 440mm*140mmaspect 3.142857
int min = 44 * 14 * DEFAULT_VERIFY_MIN;
int max = 44 * 14 * DEFAULT_VERIFY_MAX;
// Get only patchs that match to a respect ratio.
float rmin = DEFAULT_ASPECT - DEFAULT_ASPECT * DEFAULT_ERROR;
float rmax = DEFAULT_ASPECT + DEFAULT_ASPECT * DEFAULT_ERROR;
// 计算面积
int area = (int) (mr.size().height() * mr.size().width());
// 计算纵横比
float r = mr.size().width() / mr.size().height();
if (r < 1) {
r = mr.size().height() / mr.size().width();
}
return min <= area && area <= max && rmin <= r && r <= rmax;
}

Loading…
Cancel
Save