parent
7d11d901a8
commit
2d0ba56295
@ -0,0 +1,83 @@
|
||||
package com.yuxue.easypr.core;
|
||||
|
||||
import org.bytedeco.javacpp.opencv_core;
|
||||
import org.bytedeco.javacpp.opencv_core.Mat;
|
||||
import org.bytedeco.javacpp.opencv_ml.ANN_MLP;
|
||||
|
||||
import com.yuxue.constant.Constant;
|
||||
import com.yuxue.util.Convert;
|
||||
|
||||
|
||||
/**
|
||||
* 字符检测
|
||||
* @author yuxue
|
||||
* @date 2020-04-24 15:31
|
||||
*/
|
||||
public class CharsIdentify {
|
||||
|
||||
private ANN_MLP ann=ANN_MLP.create();
|
||||
|
||||
public CharsIdentify() {
|
||||
loadModel(Constant.DEFAULT_ANN_PATH);
|
||||
}
|
||||
|
||||
public void loadModel(String path) {
|
||||
this.ann.clear();
|
||||
// 加载ann配置文件 图像转文字的训练库文件
|
||||
//ann=ANN_MLP.loadANN_MLP(path, "ann");
|
||||
ann = ANN_MLP.load(path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param input
|
||||
* @param isChinese
|
||||
* @return
|
||||
*/
|
||||
public String charsIdentify(final Mat input, final Boolean isChinese, final Boolean isSpeci) {
|
||||
String result = "";
|
||||
|
||||
/*String name = "D:/PlateDetect/train/chars_recognise_ann/" + System.currentTimeMillis() + ".jpg";
|
||||
opencv_imgcodecs.imwrite(name, input);
|
||||
Mat img = opencv_imgcodecs.imread(name);
|
||||
Mat f = CoreFunc.features(img, Constant.predictSize);*/
|
||||
|
||||
Mat f = CoreFunc.features(input, Constant.predictSize);
|
||||
|
||||
int index = this.classify(f, isChinese, isSpeci);
|
||||
|
||||
System.err.print(index);
|
||||
if (index < Constant.numCharacter) {
|
||||
result = String.valueOf(Constant.strCharacters[index]);
|
||||
} else {
|
||||
String s = Constant.strChinese[index - Constant.numCharacter];
|
||||
result = Constant.KEY_CHINESE_MAP.get(s); // 编码转中文
|
||||
}
|
||||
System.err.println(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private int classify(final Mat f, final Boolean isChinses, final Boolean isSpeci) {
|
||||
int result = -1;
|
||||
|
||||
Mat output = new Mat(1, 140, opencv_core.CV_32F);
|
||||
|
||||
ann.predict(f, output, 0); // 预测结果
|
||||
|
||||
int ann_min = (!isChinses) ? ((isSpeci) ? 10 : 0) : Constant.numCharacter;
|
||||
int ann_max = (!isChinses) ? Constant.numCharacter : Constant.numAll;
|
||||
|
||||
float maxVal = -2;
|
||||
|
||||
for (int j = ann_min; j < ann_max; j++) {
|
||||
float val = Convert.toFloat(output.ptr(0, j));
|
||||
if (val > maxVal) {
|
||||
maxVal = val;
|
||||
result = j;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.yuxue.easypr.core;
|
||||
|
||||
import static com.yuxue.easypr.core.CoreFunc.features;
|
||||
import static org.bytedeco.javacpp.opencv_core.merge;
|
||||
import static org.bytedeco.javacpp.opencv_core.split;
|
||||
|
||||
import org.bytedeco.javacpp.opencv_core.Mat;
|
||||
import org.bytedeco.javacpp.opencv_core.MatVector;
|
||||
import org.bytedeco.javacpp.opencv_imgproc;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author yuxue
|
||||
* @date 2020-05-05 08:26
|
||||
*/
|
||||
public class Features implements SVMCallback {
|
||||
|
||||
/***
|
||||
* EasyPR的getFeatures回调函数
|
||||
* 本函数是生成直方图均衡特征的回调函数
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Mat getHisteqFeatures(final Mat image) {
|
||||
return histeq(image);
|
||||
}
|
||||
|
||||
private Mat histeq(Mat in) {
|
||||
Mat out = new Mat(in.size(), in.type());
|
||||
if (in.channels() == 3) {
|
||||
Mat hsv = new Mat();
|
||||
MatVector hsvSplit = new MatVector();
|
||||
opencv_imgproc.cvtColor(in, hsv, opencv_imgproc.CV_BGR2HSV);
|
||||
split(hsv, hsvSplit);
|
||||
opencv_imgproc.equalizeHist(hsvSplit.get(2), hsvSplit.get(2));
|
||||
merge(hsvSplit, hsv);
|
||||
opencv_imgproc.cvtColor(hsv, out, opencv_imgproc.CV_HSV2BGR);
|
||||
hsv = null;
|
||||
hsvSplit = null;
|
||||
System.gc();
|
||||
} else if (in.channels() == 1) {
|
||||
opencv_imgproc.equalizeHist(in, out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* EasyPR的getFeatures回调函数
|
||||
* 本函数是获取垂直和水平的直方图图值
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Mat getHistogramFeatures(Mat image) {
|
||||
Mat grayImage = new Mat();
|
||||
opencv_imgproc.cvtColor(image, grayImage, opencv_imgproc.CV_RGB2GRAY);
|
||||
|
||||
Mat img_threshold = new Mat();
|
||||
opencv_imgproc.threshold(grayImage, img_threshold, 0, 255, opencv_imgproc.CV_THRESH_OTSU + opencv_imgproc.CV_THRESH_BINARY);
|
||||
|
||||
return features(img_threshold, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 本函数是获取SITF特征子的回调函数
|
||||
*
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Mat getSIFTFeatures(final Mat image) {
|
||||
// TODO: 待完善
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 本函数是获取HOG特征子的回调函数
|
||||
*
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Mat getHOGFeatures(final Mat image) {
|
||||
// TODO: 待完善
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.yuxue.easypr.core;
|
||||
|
||||
import org.bytedeco.javacpp.opencv_core;
|
||||
import org.bytedeco.javacpp.opencv_imgproc;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.bytedeco.javacpp.opencv_core.Mat;
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* 车牌判断
|
||||
* @author yuxue
|
||||
* @date 2020-04-26 15: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);
|
||||
}
|
||||
|
||||
/**
|
||||
* EasyPR的getFeatures回调函数, 用于从车牌的image生成svm的训练特征features
|
||||
*/
|
||||
private SVMCallback features = new Features();
|
||||
|
||||
|
||||
/**
|
||||
* 对单幅图像进行SVM判断
|
||||
* @param inMat
|
||||
* @return
|
||||
*/
|
||||
public int plateJudge(final Mat inMat) {
|
||||
int ret = 1;
|
||||
// 使用com.yuxue.train.SVMTrain 生成的训练库文件
|
||||
Mat features = this.features.getHistogramFeatures(inMat);
|
||||
/*Mat samples = features.reshape(1, 1);
|
||||
samples.convertTo(samples, opencv_core.CV_32F);*/
|
||||
|
||||
Mat p = features.reshape(1, 1);
|
||||
p.convertTo(p, opencv_core.CV_32FC1);
|
||||
ret = (int) svm.predict(features);
|
||||
return ret;
|
||||
|
||||
// 使用com.yuxue.train.PlateRecoTrain 生成的训练库文件
|
||||
// 在使用的过程中,传入的样本切图要跟训练的时候处理切图的方法一致
|
||||
/*Mat grayImage = new Mat();
|
||||
opencv_imgproc.cvtColor(inMat, grayImage, opencv_imgproc.CV_RGB2GRAY);
|
||||
Mat dst = new Mat();
|
||||
opencv_imgproc.Canny(grayImage, dst, 130, 250);
|
||||
Mat samples = dst.reshape(1, 1);
|
||||
samples.convertTo(samples, opencv_core.CV_32F);*/
|
||||
|
||||
// 正样本为0 负样本为1
|
||||
/*if(svm.predict(samples) <= 0) {
|
||||
ret = 1;
|
||||
}*/
|
||||
/*ret = (int)svm.predict(samples);
|
||||
System.err.println(ret);
|
||||
return ret ;*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 对多幅图像进行SVM判断
|
||||
* @param inVec
|
||||
* @param resultVec
|
||||
* @return
|
||||
*/
|
||||
public int plateJudge(Vector<Mat> inVec, Vector<Mat> resultVec) {
|
||||
|
||||
for (int j = 0; j < inVec.size(); j++) {
|
||||
Mat inMat = inVec.get(j);
|
||||
|
||||
if (1 == plateJudge(inMat)) {
|
||||
resultVec.add(inMat);
|
||||
} else { // 再取中间部分判断一次
|
||||
int w = inMat.cols();
|
||||
int h = inMat.rows();
|
||||
|
||||
Mat tmpDes = inMat.clone();
|
||||
Mat tmpMat = new Mat(inMat, new Rect((int) (w * 0.05), (int) (h * 0.1), (int) (w * 0.9), (int) (h * 0.8)));
|
||||
opencv_imgproc.resize(tmpMat, tmpDes, new Size(inMat.size()));
|
||||
|
||||
if (plateJudge(tmpDes) == 1) {
|
||||
resultVec.add(inMat);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.yuxue.easypr.core;
|
||||
|
||||
import org.bytedeco.javacpp.opencv_core.Mat;
|
||||
|
||||
|
||||
/**
|
||||
* @author Created by fanwenjie
|
||||
* @author lin.yao
|
||||
*
|
||||
*/
|
||||
public interface SVMCallback {
|
||||
|
||||
/***
|
||||
* EasyPR的getFeatures回调函数,本函数是生成直方图均衡特征的回调函数
|
||||
*
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public abstract Mat getHisteqFeatures(final Mat image);
|
||||
|
||||
/**
|
||||
* EasyPR的getFeatures回调函数, 本函数是获取垂直和水平的直方图图值
|
||||
*
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public abstract Mat getHistogramFeatures(final Mat image);
|
||||
|
||||
/**
|
||||
* 本函数是获取SITF特征子的回调函数
|
||||
*
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public abstract Mat getSIFTFeatures(final Mat image);
|
||||
|
||||
/**
|
||||
* 本函数是获取HOG特征子的回调函数
|
||||
*
|
||||
* @param image
|
||||
* @return
|
||||
*/
|
||||
public abstract Mat getHOGFeatures(final Mat image);
|
||||
}
|
Loading…
Reference in new issue