package Camera; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import Other.SomeCodes; import lombok.Getter; import lombok.Setter; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.FrameGrabber; import org.bytedeco.javacv.OpenCVFrameConverter; import org.opencv.core.Mat; import org.opencv.core.Size; import org.opencv.imgproc.Imgproc; import org.tinylog.Logger; public class GrabbingTask implements Runnable { // for while loop control private final AtomicBoolean isGrabbing; // for grabbing frames private final FrameGrabber grabber; // Consumers @Setter private Consumer onMessageUpdate; @Setter private Consumer onHQFrameUpdate; @Setter private Consumer onLQFrameUpdate; @Setter private Consumer onHQBase64Update; @Setter private Consumer onLQBase64Update; @Setter private Consumer onYoloUpdate; @Setter private Consumer onYoloBase64Update; // status of capture fps @Getter private int CaptureFPS = 0; @Getter @Setter private int lowquality_width = 640; @Getter @Setter private int lowquality_height = 360; // for FPS calculation private int intendedFps = 10; private final YoloDetector yolo; @SuppressWarnings("SameParameterValue") private void updateMessage(String message) { if (onMessageUpdate != null) { onMessageUpdate.accept(message); } } private void updateYoloBase64(String base64) { if (onYoloBase64Update != null) { onYoloBase64Update.accept(base64); } } private void updateYoloFrame(Frame frame) { if (onYoloUpdate != null) { onYoloUpdate.accept(frame); } } private void updateHQBase64(String base64) { if (onHQBase64Update != null) { onHQBase64Update.accept(base64); } } @SuppressWarnings("SameParameterValue") private void updateLQBase64(String base64) { if (onLQBase64Update != null) { onLQBase64Update.accept(base64); } } private void updateHQFrame(Frame frame) { if (onHQFrameUpdate != null) { onHQFrameUpdate.accept(frame); } } private void updateLQFrame(Frame frame) { if (onLQFrameUpdate != null) { onLQFrameUpdate.accept(frame); } } public GrabbingTask(AtomicBoolean isGrabbing, FrameGrabber grabber, int fps) { this.isGrabbing = isGrabbing; this.grabber = grabber; if (fps>0) intendedFps = fps; yolo = new YoloDetector(); } public void Stop(){ isGrabbing.set(false); } private void processFrame(Frame fr){ if (fr!=null && fr.image!=null && fr.imageWidth>0 && fr.imageHeight>0){ try(var converter = new OpenCVFrameConverter.ToOrgOpenCvCoreMat()){ org.opencv.core.Mat mat = converter.convert(fr); if (mat.cols()>0 && mat.rows()>0){ updateHQFrame(fr); updateHQBase64(SomeCodes.MatToBase64(mat)); Size lowsize = new Size(lowquality_width, lowquality_height); Mat resized = new Mat(); Imgproc.resize(mat, resized, lowsize); if (resized.cols()>0 && resized.rows()>0){ Frame resizedFrame = SomeCodes.CoreMatConverter.convert(resized); updateLQFrame(resizedFrame); updateLQBase64(SomeCodes.MatToBase64(resized)); } else System.out.println("processFrame resized size is 0"); DetectYolo(mat); resized.release(); } else System.out.println("processFrame Mat size is 0"); mat.release(); } catch (Exception e){ Logger.error("Error processing frame: "+e.getMessage()); } } else { System.out.println("processFrame have null frame"); updateMessage("processFrame have null frame"); } } private void DetectYolo(Mat mat){ if (mat!=null && mat.cols()>0 && mat.rows()>0){ //System.out.println("DetectYolo mat cols = "+mat.cols()+", rows = "+mat.rows()); try{ Mat[] processed = yolo.Detect(mat); Mat yolomat = yolo.Process(mat, processed[0], processed[1]); Frame yoloFrame = SomeCodes.CoreMatConverter.convert(yolomat); updateYoloFrame(yoloFrame); updateYoloBase64(SomeCodes.MatToBase64(yolomat)); } catch (Exception e){ System.out.println("error processing YOLO, Message : "+e.getMessage()); updateYoloFrame(null); updateYoloBase64(""); } } else System.out.println("DetectYolo mat is null"); } private void flush_grabber(){ try { if (grabber!=null) grabber.flush(); } catch (FrameGrabber.Exception e) { Logger.error("Error flushing grabber: "+e.getMessage()); } } @Override public void run() { isGrabbing.set(true); Logger.info("Grabbing Task started"); double fps = grabber.getFrameRate(); int skippedframes = (int)(fps / intendedFps); //Logger.info("Grabber framerate = {}, intendedFps = {}, Skipping frames = {}", fps, intendedFps, skippedframes); int framecount = 0; flush_grabber(); long starttick = System.currentTimeMillis(); while (isGrabbing.get()) { try{ Thread.yield(); Frame frame = grabber.grab(); if (framecount0) { int xx = (int) (1000 / elapsed); if (xx