我正在尝试实现一种检测空闲停车位的机制。我有一些图像要测试。我从中裁剪出一些图像,正片和负片的尺寸均为45x90。我尝试使用生猪训练探测器,然后在测试图像上突出显示可用的停车位,但检测不正确。我附加了代码,用于测试的图像以及正负图像。谢谢!
public class Main {
public static final String SVM_MODEL_FILE_PATH = "E:\\datasets\\svm1.xml";
public static final String SVM_ROOT = "E:\\datasets\\my dataset1\\";
public static final String SVM_HAS_TRAIN = "free";
public static final String SVM_NO_TRAIN = "busy";
private static TrainData loadTrainData() {
List<File> hasFileList = getFiles(SVM_ROOT + SVM_HAS_TRAIN);
List<File> noFileList = getFiles(SVM_ROOT + SVM_NO_TRAIN);
int hasCount = hasFileList.size();
int noCount = noFileList.size();
Mat samples = new Mat();
MatOfInt labels = new MatOfInt();
for (int i = 0; i < hasCount; i++) {// positive
Mat img = Imgcodecs.imread(hasFileList.get(i).getAbsolutePath());
Mat imageHOG = obtainHOG(img);
samples.push_back(imageHOG.reshape(1, 1));
labels.push_back(Mat.ones(new Size(1, 1), CvType.CV_32S));
}
for (int j = 0; j < noCount; j++) {// negative
Mat img = Imgcodecs.imread(noFileList.get(j).getAbsolutePath());
Mat imageHOG = obtainHOG(img);
samples.push_back(imageHOG.reshape(1, 1));
labels.push_back(Mat.zeros(new Size(1, 1), CvType.CV_32S));
}
Mat trainingData = new Mat();
samples.copyTo(trainingData);
trainingData.convertTo(trainingData, CvType.CV_32FC1);
return TrainData.create(trainingData, Ml.ROW_SAMPLE, labels);
}
private static List<File> getFiles(String folderPath) {
List<File> list = new ArrayList<File>();
File file = new File(folderPath);
if (!file.exists()) {
System.out.println("Error : " + folderPath + " folder is not exist!");
return list;
}
if (!file.isDirectory()) {
System.out.println("Error : " + folderPath + " is not a folder!");
return list;
}
File[] files = file.listFiles();
if (files.length == 0) {
System.out.println("Error : " + folderPath + " folder is empty!");
return list;
}
for (int i = 0; i < files.length; i++) {
File f = files[i];
list.add(f);
}
return list;
}
public static MatOfFloat getSvmDetector(SVM svm) {
Mat supportVectors = svm.getSupportVectors();
Mat alpha = new Mat();
Mat svidx = new Mat();
double rho = svm.getDecisionFunction(0, alpha, svidx);
int size = (int)(supportVectors.total() + 1) * supportVectors.channels();
float[] temp = new float[size];
supportVectors.get(0, 0, temp);
temp[temp.length - 1] = (float)-rho;
MatOfFloat floatvector = new MatOfFloat(temp);
return floatvector;
}
public static Mat convertToMl(List<Mat> trainSamples) {
int rows = trainSamples.size();
int cols = Math.max(trainSamples.get(0).cols(), trainSamples.get(0).rows());
Mat tmp = new Mat(1, cols, CvType.CV_32F);
Mat trainData = new Mat(rows, cols, CvType.CV_32F);
for (int i = 0; i < trainSamples.size(); i++) {
if (trainSamples.get(i).cols() == 1) {
Core.transpose(trainSamples.get(i), tmp);
tmp.copyTo(trainData.row(i));
} else if (trainSamples.get(i).rows() == 1) {
trainSamples.get(i).copyTo(trainData.row(i));
}
}
return trainData;
}
public static void loadImages(String dirName, List<Mat> imageList) throws IOException {
List<File> files = new ArrayList<File>();
File directory = new File(dirName);
files = Arrays.asList(directory.listFiles());
for (File file : files) {
Mat img = Imgcodecs.imread(file.getAbsolutePath());
imageList.add(img);
}
}
public static Mat obtainHOG(Mat image) {
Size size = image.size();
HOGDescriptor hog = new HOGDescriptor(size, // winSize
new Size(9, 9), // blocksize
new Size(3, 3), // blockStride,
new Size(1, 1), // cellSize,
9);
MatOfFloat descriptors = new MatOfFloat();
hog.compute(image, descriptors);
return descriptors.clone();
}
public static void testTrainedDetector(String objDetFilename, String testDir) {
HOGDescriptor hog = new HOGDescriptor(objDetFilename);
List<File> files = new ArrayList<File>();
File directory = new File(testDir);
files = Arrays.asList(directory.listFiles());
int delay = 0;
objDetFilename = "testing " + objDetFilename;
HighGui.namedWindow(objDetFilename, HighGui.WINDOW_NORMAL);
for (File file: files) {
Mat img = Imgcodecs.imread(file.getAbsolutePath());
if (img.empty()) {
return;
}
MatOfRect detections = new MatOfRect();
MatOfDouble foundWeights = new MatOfDouble();
hog.detectMultiScale(img, detections, foundWeights);
Rect[] detectionsArray = detections.toArray();
double[] foundWeightsArray = foundWeights.toArray();
for (int j = 0; j < detectionsArray.length; j++) {
Scalar color = new Scalar(0, foundWeightsArray[j] * foundWeightsArray[j] * 200, 0);
Imgproc.rectangle(img, detectionsArray[j].tl(), detectionsArray[j].br(), color);
}
Imgcodecs.imwrite(file.getAbsolutePath().replace(".", "-after-test."), img);
}
}
public static void testTrainedDetector(String objDetFilename, String testDir, String videoFilename) {
HOGDescriptor hog = new HOGDescriptor(objDetFilename);
List<String> files = new ArrayList<String>();
File directory = new File(testDir);
files = Arrays.asList(directory.list());
int delay = 0;
VideoCapture cap = new VideoCapture();
if (videoFilename != null && !videoFilename.isEmpty()) {
if (videoFilename.length() == 1 && Character.isDigit(videoFilename.charAt(0))) {
cap.open(Integer.valueOf(videoFilename.charAt(0)));
} else {
cap.open(videoFilename);
}
}
objDetFilename = "testing " + objDetFilename;
HighGui.namedWindow(objDetFilename, HighGui.WINDOW_NORMAL);
int i = 0;
while (true) {
Mat img = new Mat();
if (cap.isOpened()) {
cap.read(img);
delay = 1;
} else if (i < files.size()) {
img = Imgcodecs.imread(files.get(i));
}
if (img.empty()) {
return;
}
MatOfRect detections = new MatOfRect();
MatOfDouble foundWeights = new MatOfDouble();
hog.detectMultiScale(img, detections, foundWeights);
Rect[] detectionsArray = detections.toArray();
double[] foundWeightsArray = foundWeights.toArray();
for (int j = 0; j < detectionsArray.length; j++) {
Scalar color = new Scalar(0, foundWeightsArray[j] * foundWeightsArray[j] * 200, 0);
Imgproc.rectangle(img, detectionsArray[j].tl(), detectionsArray[j].br(), color);
}
HighGui.imshow(objDetFilename, img);
if (HighGui.waitKey(delay) == 27) {
return;
}
}
}
private static void train() {
SVM svm = SVM.create();
svm.setType(SVM.EPS_SVR);
svm.setKernel(SVM.LINEAR);
svm.setDegree(0.1);
// 1.4 bug fix: old 1.4 ver gamma is 1
svm.setGamma(0.1);
svm.setCoef0(0.1);
svm.setC(1);
svm.setNu(0.1);
svm.setP(0.1);
svm.setTermCriteria(new TermCriteria(1, 20000, 0.0001));
// load data
TrainData trainData = loadTrainData();
// train
long start = System.currentTimeMillis();
System.out.println("start train...");
svm.train(trainData);
System.out.println("end train...total time : " + (System.currentTimeMillis() - start) + "ms");
svm.save(SVM_MODEL_FILE_PATH);
System.out.println("save the train model...");
}
public static void main(String[] args) throws IOException {
String testDir = "E:\\datasets\\test1";
String objDetFilename = "E:\\datasets\\my_detector1.yml";
OpenCV.loadShared();
train();
System.out.println("Loading svm trained data...");
SVM loadedSVM = SVM.load(SVM_MODEL_FILE_PATH);
loadedSVM.setType(SVM.EPS_SVR);
loadedSVM.setKernel(SVM.LINEAR);
loadedSVM.setDegree(0.1);
// 1.4 bug fix: old 1.4 ver gamma is 1
loadedSVM.setGamma(0.1);
loadedSVM.setCoef0(0.1);
loadedSVM.setC(1);
loadedSVM.setNu(0.1);
loadedSVM.setP(0.1);
loadedSVM.setTermCriteria(new TermCriteria(1, 20000, 0.0001));
HOGDescriptor hog = new HOGDescriptor(new Size(45, 90), // winSize
new Size(9, 9), // blocksize
new Size(3, 3), // blockStride,
new Size(1, 1), // cellSize,
9);
if (hog.checkDetectorSize()) {
hog.setSVMDetector(getSvmDetector(loadedSVM));
}
hog.save(objDetFilename);
testTrainedDetector(objDetFilename, testDir);
}
测试图像
测试后的图片
这里是代码中指定的文件夹“ datasets”的链接: https://www42.zippyshare.com/v/ILjcBpW6/file.html