增加黑牌识别(待测试)

devA
JXF9527 4 years ago
parent 5d0eee317d
commit e432f0aba4

@ -13,11 +13,11 @@ public class Constant {
public static final String UTF8 = "UTF-8"; public static final String UTF8 = "UTF-8";
// 车牌识别, 默认车牌图片保存路径 // 车牌识别, 默认车牌图片保存路径
// public static String DEFAULT_DIR = "./PlateDetect/"; // 使用项目的相对路径 //public static String DEFAULT_DIR = "./PlateDetect/"; // 使用项目的相对路径
public static String DEFAULT_DIR = "D:/PlateDetect/"; // 使用盘符的绝对路径 public static String DEFAULT_DIR = "D:/PlateDetect/"; // 使用盘符的绝对路径
// 车牌识别, 默认车牌图片处理过程temp路径 // 车牌识别, 默认车牌图片处理过程temp路径
// public static String DEFAULT_TEMP_DIR = "./PlateDetect/temp/"; // 使用项目的相对路径 //public static String DEFAULT_TEMP_DIR = "./PlateDetect/temp/"; // 使用项目的相对路径
public static String DEFAULT_TEMP_DIR = "D:/PlateDetect/temp/"; // 使用盘符的绝对路径 public static String DEFAULT_TEMP_DIR = "D:/PlateDetect/temp/"; // 使用盘符的绝对路径
// 车牌识别,默认处理图片类型 // 车牌识别,默认处理图片类型
@ -26,7 +26,7 @@ public class Constant {
public static String DEFAULT_ANN_PATH = "res/model/ann.xml"; 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_ANN_PATH = "D:/PlateDetect/train/chars_recognise_ann/ann.xml";
public static String DEFAULT_SVM_PATH = "res/model/svm.xml"; public static String DEFAULT_SVM_PATH = "res/model/svm.xml"; //svm2.xml为测试用
public static final int DEFAULT_WIDTH = 136; // cols public static final int DEFAULT_WIDTH = 136; // cols
public static final int DEFAULT_HEIGHT = 36; // rows public static final int DEFAULT_HEIGHT = 36; // rows

@ -119,7 +119,7 @@ public class CoreFunc {
* *
* @param src * @param src
* mat * mat
* @param r * @param color
* *
* @param adaptive_minsv * @param adaptive_minsv
* SVadaptive_minsvbool * SVadaptive_minsvbool
@ -159,7 +159,10 @@ public class CoreFunc {
return PlateColor.YELLOW; return PlateColor.YELLOW;
} else if (plateColorJudge(src, PlateColor.GREEN, adaptive_minsv) == true) { } else if (plateColorJudge(src, PlateColor.GREEN, adaptive_minsv) == true) {
return PlateColor.GREEN; return PlateColor.GREEN;
} else { } else if (plateColorJudge(src, PlateColor.BLACK, adaptive_minsv) == true) {
return PlateColor.BLACK;
}
else {
return PlateColor.UNKNOWN; return PlateColor.UNKNOWN;
} }
} }

@ -1,6 +1,8 @@
package com.yuxue.easypr.core; package com.yuxue.easypr.core;
import com.yuxue.train.SVMTrain;
import org.bytedeco.javacpp.opencv_core; import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_imgproc; import org.bytedeco.javacpp.opencv_imgproc;
import java.util.Vector; import java.util.Vector;
@ -10,9 +12,11 @@ import org.bytedeco.javacpp.opencv_core.Rect;
import org.bytedeco.javacpp.opencv_core.Size; import org.bytedeco.javacpp.opencv_core.Size;
import org.bytedeco.javacpp.opencv_ml.SVM; import org.bytedeco.javacpp.opencv_ml.SVM;
import com.yuxue.constant.Constant; import com.yuxue.constant.Constant;
/** /**
* *
* @author yuxue * @author yuxue
@ -28,7 +32,7 @@ public class PlateJudge {
public void loadSVM(String path) { public void loadSVM(String path) {
svm.clear(); svm.clear();
// svm=SVM.loadSVM(path, "svm"); //svm=SVM.loadSVM(path, "svm");
svm=SVM.load(path); svm=SVM.load(path);
} }
@ -36,7 +40,7 @@ public class PlateJudge {
* EasyPRgetFeatures, imagesvmfeatures * EasyPRgetFeatures, imagesvmfeatures
*/ */
private SVMCallback features = new Features(); private SVMCallback features = new Features();
/** /**
* SVM * SVM
@ -47,12 +51,13 @@ public class PlateJudge {
int ret = 1; int ret = 1;
// 使用com.yuxue.train.SVMTrain 生成的训练库文件 // 使用com.yuxue.train.SVMTrain 生成的训练库文件
Mat features = this.features.getHistogramFeatures(inMat); Mat features = this.features.getHistogramFeatures(inMat);
/*Mat samples = features.reshape(1, 1); //Mat features = SVMTrain.getFeature(inMat);
samples.convertTo(samples, opencv_core.CV_32F);*/ 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); /*Mat p = features.reshape(1, 1);
ret = (int) svm.predict(features); p.convertTo(p, opencv_core.CV_32FC1);*/
ret = (int) svm.predict(samples);
return ret; return ret;
// 使用com.yuxue.train.PlateRecoTrain 生成的训练库文件 // 使用com.yuxue.train.PlateRecoTrain 生成的训练库文件
@ -62,13 +67,13 @@ public class PlateJudge {
Mat dst = new Mat(); Mat dst = new Mat();
opencv_imgproc.Canny(grayImage, dst, 130, 250); opencv_imgproc.Canny(grayImage, dst, 130, 250);
Mat samples = dst.reshape(1, 1); Mat samples = dst.reshape(1, 1);
samples.convertTo(samples, opencv_core.CV_32F);*/ samples.convertTo(samples, opencv_core.CV_32F);
// 正样本为0 负样本为1 // 正样本为0 负样本为1
/*if(svm.predict(samples) <= 0) { if(svm.predict(samples) <= 0) {
ret = 1; ret = 1;
}*/ }
/*ret = (int)svm.predict(samples); ret = (int)svm.predict(samples);
System.err.println(ret); System.err.println(ret);
return ret ;*/ return ret ;*/

@ -6,6 +6,7 @@ import static org.bytedeco.javacpp.opencv_core.*;
import static org.bytedeco.javacpp.opencv_imgproc.*; import static org.bytedeco.javacpp.opencv_imgproc.*;
import com.yuxue.constant.Constant; import com.yuxue.constant.Constant;
import org.bytedeco.javacpp.opencv_highgui;
import org.bytedeco.javacpp.opencv_imgcodecs; import org.bytedeco.javacpp.opencv_imgcodecs;
import org.bytedeco.javacpp.opencv_core.CvPoint2D32f; import org.bytedeco.javacpp.opencv_core.CvPoint2D32f;
@ -17,7 +18,6 @@ import org.bytedeco.javacpp.opencv_core.RotatedRect;
import org.bytedeco.javacpp.opencv_core.Scalar; import org.bytedeco.javacpp.opencv_core.Scalar;
import org.bytedeco.javacpp.opencv_core.Size; import org.bytedeco.javacpp.opencv_core.Size;
/** /**
* *
* @author yuxue * @author yuxue
@ -117,12 +117,16 @@ public class PlateLocate {
// 高斯模糊。Size中的数字影响车牌定位的效果。 // 高斯模糊。Size中的数字影响车牌定位的效果。
GaussianBlur(src, src_blur, new Size(gaussianBlurSize, gaussianBlurSize), 0, 0, BORDER_DEFAULT); GaussianBlur(src, src_blur, new Size(gaussianBlurSize, gaussianBlurSize), 0, 0, BORDER_DEFAULT);
if (debug) { if (debug) {
//opencv_highgui.imshow("Plate Detected", src_blur);
//opencv_highgui.waitKey(0);
opencv_imgcodecs.imwrite(tempPath + "debug_GaussianBlur.jpg", src_blur); opencv_imgcodecs.imwrite(tempPath + "debug_GaussianBlur.jpg", src_blur);
} }
// Convert it to gray 将图像进行灰度化 // Convert it to gray 将图像进行灰度化
cvtColor(src_blur, src_gray, CV_RGB2GRAY); cvtColor(src_blur, src_gray, CV_RGB2GRAY);
if (debug) { if (debug) {
//opencv_highgui.imshow("Plate Detected", src_gray);
//opencv_highgui.waitKey(0);
opencv_imgcodecs.imwrite(tempPath + "debug_gray.jpg", src_gray); opencv_imgcodecs.imwrite(tempPath + "debug_gray.jpg", src_gray);
} }
@ -144,6 +148,8 @@ public class PlateLocate {
addWeighted(abs_grad_x, SOBEL_X_WEIGHT, abs_grad_y, SOBEL_Y_WEIGHT, 0, grad); addWeighted(abs_grad_x, SOBEL_X_WEIGHT, abs_grad_y, SOBEL_Y_WEIGHT, 0, grad);
if (debug) { if (debug) {
//opencv_highgui.imshow("Plate Detected", grad);
//opencv_highgui.waitKey(0);
opencv_imgcodecs.imwrite(tempPath + "debug_Sobel.jpg", grad); opencv_imgcodecs.imwrite(tempPath + "debug_Sobel.jpg", grad);
} }
@ -153,6 +159,8 @@ public class PlateLocate {
threshold(grad, img_threshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY); threshold(grad, img_threshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
if (debug) { if (debug) {
//opencv_highgui.imshow("Plate Detected", img_threshold);
//opencv_highgui.waitKey(0);
opencv_imgcodecs.imwrite(tempPath + "debug_threshold.jpg", img_threshold); opencv_imgcodecs.imwrite(tempPath + "debug_threshold.jpg", img_threshold);
} }
@ -162,6 +170,8 @@ public class PlateLocate {
morphologyEx(img_threshold, img_threshold, MORPH_CLOSE, element); morphologyEx(img_threshold, img_threshold, MORPH_CLOSE, element);
if (debug) { if (debug) {
//opencv_highgui.imshow("Plate Detected", img_threshold);
//opencv_highgui.waitKey(0);
opencv_imgcodecs.imwrite(tempPath + "debug_morphology.jpg", img_threshold); opencv_imgcodecs.imwrite(tempPath + "debug_morphology.jpg", img_threshold);
} }
@ -178,6 +188,8 @@ public class PlateLocate {
// 将轮廓描绘到图上输出 // 将轮廓描绘到图上输出
drawContours(result, contours, -1, new Scalar(0, 0, 255, 255)); drawContours(result, contours, -1, new Scalar(0, 0, 255, 255));
opencv_imgcodecs.imwrite(tempPath + "debug_Contours.jpg", result); opencv_imgcodecs.imwrite(tempPath + "debug_Contours.jpg", result);
//opencv_highgui.imshow("Plate Detected", result);
//opencv_highgui.waitKey(0);
} }
// Start to iterate to each contour founded // Start to iterate to each contour founded
@ -275,6 +287,7 @@ public class PlateLocate {
Mat resultResized = new Mat(); Mat resultResized = new Mat();
resultResized.create(HEIGHT, WIDTH, TYPE); resultResized.create(HEIGHT, WIDTH, TYPE);
//大小调整,训练之前要保证图像大小一致
resize(img_crop, resultResized, resultResized.size(), 0, 0, INTER_CUBIC); resize(img_crop, resultResized, resultResized.size(), 0, 0, INTER_CUBIC);
if (debug) { if (debug) {
opencv_imgcodecs.imwrite(tempPath + "debug_resize_" + index + ".jpg", resultResized); opencv_imgcodecs.imwrite(tempPath + "debug_resize_" + index + ".jpg", resultResized);

@ -11,12 +11,14 @@ public enum PlateColor {
BLUE("BLUE","蓝牌", 100, 130), BLUE("BLUE","蓝牌", 100, 130),
GREEN("GREEN","绿牌", 38, 100), GREEN("GREEN","绿牌", 38, 100),
YELLOW("YELLOW","黄牌", 15, 40), YELLOW("YELLOW","黄牌", 15, 40),
BLACK("BLACK", "黑牌", 0, 180),
UNKNOWN("UNKNOWN","未知", 0, 0); UNKNOWN("UNKNOWN","未知", 0, 0);
public final String code; public final String code;
public final String desc; public final String desc;
// 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
//新增黑牌H范围0-180S范围0-255V范围0-46
public final int minH; public final int minH;
public final int maxH; public final int maxH;

@ -1,5 +1,8 @@
package com.yuxue.train; package com.yuxue.train;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
@ -140,6 +143,9 @@ public class SVMTrain {
doPridect(svm, DEFAULT_PATH + "test/debug_resize_3.jpg"); doPridect(svm, DEFAULT_PATH + "test/debug_resize_3.jpg");
doPridect(svm, DEFAULT_PATH + "test/S22_KG2187_3.jpg"); doPridect(svm, DEFAULT_PATH + "test/S22_KG2187_3.jpg");
doPridect(svm, DEFAULT_PATH + "test/S22_KG2187_5.jpg"); doPridect(svm, DEFAULT_PATH + "test/S22_KG2187_5.jpg");
doPridect(svm, DEFAULT_PATH + "test/BE_16888.jpg");
doPridect(svm, DEFAULT_PATH + "test/BS_36359.jpg");
doPridect(svm, DEFAULT_PATH + "test/1.png");
} }
public static void doPridect(SVM svm, String imgPath) { public static void doPridect(SVM svm, String imgPath) {
@ -170,6 +176,26 @@ public class SVMTrain {
} }
/**
* org.opencv.core.Matjava.awt.image.BufferedImage
* @param matrix
* @return
*/
public static BufferedImage toBufferedImage(Mat matrix) {
int type = BufferedImage.TYPE_BYTE_GRAY;
if (matrix.channels() > 1) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = matrix.channels() * matrix.cols() * matrix.rows();
byte[] buffer = new byte[bufferSize];
matrix.get(0, 0, buffer); // get all pixel from martix
BufferedImage image = new BufferedImage(matrix.cols(), matrix.rows(), type);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(buffer, 0, targetPixels, 0, buffer.length);
return image;
}
public static Mat getFeature(Mat inMat) { public static Mat getFeature(Mat inMat) {
Mat histogram = getHistogramFeatures(inMat); Mat histogram = getHistogramFeatures(inMat);

@ -18,6 +18,11 @@ import com.yuxue.easypr.core.PlateLocate;
import com.yuxue.enumtype.Direction; import com.yuxue.enumtype.Direction;
import com.yuxue.enumtype.PlateColor; import com.yuxue.enumtype.PlateColor;
import static org.bytedeco.javacpp.opencv_core.CV_32F;
import static org.bytedeco.javacpp.opencv_core.CV_8UC3;
import static org.bytedeco.javacpp.opencv_imgproc.INTER_CUBIC;
import static org.bytedeco.javacpp.opencv_imgproc.resize;
/** /**
* EasyPr * EasyPr
* - https://gitee.com/easypr/EasyPR 很老的项目了 * - https://gitee.com/easypr/EasyPR 很老的项目了
@ -89,9 +94,10 @@ public class PlateRecoTest {
Mat img = matVector.get(i); Mat img = matVector.get(i);
// 弹窗显示 // 弹窗显示
opencv_highgui.imshow("Plate Detected", img); opencv_highgui.imshow("Plate Detected", img);
opencv_highgui.waitKey(0);
String str = "d:/test/" + i + ".png"; String str = "d:/test/" + i + ".png";
opencv_imgcodecs.imwrite(str, img); opencv_imgcodecs.imwrite(str, img);
} }
} }
} }
@ -104,7 +110,7 @@ public class PlateRecoTest {
*/ */
@Test @Test
public void testPlateLocate() { public void testPlateLocate() {
String imgPath = "res/image/test_image/test.jpg"; String imgPath = "res/image/test_image/test3.jpg";
Mat src = opencv_imgcodecs.imread(imgPath); Mat src = opencv_imgcodecs.imread(imgPath);
@ -177,7 +183,27 @@ public class PlateRecoTest {
System.out.println(result); System.out.println(result);
} }
/**
*
*/
@Test
public void testCut() {
String path = "D:/PlateDetect/train/plate_detect_svm/test/";
Mat inMat = opencv_imgcodecs.imread(path + "BS_36359.jpg");
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, CV_32F);
//Mat resultResized = new Mat();
//resultResized.create(36,136, CV_8UC3);
//大小调整,训练之前要保证图像大小一致
//resize(img_crop, resultResized, resultResized.size(), 0, 0, INTER_CUBIC);
opencv_imgcodecs.imwrite("D:/" + "debug_resize" + ".jpg", samples);
}
/** /**

Loading…
Cancel
Save