195 lines
6.3 KiB
Java
195 lines
6.3 KiB
Java
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<String> onMessageUpdate;
|
|
@Setter private Consumer<Frame> onHQFrameUpdate;
|
|
@Setter private Consumer<Frame> onLQFrameUpdate;
|
|
@Setter private Consumer<String> onHQBase64Update;
|
|
@Setter private Consumer<String> onLQBase64Update;
|
|
@Setter private Consumer<Frame> onYoloUpdate;
|
|
@Setter private Consumer<String> 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 (framecount<Integer.MAX_VALUE) framecount++; else framecount = 0;
|
|
if (framecount % skippedframes == 0) {
|
|
processFrame(frame);
|
|
}
|
|
} catch (Exception e){
|
|
Logger.error("Error grabbing frame: "+e.getMessage());
|
|
|
|
}
|
|
|
|
long elapsed = System.currentTimeMillis() - starttick;
|
|
starttick = System.currentTimeMillis();
|
|
if (elapsed>0) {
|
|
int xx = (int) (1000 / elapsed);
|
|
if (xx<fps) CaptureFPS = xx;
|
|
}
|
|
//Logger.info("Elapsed time = {} ms, captureFPS = {}", elapsed, CaptureFPS);
|
|
}
|
|
Logger.info("Grabbing Task stopped");
|
|
}
|
|
}
|