experimental #1
@@ -15,6 +15,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
|
||||
import org.opencv.core.*;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.dnn.Dnn;
|
||||
@@ -47,7 +48,7 @@ public class CameraApp extends JFrame {
|
||||
private List<String> outputLayers;
|
||||
private boolean detectionEnabled = true;
|
||||
private boolean modelLoaded = false;
|
||||
private int frameCount = 0;
|
||||
private final int frameCount = 0;
|
||||
private long lastFpsUpdate = System.currentTimeMillis();
|
||||
|
||||
public CameraApp() {
|
||||
@@ -245,6 +246,12 @@ public class CameraApp extends JFrame {
|
||||
}
|
||||
|
||||
private void loadYolo() {
|
||||
// Try to load from resources first
|
||||
if (loadYoloFromResources()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fall back to downloading if not found in resources
|
||||
String weightsUrl = "https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.weights";
|
||||
String configUrl = "https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov4-tiny.cfg";
|
||||
String classesUrl = "https://raw.githubusercontent.com/AlexeyAB/darknet/master/data/coco.names";
|
||||
@@ -253,47 +260,40 @@ public class CameraApp extends JFrame {
|
||||
String configPath = "./yolov4-tiny.cfg";
|
||||
String classesPath = "./coco.names";
|
||||
|
||||
boolean filesValid = true;
|
||||
// Rest of your download logic...
|
||||
}
|
||||
|
||||
private boolean loadYoloFromResources() {
|
||||
try {
|
||||
Path path = Paths.get(weightsPath);
|
||||
if (!Files.exists(path) || Files.size(path) < 10000000) {
|
||||
filesValid = false;
|
||||
}
|
||||
final Path path1 = Paths.get(configPath);
|
||||
if (!Files.exists(path1) || Files.size(path1) < 10000) {
|
||||
filesValid = false;
|
||||
}
|
||||
final Path path2 = Paths.get(classesPath);
|
||||
if (!Files.exists(path2) || Files.size(path2) < 1000) {
|
||||
filesValid = false;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
filesValid = false;
|
||||
}
|
||||
if (!filesValid) {
|
||||
int reply = JOptionPane.showConfirmDialog(this,
|
||||
"YOLO model files need to be downloaded (~25MB). Continue?",
|
||||
"Download Files", JOptionPane.YES_NO_OPTION);
|
||||
// Load the model files from resources
|
||||
byte[] weights = readResourceToByteArray("/yolov4-tiny.weights");
|
||||
byte[] config = readResourceToByteArray("/yolov4-tiny.cfg");
|
||||
|
||||
if (reply == JOptionPane.NO_OPTION) {
|
||||
statusLabel.setText("Object detection disabled - model not loaded");
|
||||
return;
|
||||
if (weights == null || config == null) {
|
||||
statusLabel.setText("Model files not found in resources");
|
||||
return false;
|
||||
}
|
||||
|
||||
downloadYoloFiles(weightsUrl, configUrl, classesUrl);
|
||||
}
|
||||
// Create temp files with proper extensions
|
||||
File weightsFile = File.createTempFile("yolov4-tiny", ".weights");
|
||||
File configFile = File.createTempFile("yolov4-tiny", ".cfg");
|
||||
|
||||
try {
|
||||
net = Dnn.readNetFromDarknet(configPath, weightsPath);
|
||||
// Write bytes to temp files
|
||||
Files.write(weightsFile.toPath(), weights);
|
||||
Files.write(configFile.toPath(), config);
|
||||
|
||||
// Try to use GPU if available (OpenCV Java doesn't have CUDA detection, so we'll use CPU)
|
||||
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
|
||||
net.setPreferableTarget(Dnn.DNN_TARGET_CPU);
|
||||
statusLabel.setText("Using CPU backend");
|
||||
// Load the network
|
||||
net = Dnn.readNetFromDarknet(configFile.getAbsolutePath(), weightsFile.getAbsolutePath());
|
||||
|
||||
if (net.empty()) {
|
||||
statusLabel.setText("Failed to load model from resources");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load class names
|
||||
classes = new ArrayList<>();
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(classesPath))) {
|
||||
try (InputStream classesStream = getClass().getResourceAsStream("/coco.names");
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(classesStream))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
classes.add(line.trim());
|
||||
@@ -302,8 +302,7 @@ public class CameraApp extends JFrame {
|
||||
|
||||
// Get output layer names
|
||||
List<String> layerNames = net.getLayerNames();
|
||||
MatOfInt unconnectedOutLayers = new MatOfInt();
|
||||
net.getUnconnectedOutLayers();
|
||||
MatOfInt unconnectedOutLayers = net.getUnconnectedOutLayers();
|
||||
int[] indices = unconnectedOutLayers.toArray();
|
||||
|
||||
outputLayers = new ArrayList<>();
|
||||
@@ -312,15 +311,41 @@ public class CameraApp extends JFrame {
|
||||
}
|
||||
|
||||
modelLoaded = true;
|
||||
statusLabel.setText("YOLOv4 model loaded successfully");
|
||||
statusLabel.setText("YOLOv4 model loaded from resources");
|
||||
return true;
|
||||
|
||||
} catch (Exception e) {
|
||||
modelLoaded = false;
|
||||
statusLabel.setText(String.format("Error loading model: %s", e.getMessage()));
|
||||
JOptionPane.showMessageDialog(this, "Failed to load object detection model", "Error", JOptionPane.WARNING_MESSAGE);
|
||||
statusLabel.setText("Error loading model: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private byte [] readResourceToByteArray(String resourcePath) throws IOException {
|
||||
try (InputStream is = getClass().getResourceAsStream(resourcePath)) {
|
||||
if (is == null) return null;
|
||||
return is.readAllBytes();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validateModel() {
|
||||
if (net == null || net.empty()) {
|
||||
statusLabel.setText("Model is empty or not loaded");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// Create a dummy blob to test the network
|
||||
Mat blob = Dnn.blobFromImage(new Mat(416, 416, CvType.CV_8UC3), 1.0/255.0);
|
||||
net.setInput(blob);
|
||||
List<Mat> outs = new ArrayList<>();
|
||||
net.forward(outs, outputLayers);
|
||||
return !outs.isEmpty();
|
||||
} catch (Exception e) {
|
||||
statusLabel.setText("Model validation failed: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private void downloadYoloFiles(String weightsUrl, String configUrl, String classesUrl) {
|
||||
String[][] files = {
|
||||
{"yolov4-tiny.weights", weightsUrl},
|
||||
@@ -437,8 +462,16 @@ public class CameraApp extends JFrame {
|
||||
}
|
||||
|
||||
public void displayFrame(Mat frame) {
|
||||
if (frame == null || frame.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
BufferedImage bufferedImage = matToBufferedImage(frame);
|
||||
if (bufferedImage == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImageIcon imageIcon = new ImageIcon(bufferedImage);
|
||||
|
||||
// Scale to fit label
|
||||
|
||||
Reference in New Issue
Block a user