优化代码结构

devA
yuxue 5 years ago
parent 817b41c454
commit a40705f15a

@ -15,6 +15,8 @@
- **图片车牌检测训练**
- **图片文字识别训练**
- 包含两种依赖包的实现方式: 基于org.bytedeco.javacpp包的实现方式 基于org.opencv官方包的实现方式
- org.opencv官方包提供了java语言apijava项目可以通过build path方式或者环境变量的方式引用
- org.bytedeco.javacpp包JavaCPP是一个开源库它提供了在 Java 中高效访问本地 C++的方法在pom中引入坐标依赖即可
#### 软件版本
- jdk 1.8.61+

@ -25,14 +25,15 @@ public class Constant {
public static String DEFAULT_ANN_PATH = "res/model/ann.xml";
//public static String DEFAULT_ANN_PATH = "D:/PlateDetect/train/chars_recognise_ann/ann.xml";
public static String DEFAULT_SVM_PATH = "res/model/svm.xml";
// 车牌识别,判断是否车牌的正则表达式
public static String plateReg = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1})";
public static int predictSize = 10;
public static int neurons = 40;
// 中国车牌; 34个字符; 没有 字母I、字母O

@ -1,7 +1,6 @@
package com.yuxue.easypr.core;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_imgcodecs;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_ml.ANN_MLP;
@ -22,11 +21,11 @@ public class CharsIdentify {
loadModel(Constant.DEFAULT_ANN_PATH);
}
public void loadModel(String s) {
public void loadModel(String path) {
this.ann.clear();
// 加载ann配置文件 图像转文字的训练库文件
//ann=ANN_MLP.loadANN_MLP(s, "ann");
ann = ANN_MLP.load(s);
//ann=ANN_MLP.loadANN_MLP(path, "ann");
ann = ANN_MLP.load(path);
}

@ -1,21 +1,12 @@
package com.yuxue.easypr.core;
import static org.bytedeco.javacpp.opencv_core.CV_32F;
import static org.bytedeco.javacpp.opencv_core.countNonZero;
import static org.bytedeco.javacpp.opencv_core.extractChannel;
import static org.bytedeco.javacpp.opencv_core.merge;
import static org.bytedeco.javacpp.opencv_core.split;
import static org.bytedeco.javacpp.opencv_highgui.cvWaitKey;
import static org.bytedeco.javacpp.opencv_imgproc.CV_BGR2HSV;
import static org.bytedeco.javacpp.opencv_imgproc.cvtColor;
import static org.bytedeco.javacpp.opencv_imgproc.equalizeHist;
import static org.bytedeco.javacpp.opencv_imgproc.resize;
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.Size;
import org.bytedeco.javacpp.opencv_highgui;
import org.bytedeco.javacpp.opencv_imgproc;
import org.bytedeco.javacpp.indexer.FloatIndexer;
import com.yuxue.enumtype.Direction;
@ -49,8 +40,7 @@ public class CoreFunc {
final float minref_sv = 64;
final float minabs_sv = 95;
//opencv颜色识别的HSV中各个颜色所对应的H的范围 Orange 0-22 Yellow 22- 38 Green 38-75 Blue 75-130
// opencv颜色识别的HSV中各个颜色所对应的H的范围 Orange 0-22 Yellow 22- 38 Green 38-75 Blue 75-130
// blue的H范围
final int min_blue = 100;
final int max_blue = 140;
@ -58,18 +48,18 @@ public class CoreFunc {
// yellow的H范围
final int min_yellow = 15;
final int max_yellow = 40;
// green的H范围
final int min_green = 8;
final int max_green = 150;
// 转到HSV空间进行处理颜色搜索主要使用的是H分量进行蓝色与黄色的匹配工作
Mat src_hsv = new Mat();
cvtColor(src, src_hsv, CV_BGR2HSV);
opencv_imgproc.cvtColor(src, src_hsv, opencv_imgproc.CV_BGR2HSV);
MatVector hsvSplit = new MatVector();
split(src_hsv, hsvSplit);
equalizeHist(hsvSplit.get(2), hsvSplit.get(2));
merge(hsvSplit, src_hsv);
opencv_core.split(src_hsv, hsvSplit);
opencv_imgproc.equalizeHist(hsvSplit.get(2), hsvSplit.get(2));
opencv_core.merge(hsvSplit, src_hsv);
// 匹配模板基色,切换以查找想要的基色
int min_h = 0;
@ -147,7 +137,7 @@ public class CoreFunc {
// 获取颜色匹配后的二值灰度图
MatVector hsvSplit_done = new MatVector();
split(src_hsv, hsvSplit_done);
opencv_core.split(src_hsv, hsvSplit_done);
Mat src_grey = hsvSplit_done.get(2);
return src_grey;
@ -174,7 +164,7 @@ public class CoreFunc {
Mat gray = colorMatch(src, color, adaptive_minsv);
float percent = (float) countNonZero(gray) / (gray.rows() * gray.cols());
float percent = (float) opencv_core.countNonZero(gray) / (gray.rows() * gray.cols());
return (percent > thresh) ? true : false;
}
@ -227,10 +217,10 @@ public class CoreFunc {
// 统计这一行或一列中非零元素的个数并保存到nonZeroMat中
float[] nonZeroMat = new float[sz];
extractChannel(img, img, 0);
opencv_core.extractChannel(img, img, 0);
for (int j = 0; j < sz; j++) {
Mat data = (direction == Direction.HORIZONTAL) ? img.row(j) : img.col(j);
int count = countNonZero(data);
int count = opencv_core.countNonZero(data);
nonZeroMat[j] = count;
}
@ -267,11 +257,11 @@ public class CoreFunc {
Mat lowData = new Mat();
if (sizeData > 0) {
// resize.cpp:3784: error: (-215:Assertion failed) !ssize.empty() in function 'cv::resize'
resize(in, lowData, new Size(sizeData, sizeData));
opencv_imgproc.resize(in, lowData, new Size(sizeData, sizeData));
}
int numCols = vhist.length + hhist.length + lowData.cols() * lowData.rows();
Mat out = Mat.zeros(1, numCols, CV_32F).asMat();
Mat out = Mat.zeros(1, numCols, opencv_core.CV_32F).asMat();
FloatIndexer idx = out.createIndexer();
int j = 0;
@ -291,16 +281,17 @@ public class CoreFunc {
return out;
}
/**
*
*
* @param title
* @param src
*/
public static void showImage(final String title, final Mat src) {
if(src!=null){
if (src != null) {
opencv_highgui.imshow(title, src);
cvWaitKey(0);
opencv_highgui.cvWaitKey(0);
}
}

@ -9,7 +9,7 @@ import org.bytedeco.javacpp.opencv_core.MatVector;
import org.bytedeco.javacpp.opencv_imgproc;
/**
*
*
* @author yuxue
* @date 2020-05-05 08:26
*/

@ -6,7 +6,7 @@ import org.bytedeco.javacpp.opencv_core.Mat;
/**
*
*
* 1 2
* @author yuxue
* @date 2020-04-24 15:33

@ -10,6 +10,8 @@ import org.bytedeco.javacpp.opencv_core.Rect;
import org.bytedeco.javacpp.opencv_core.Size;
import org.bytedeco.javacpp.opencv_ml.SVM;
import com.yuxue.constant.Constant;
/**
*
@ -20,22 +22,21 @@ public class PlateJudge {
private SVM svm = SVM.create();
public PlateJudge() {
loadSVM(Constant.DEFAULT_SVM_PATH);
}
public void loadSVM(String path) {
svm.clear();
// svm=SVM.loadSVM(path, "svm");
svm=SVM.load(path);
}
/**
* EasyPRgetFeatures, imagesvmfeatures
*/
private SVMCallback features = new Features();
/**
*
*/
private String path = "res/model/svm.xml";
public PlateJudge() {
svm.clear();
svm=SVM.loadSVM(path, "svm");
//svm=SVM.load(path);
}
/**
* SVM
@ -54,7 +55,6 @@ public class PlateJudge {
ret = (int) svm.predict(features);
return ret;
// 使用com.yuxue.train.PlateRecoTrain 生成的训练库文件
// 在使用的过程中,传入的样本切图要跟训练的时候处理切图的方法一致
/*Mat grayImage = new Mat();
@ -104,12 +104,4 @@ public class PlateJudge {
}
public void setModelPath(String path) {
this.path = path;
}
public final String getModelPath() {
return path;
}
}

@ -72,8 +72,6 @@ public class PlateLocate {
// 开启调试模式之后,切图文件保存路径
protected String tempPath = Constant.DEFAULT_TEMP_DIR + System.currentTimeMillis() + "/";
/**
*
* @param islifemode
@ -176,15 +174,14 @@ public class PlateLocate {
Mat result = new Mat();
if (debug) {
// Draw red contours on the source image
src.copyTo(result);
// 将轮廓描绘到图上输出
drawContours(result, contours, -1, new Scalar(0, 0, 255, 255));
opencv_imgcodecs.imwrite(tempPath + "debug_Contours.jpg", result);
}
// Start to iterate to each contour founded
// 筛选。对轮廓求最小外接矩形,然后验证,不满足条件的淘汰。
Vector<RotatedRect> rects = new Vector<RotatedRect>();
for (int i = 0; i < contours.size(); ++i) {

@ -37,7 +37,6 @@ import com.yuxue.util.FileUtil;
public class PlateServiceImpl implements PlateService {
// 车牌定位处理步骤该map用于表示步骤图片的顺序
private static Map<String, Integer> debugMap = Maps.newLinkedHashMap();
static {

@ -40,10 +40,10 @@ public class SVMTrain1 {
private static final String hasPlate = "HasPlate";
private static final String noPlate = "NoPlate";
public SVMTrain() {
public SVMTrain1() {
}
public SVMTrain(SVMCallback callback) {
public SVMTrain1(SVMCallback callback) {
this.callback = callback;
}
@ -374,7 +374,7 @@ public class SVMTrain1 {
}
public static void main(String[] args) {
SVMTrain s = new SVMTrain();
SVMTrain1 s = new SVMTrain1();
s.svmTrain(true);
s.svmPredict();
}

@ -1,13 +0,0 @@
package com.yuxue.util;
/**
*
* @author yuxue
* @date 2020-05-10 19:31
*/
public class ImageUtil {
}

@ -13,9 +13,7 @@ public class PalteUtil {
* @return
*/
public static Boolean isPlate(String str) {
Pattern p = Pattern.compile(Constant.plateReg);
Boolean bl = false;
//提取车牌

Loading…
Cancel
Save