添加样本训练测试代码

devA
yuxue 5 years ago
parent 1fbb6e9523
commit b66b98d9cc

@ -36,7 +36,6 @@ public class EasyPrTest {
*/
@Test
public void testPlateRecognise() {
//String imgPath = "res/image/test_image/test.jpg";
String imgPath = "res/image/test_image/plate_recognize.jpg";
Mat src = opencv_imgcodecs.imread(imgPath);
@ -55,7 +54,7 @@ public class EasyPrTest {
String palte = cr.charsRecognise(img, "tem/"); // 字符识别
PlateColor color = CoreFunc.getPlateType(img, true);
System.err.println("识别到的车牌: " + palte + "_" + color);
System.err.println("识别到的车牌: " + palte + "_" + color.desc);
// 识别的车牌,保存图片文件 //需要先创建文件夹
String str = "d:/PlateDetect/" + palte + "_"+ color + "_" + System.currentTimeMillis() +".png";
String str1 = "d:/PlateDetect/" + i + ".png";
@ -89,7 +88,7 @@ public class EasyPrTest {
for (int i = 0; i < matVector.size(); ++i) {
Mat img = matVector.get(i);
// 弹窗显示
//opencv_highgui.imshow("Plate Detected", img);
opencv_highgui.imshow("Plate Detected", img);
String str = "d:/test/" + i + ".png";
opencv_imgcodecs.imwrite(str, img);
@ -178,11 +177,17 @@ public class EasyPrTest {
System.out.println(result);
}
/**
* 绿
*/
@Test
public void testGreenPlate() {
public void testGreenColorReco() {
String imgPath = "res/image/test_image/debug_resize_2.jpg";
Mat src = opencv_imgcodecs.imread(imgPath);
// 获取绿牌的H值范围
/*MatVector hsvSplit = new MatVector();
split(src_hsv, hsvSplit);
@ -213,44 +218,47 @@ public class EasyPrTest {
} else {
map.put(H, 1);
}
}
}
map.entrySet().forEach(n->{
System.err.println(n.getKey() + "\t" + n.getValue());
});*/
// 判断绿色车牌
/*Mat src_hsv = new Mat();
Mat src_hsv = new Mat();
opencv_imgproc.cvtColor(src, src_hsv, opencv_imgproc.CV_BGR2HSV);
src_hsv = CoreFunc.colorMatch(src, PlateColor.GREEN, true);
System.err.println(CoreFunc.plateColorJudge(src, PlateColor.GREEN, true));
String str = "d:/PlateDetect/src_hsv.png";
opencv_imgcodecs.imwrite(str, src_hsv);*/
opencv_imgcodecs.imwrite(str, src_hsv);
}
@Test
public void testGreenPlate() {
String imgPath = "res/image/test_image/debug_resize_2.jpg";
Mat src = opencv_imgcodecs.imread(imgPath);
// 车牌检测对象
PlateDetect plateDetect = new PlateDetect();
plateDetect.setPDLifemode(true);
plateDetect.setDebug(false, ""); // 将过程的图块保存到盘符
Vector<Mat> matVector = new Vector<Mat>();
System.err.println(plateDetect.plateDetect(src, matVector));
System.err.println(matVector.size());
for (int i = 0; i < matVector.size(); ++i) { // 遍历车牌图块Mat进行识别
Mat img = matVector.get(i);
// 识别的车牌,保存图片文件
// 此方法生成的文件中文名称都是乱码试了各种编解码均无效OpenCV自身的编解码问题。
opencv_highgui.imshow("123", img);
String str = "d:/PlateDetect/temp/result_.png";
opencv_imgcodecs.imwrite(str, img);
}
}

@ -0,0 +1,68 @@
package com.yuxue.test;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.ml.SVM;
/**
* windows
* 1openvphttps://opencv.org/releases/page/2/ 当前使用4.0.1版本
* 2exe \build\java\x64\opencv_java401.dll \build\x64\vc14\bin\
* 3eclipseUser Libraries
* 4build pathlib
*
*
* @author yuxue
* @date 2020-05-12 21:34
*/
public class PridectTest {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) {
Mat src = Imgcodecs.imread("D:\\xunlian\\a\\0.jpg");//图片大小要和样本一致
Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2GRAY);
Mat dst = new Mat();
Imgproc.Canny(src, dst, 40, 200);
test(dst);
}
public static void test(Mat src) {
SVM svm = SVM.load("./Result/a.xml");//加载训练得到的 xml
Mat samples = new Mat(1,src.cols()*src.rows(),CvType.CV_32FC1);
//转换 src 图像的 cvtype
//失败案例:我试图用 src.convertTo(src, CvType.CV_32FC1); 转换,但是失败了,原因未知。猜测: 内部的数据类型没有转换?
float[] dataArr = new float[src.cols()*src.rows()];
for(int i =0,f = 0 ;i<src.rows();i++) {
for(int j = 0;j<src.cols();j++) {
float pixel = (float)src.get(i, j)[0];
dataArr[f] = pixel;
f++;
}
}
samples.put(0, 0, dataArr);
//预测用的方法,返回定义的标识。
// int labels[] = {9,9,9,9,
// 1,1,1,1,1,1,1,
// 1,1,1,1,1,1,1};
// 如果训练时使用这个标识那么符合的图像会返回9.0
float flag = svm.predict(samples);
System.out.println("预测结果:"+flag);
if(flag == 0) {
System.out.println("目标符合");
}
if(flag == 1) {
System.out.println("目标不符合");
}
}
}

@ -0,0 +1,115 @@
package com.yuxue.test;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.TermCriteria;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.ml.Ml;
import org.opencv.ml.SVM;
import org.opencv.ml.TrainData;
/**
* windows
* 1openvphttps://opencv.org/releases/page/2/ 当前使用4.0.1版本
* 2exe \build\java\x64\opencv_java401.dll \build\x64\vc14\bin\
* 3eclipseUser Libraries
* 4build pathlib
*
*
* @author yuxue
* @date 2020-05-12 21:34
*/
public class TrainTest {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
/**
* @author idmin
*
*/
private static final int SAMPLE_NUMBER=18;
public static void main(String[] args) {
//用于存放所有样本矩阵
Mat trainingDataMat = null;
//标记:正样本用 0 表示,负样本用 1 表示。
//图片命名:
//正样本: 0.jpg 1.jpg 2.jpg 3.jpg 4.jpg
//负样本5.jpg 6.jpg 7.jpg ... 17.jpg
int labels[] = {0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1};
//存放标记的Mat,每个图片都要给一个标记。SAMPLE_NUMBER 是自己定义的图片数量
Mat labelsMat = new Mat(SAMPLE_NUMBER, 1, CvType.CV_32SC1);
labelsMat.put(0, 0, labels);
//这里的意思是trainingDataMat 存放18张图片的矩阵trainingDataMat 的每一行存放一张图片的矩阵。
for(int i = 0;i<SAMPLE_NUMBER;i++) {
String path = "D:\\xunlian\\a\\" + i + ".jpg" ;
Mat src = Imgcodecs.imread(path);
//创建一个行数为18(正负样本总数量为18),列数为 rows*cols 的矩阵
if(trainingDataMat == null) {
trainingDataMat = new Mat(SAMPLE_NUMBER, src.rows()*src.cols(),CvType.CV_32FC1);// CV_32FC1 是规定的训练用的图片格式。
}
//转成灰度图并检测边缘
//这里是为了过滤不需要的特征,减少训练时间。实际处理按情况论。
Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2GRAY);
Mat dst = new Mat(src.rows(),src.cols(),src.type());//此时的 dst 是8u1c。
Imgproc.Canny(src, dst, 130, 250);
//转成数组再添加。
//失败案例:这里我试图用 get(row,col,data)方法获取数组,但是结果和这个结果不一样,原因未知。
float[] arr =new float[dst.rows()*dst.cols()];
int l=0;
for (int j=0;j<dst.rows();j++){
for(int k=0;k<dst.cols();k++) {
double[] a=dst.get(j, k);
arr[l]=(float)a[0];
l++;
}
}
trainingDataMat.put(i, 0, arr);
}
//每次训练的结果得到的 xml 文件都不一样,原因未知。猜测是我的样本数太太太太小
// MySvm(trainingDataMat, labelsMat, "./Result/a.xml");
// MySvm(trainingDataMat, labelsMat, "./Result/b.xml");
// MySvm(trainingDataMat, labelsMat, "./Result/c.xml");
// MySvm(trainingDataMat, labelsMat, "./Result/d.xml");
// MySvm(trainingDataMat, labelsMat, "./Result/e.xml");
MySvm(trainingDataMat, labelsMat, "./Result/f.xml");
}
/**
* SVM
* @param trainingDataMat
* @param labelsMat
* @param savePath d:/svm.xml
*/
public static void MySvm(Mat trainingDataMat, Mat labelsMat, String savePath) {
SVM svm = SVM.create();
// 配置SVM训练器参数
TermCriteria criteria = new TermCriteria(TermCriteria.EPS + TermCriteria.MAX_ITER, 1000, 0);
svm.setTermCriteria(criteria);// 指定
svm.setKernel(SVM.LINEAR);// 使用预先定义的内核初始化
svm.setType(SVM.C_SVC); // SVM的类型,默认是SVM.C_SVC
svm.setGamma(0.5);// 核函数的参数
svm.setNu(0.5);// SVM优化问题参数
svm.setC(1);// SVM优化问题的参数C
TrainData td = TrainData.create(trainingDataMat, Ml.ROW_SAMPLE, labelsMat);// 类封装的训练数据
boolean success = svm.train(td.getSamples(), Ml.ROW_SAMPLE, td.getResponses());// 训练统计模型
System.out.println("Svm training result: " + success);
svm.save(savePath);// 保存模型
}
}
Loading…
Cancel
Save