OpenCV无法使用hog和svm正确识别

时间:2019-07-06 09:49:21

标签: java opencv image-processing machine-learning computer-vision

我正在尝试实现一种检测空闲停车位的机制。我有一些图像要测试。我从中裁剪出一些图像,正片和负片的尺寸均为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);
}

测试图像

test image

测试后的图片

image after test

这里是代码中指定的文件夹“ datasets”的链接: https://www42.zippyshare.com/v/ILjcBpW6/file.html

0 个答案:

没有答案