How to code in Java in to train a xml file with positive and negative examples image for an image recognition model by using HOG Features

24 views Asked by At

Tin during the code is that the xml file output does not fit into the Object Recognition code. The object recognition code basically read through the xml file and open the camera in my computer. Normally when I am using the xml file that opencv has done itself for example a trained xml file for recognition of a human face, it always work. But when I am trying to put my own trained xml files in it just error occurs. This prove that it is the trained model not working.

Here is my code for SVMTrainer:

import org.bytedeco.javacpp.FloatPointer;
    import org.bytedeco.javacpp.indexer.FloatIndexer;
    import org.bytedeco.javacpp.indexer.IntIndexer;
    import org.bytedeco.opencv.global.opencv_imgproc;
    import org.bytedeco.opencv.opencv_core.*;
    import org.bytedeco.opencv.opencv_ml.SVM;
    import org.bytedeco.opencv.opencv_objdetect.HOGDescriptor;
    import org.opencv.core.CvType;
    import org.opencv.ml.Ml;
    
    import java.nio.file.FileVisitOption;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class SVMTrainer2 {
        public static final String positiveSamplesPath = "D:/Desktop/positiveexamples";
        
        public static final String negativeSamplesPath = "D:/Desktop/negativeexamples";
        public static final String modelSavePath = "C:/Robotics/xml files/";
    
        public static final int NUM_IMAGES_TO_LOAD = 5;
    
        public static SVM trainSVM(String positiveSamplesPath, String negativeSamplesPath, String modelSavePath) {
            // Combine positive and negative samples into one list
            List<Mat> positiveSamples = loadSamples(positiveSamplesPath, NUM_IMAGES_TO_LOAD);
            List<Mat> negativeSamples = loadSamples(negativeSamplesPath, NUM_IMAGES_TO_LOAD);
    
            List<Mat> allSamples = new ArrayList<>(positiveSamples);
            allSamples.addAll(negativeSamples);
    
            // Create labels for samples (1 for positive, -1 for negative)
            Mat labels = new Mat(allSamples.size(), 1, CvType.CV_32SC1);
            IntIndexer labelIndexer = labels.createIndexer();
            for (int i = 0; i < positiveSamples.size(); i++) {
                labelIndexer.put(i, 0, 1);
            }
            for (int i = positiveSamples.size(); i < allSamples.size(); i++) {
                labelIndexer.put(i, 0, -1);
            }
    
            // Extract HOG features for each sample
            List<Mat> hogFeaturesList = new ArrayList<>();
            for (Mat sample : allSamples) {
                Mat hogFeatures = extractHOGFeatures(sample);
                hogFeaturesList.add(hogFeatures);
            }
            
            
         // Convert HOG features to Mat
            Mat samples = new Mat(hogFeaturesList.size(), hogFeaturesList.get(0).rows(), CvType.CV_32FC1);
            FloatIndexer samplesIndexer = samples.createIndexer();
            
    
            for (int i = 0; i < hogFeaturesList.size(); i++) {
                Mat hogFeature = hogFeaturesList.get(i);
                
                // Reshape the hogFeature to a single-row matrix
                hogFeature = hogFeature.reshape(1, 1);
                
                System.out.println("Original hogFeature size: " + hogFeaturesList.get(i).size().width() + " x " + hogFeaturesList.get(i).size().height());
                System.out.println("Reshaped hogFeature size: " + hogFeature.size().width() + " x " + hogFeature.size().height());
                
                // Ensure the matrix is a single row (1xN)
                if (hogFeature.rows() == 1) {
                    FloatIndexer hogFeatureIndexer = hogFeature.createIndexer();
    
                    System.out.println("hogFeature size: " + hogFeature.size().width() + " x " + hogFeature.size().height());
                    
                    // Ensure the hogFeature has the same number of columns as the samples matrix
                    if (hogFeature.cols() == samples.cols()) {
                        // Set the data into the samples Mat directly
                        for (int j = 0; j < hogFeature.cols(); j++) {
                            samplesIndexer.put(i, j, hogFeatureIndexer.get(0, j));
                        }
                    } else {
                        System.err.println("Number of columns in hogFeature doesn't match samples matrix.");
                    }
                } else {
                    System.err.println("hogFeature is not a single row matrix.");
                }
            }
            System.out.println("samples size: " + samples.size().width() + " x " + samples.size().height());
    
    
            
            
            // Train SVM
            SVM svm = SVM.create();
            svm.setType(SVM.C_SVC);
            svm.setKernel(SVM.LINEAR);
            svm.setTermCriteria(new TermCriteria(TermCriteria.EPS, 100, 1e-6));
            svm.train(samples, Ml.ROW_SAMPLE, labels);
    
            // Save the trained SVM model
            //String modelSavePath1 = modelSavePath + "/svm_model.xml";
            //svm.save(modelSavePath1);
    
            return svm;
        }
    
        public static Mat extractHOGFeatures(Mat image) {
            // Convert the image to grayscale
            Mat grayImage = new Mat();
            opencv_imgproc.cvtColor(image, grayImage, opencv_imgproc.COLOR_BGR2GRAY);
    
            // Create a HOGDescriptor
            HOGDescriptor hog = new HOGDescriptor(
                    new Size(960, 544),  // Increase window size for higher resolution
                    new Size(16, 16),  // Adjust block size based on object size
                    new Size(8, 8),    // Adjust block stride based on image size
                    new Size(8, 8),    // Keep cell size similar
                    9);                // Number of bins
    
            // Compute HOG features
            FloatPointer features = new FloatPointer();
            hog.compute(grayImage, features);
    
            // Convert the FloatPointer to a Mat if needed
            Mat hogFeatures = new Mat(features);
    
            return hogFeatures;
        }
    
        private static List<Mat> loadSamples(String samplesPath, int numImagesToLoad) {
            List<Mat> samples = new ArrayList<>();
    
            try {
                List<Path> imagePaths = Files.walk(Path.of(samplesPath), 1, FileVisitOption.FOLLOW_LINKS)
                        .filter(p -> p.toString().endsWith(".jpg") || p.toString().endsWith(".png"))
                        .limit(numImagesToLoad)  // Limit the number of images to load
                        .collect(Collectors.toList());
    
                for (Path imagePath : imagePaths) {
                    Mat image = org.bytedeco.opencv.global.opencv_imgcodecs.imread(imagePath.toString());
                    if (!image.empty()) {
                        samples.add(image);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return samples;
        }
    
        public static void main(String[] args) {
            
    
            System.out.println("Start");
    
            // Resize images in positiveexamples folder
            //resizeImagesInFolder(positiveSamplesPath, 960, 544);
    
            // Resize images in negativeexamples folder
            //resizeImagesInFolder(negativeSamplesPath, 960, 544);
    
            // Continue with your training logic
            SVM trainedSVM = trainSVM(positiveSamplesPath, negativeSamplesPath, modelSavePath);
            
            String modelSavePath1 = modelSavePath + "/svm_model.xml";
            trainedSVM.save(modelSavePath1);
    
            System.out.println("Success");
        }
        /*private static void resizeImagesInFolder(String folderPath, int targetWidth, int targetHeight) {
            try {
                List<Path> imagePaths = Files.walk(Path.of(folderPath), 1, FileVisitOption.FOLLOW_LINKS)
                        .filter(p -> p.toString().endsWith(".jpg") || p.toString().endsWith(".png"))
                        .collect(Collectors.toList());
    
                for (Path imagePath : imagePaths) {
                    Mat image = opencv_imgcodecs.imread(imagePath.toString());
                    if (!image.empty()) {
                        // Resize the image
                        Mat resizedImage = resizeImage(image, targetWidth, targetHeight);
    
                        // Save the resized image back to the same path
                        opencv_imgcodecs.imwrite(imagePath.toString(), resizedImage);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private static Mat resizeImage(Mat inputImage, int targetWidth, int targetHeight) {
            Mat resizedImage = new Mat();
            Size size = new Size(targetWidth, targetHeight);
            org.bytedeco.opencv.global.opencv_imgproc.resize(inputImage, resizedImage, size);
            return resizedImage;
        }*/
    }

This can actually generate a xml file but it does not work when I actually runs it. Here is the difference between both xml files: it should be something like this with dependencies:

<opencv_storage>
<cascade>
  <stageType>BOOST</stageType>
  <featureType>HAAR</featureType>
  <height>24</height>
  <width>24</width>
  <stageParams>
    <boostType>GAB</boostType>
    <minHitRate>9.9500000476837158e-01</minHitRate>
    <maxFalseAlarm>5.0000000000000000e-01</maxFalseAlarm>
    <weightTrimRate>9.4999999999999996e-01</weightTrimRate>
    <maxDepth>1</maxDepth>
    <maxWeakCount>100</maxWeakCount></stageParams>
  <featureParams>
    <maxCatCount>0</maxCatCount>
    <featSize>1</featSize>
    <mode>BASIC</mode></featureParams>
  <stageNum>20</stageNum>
  <stages>
<!-- stage 0 -->
<_>
  <maxWeakCount>16</maxWeakCount>
  <stageThreshold>-1.4806525707244873e+00</stageThreshold>
  <weakClassifiers>
    <_>
      <internalNodes>
        0 -1 472 -1.5126220881938934e-02</internalNodes>
      <leafValues>
        7.5887596607208252e-01 -3.4230688214302063e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 839 3.9337221533060074e-03</internalNodes>
      <leafValues>
        -3.3288389444351196e-01 5.2361363172531128e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 858 -1.5044892206788063e-02</internalNodes>
      <leafValues>
        5.5565774440765381e-01 -2.2505992650985718e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 387 -1.2927042320370674e-02</internalNodes>
      <leafValues>
        5.7442700862884521e-01 -1.9708566367626190e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 137 5.5960696190595627e-03</internalNodes>
      <leafValues>
        -3.0430641770362854e-01 4.0241482853889465e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 207 1.5758406370878220e-02</internalNodes>
      <leafValues>
        -1.9767063856124878e-01 4.5033392310142517e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 678 2.4262722581624985e-02</internalNodes>
      <leafValues>
        -1.6931040585041046e-01 5.9707510471343994e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 267 -3.5242564976215363e-02</internalNodes>
      <leafValues>
        6.5973556041717529e-01 -1.4519356191158295e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 687 2.6568008586764336e-02</internalNodes>
      <leafValues>
        -1.3476610183715820e-01 5.4296624660491943e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 228 4.7154121100902557e-02</internalNodes>
      <leafValues>
        -1.7337851226329803e-01 4.6071702241897583e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 925 -5.3081759251654148e-03</internalNodes>
      <leafValues>
        5.4976856708526611e-01 -1.1913410574197769e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 608 5.3415738046169281e-02</internalNodes>
      <leafValues>
        -1.2382411211729050e-01 6.3972741365432739e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 671 -3.0798995867371559e-03</internalNodes>
      <leafValues>
        -8.2048600912094116e-01 1.0249497741460800e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 676 -2.3766520898789167e-03</internalNodes>
      <leafValues>
        -7.0665025711059570e-01 6.7025005817413330e-02</leafValues></_>
    <_>
      <internalNodes>
        0 -1 180 1.1965663870796561e-03</internalNodes>
      <leafValues>
        -2.4753804504871368e-01 3.0198124051094055e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 830 -4.2106406763195992e-03</internalNodes>
      <leafValues>
        3.8455343246459961e-01 -1.8334107100963593e-01</leafValues></_></weakClassifiers></_>
<!-- stage 1 -->
<_>
  <maxWeakCount>26</maxWeakCount>
  <stageThreshold>-1.4618960618972778e+00</stageThreshold>
  <weakClassifiers>
    <_>
      <internalNodes>
        0 -1 725 1.0133055038750172e-02</internalNodes>
      <leafValues>
        -2.8207325935363770e-01 6.2703561782836914e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 356 3.8468956947326660e-02</internalNodes>
      <leafValues>
        -1.4483113586902618e-01 7.4971008300781250e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 2 -3.7523733917623758e-03</internalNodes>
      <leafValues>
        4.2959973216056824e-01 -2.1445912122726440e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 844 9.9978316575288773e-04</internalNodes>
      <leafValues>
        -1.9259409606456757e-01 4.2325544357299805e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 387 -1.6786376014351845e-02</internalNodes>
      <leafValues>
        5.0582861900329590e-01 -1.8607729673385620e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 208 3.0330579727888107e-02</internalNodes>
      <leafValues>
        -2.1100421249866486e-01 4.2819553613662720e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 206 1.5150709077715874e-02</internalNodes>
      <leafValues>
        -2.1129198372364044e-01 3.6263525485992432e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 451 -3.6349350120872259e-03</internalNodes>
      <leafValues>
        3.9500275254249573e-01 -1.8650630116462708e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 270 -7.2061517275869846e-03</internalNodes>
      <leafValues>
        -7.2816300392150879e-01 1.1153221875429153e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 866 -2.0212728530168533e-02</internalNodes>
      <leafValues>
        5.6296736001968384e-01 -1.2056054919958115e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 265 2.5640423409640789e-03</internalNodes>
      <leafValues>
        -2.3753854632377625e-01 3.5794413089752197e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 230 -6.2726587057113647e-03</internalNodes>
      <leafValues>
        -6.7750877141952515e-01 1.2570948898792267e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 126 7.8710336238145828e-03</internalNodes>
      <leafValues>
        6.9211356341838837e-02 -7.6449161767959595e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 306 5.9134580194950104e-02</internalNodes>
      <leafValues>
        -1.7324967682361603e-01 3.3361187577247620e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 185 -2.8770491480827332e-03</internalNodes>
      <leafValues>
        3.6101511120796204e-01 -1.6122241318225861e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 388 -5.7046953588724136e-03</internalNodes>
      <leafValues>
        -6.7659336328506470e-01 8.4153175354003906e-02</leafValues></_>
    <_>
      <internalNodes>
        0 -1 13 -7.8070178627967834e-02</internalNodes>
      <leafValues>
        6.0763663053512573e-01 -1.1037797480821609e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 321 6.5858578309416771e-03</internalNodes>
      <leafValues>
        9.3060031533241272e-02 -7.0068693161010742e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 796 -2.0920131355524063e-03</internalNodes>
      <leafValues>
        2.8173315525054932e-01 -1.8406434357166290e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 578 -2.1252598613500595e-02</internalNodes>
      <leafValues>
        3.9672371745109558e-01 -1.5127600729465485e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 770 -3.2937981188297272e-02</internalNodes>
      <leafValues>
        3.9487251639366150e-01 -1.3228580355644226e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 1016 4.9491915851831436e-03</internalNodes>
      <leafValues>
        1.1234261840581894e-01 -4.7414371371269226e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 215 3.4271054901182652e-03</internalNodes>
      <leafValues>
        7.8623600304126740e-02 -5.7828009128570557e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 200 -6.0859560035169125e-03</internalNodes>
      <leafValues>
        -5.0091904401779175e-01 9.1926425695419312e-02</leafValues></_>
    <_>
      <internalNodes>
        0 -1 990 1.2116413563489914e-02</internalNodes>
      <leafValues>
        -1.7154470086097717e-01 2.6759135723114014e-01</leafValues></_>
    <_>
      <internalNodes>
        0 -1 456 8.2814376801252365e-03</internalNodes>
      <leafValues>
        -1.2938241660594940e-01 3.5665917396545410e-01</leafValues></_><

But mine is like this:

<?xml version="1.0"?>
<opencv_storage>
<opencv_ml_svm>
  <format>3a</format>
  <svmType>C_SVC</svmType>
  <kernel>
    <type>LINEAR</type></kernel>
  <C>1.</C>
  <term_criteria><epsilon>9.9999999999999995e-07</epsilon></term_criteria>
  <var_count>287028</var_count>
  <class_count>2</class_count>
  <class_labels type_id="opencv-matrix">
    <rows>2</rows>
    <cols>1</cols>
    <dt>i</dt>
    <data>
      -1 1</data></class_labels>
  <sv_total>1</sv_total>
  <support_vectors>
    <_>
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
  0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 

and these:

.31444351e-02 5.23362122e-02 3.09769511e-01 3.09769511e-01
9.46327578e-03 9.61663108e-03 0. 2.89486229e-01 0. 9.32921283e-03
6.42074049e-02 3.09769511e-01 3.09769511e-01 4.86077834e-03 0. 0.
3.03416371e-01 2.12417841e-02 1.02448780e-02 6.72894120e-02
3.09769511e-01 1.69313803e-01 5.68061545e-02 4.07612957e-02
1.61841139e-02 2.43170530e-01 1.03058174e-01 1.57478735e-01
1.37013525e-01 2.22078428e-01 2.62951165e-01 1.60860553e-01
1.95810661e-01 1.70263499e-01 2.62951165e-01 2.62951165e-01
2.62951165e-01 2.62951165e-01 2.62951165e-01 8.07161182e-02
1.60897318e-02 1.06704608e-02 8.13189987e-03 1.99176252e-01
4.67931964e-02 4.93425094e-02 4.14676666e-02 1.08491279e-01
1.57530084e-01 3.25466134e-02 6.75964057e-02 5.39438426e-02
2.62951165e-01 1.56355828e-01 1.69698253e-01 1.48492500e-01
2.24302992e-01 1.76372722e-01 8.03147107e-02 1.74810737e-01
8.08113143e-02 2.54457623e-01 2.30080724e-01 2.31936350e-01

which does not look correct and at the same time it does not work in the actually recognition code.

I believe that there is some problems with the java code I have coded. Please help me to sort this out because I have tried all different kind of solution but they doesn't work at the end. Just help me point out the problems with the code.

by the way this is my code for recognition. I believe that there is no problem here but if anyone want to have a look please do:

    import org.opencv.core.*;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    import org.opencv.objdetect.CascadeClassifier;
    import org.opencv.videoio.VideoCapture;
    
    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    
    public class ObjectRecognition {
        private CascadeClassifier faceDetector;
        private VideoCapture camera;
        private Frame frame;
        
        
    
        public ObjectRecognition(Frame frame) {
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            this.frame = frame;
            // Load the pre-trained face detection model (change the path as needed)
            faceDetector = new CascadeClassifier("C:/Robotics/xml files/");
            // Open the video capture (0 is usually the default camera)
            camera = new VideoCapture(0);
            if (!camera.isOpened()) {
                System.out.println("Error: Camera not opened.");
                return;
            }
            Mat frameMat = new Mat();
            MatOfRect faceDetections = new MatOfRect();
            while (true) {
                camera.read(frameMat);
                if (!frameMat.empty()) {
                    // Detect faces in the frame
                    faceDetector.detectMultiScale(frameMat, faceDetections);
                    for (Rect rect : faceDetections.toArray()) {
                        // Draw a rectangle around each detected face
                        Imgproc.rectangle(frameMat, rect.tl(), rect.br(), new Scalar(0, 255, 0), 3);
                    }
                    // Convert the Mat to a BufferedImage for display
                    BufferedImage img = matToBufferedImage(frameMat);
                    frame.displayImage(img);
                } else {
                    System.out.println("Error: Frame is empty.");
                }
            }
        }
    
        // Converts a Mat object to a BufferedImage
        private BufferedImage matToBufferedImage(Mat mat) {
            MatOfByte mob = new MatOfByte();
            Imgcodecs.imencode(".jpg", mat, mob);
            byte[] byteArray = mob.toArray();
            BufferedImage bufImage = null;
            try {
                ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray);
                bufImage = ImageIO.read(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bufImage;
        }
    }
0

There are 0 answers