XHotSniperX
Lt. Junior Grade
- Registriert
- Jan. 2008
- Beiträge
- 474
Ich mache gerade ein kleines Projekt mit dem Lego Mindstorm. Als Programmiersprache habe ich Java mit OpenCV genommen (JavaCV) und die lejos library für den Mindstorm Legobaustein.
Das Programm soll einfach mit einer Kamera bestimmte Farben im Bild erkennen (bei mir Rot und Blau). Alles klappt eigentlich, nur kommt manchmal nach wenigen Minuten ein Out Of Memory Error. Weiss einer warum das Programm den Speicher leerfrisst?
Ich vermute, es hängt mit IplImage.create() zusammen. Wie kann ich den Speicher immer schön leeren?
Hier ist der komplette Code:
Das Programm soll einfach mit einer Kamera bestimmte Farben im Bild erkennen (bei mir Rot und Blau). Alles klappt eigentlich, nur kommt manchmal nach wenigen Minuten ein Out Of Memory Error. Weiss einer warum das Programm den Speicher leerfrisst?
Ich vermute, es hängt mit IplImage.create() zusammen. Wie kann ich den Speicher immer schön leeren?
Hier ist der komplette Code:
Code:
package com.mydomain;
/**
* This is a Project in Computer Architecture and Operating Systems,
* where a robot is remotely controlled by the computer.
*
*
*/
import static com.googlecode.javacv.cpp.opencv_core.cvFlip;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSize;
import static com.googlecode.javacv.cpp.opencv_core.cvInRangeS;
import static com.googlecode.javacv.cpp.opencv_core.cvScalar;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_MEDIAN;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvGetCentralMoment;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvGetSpatialMoment;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvMoments;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvSmooth;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
import lejos.nxt.Motor;
import lejos.nxt.remote.RemoteMotor;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.VideoInputFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_imgproc.CvMoments;
public class RoboPong implements Runnable {
final int INTERVAL = 1000;// 1sec
final int CAMERA_NUM = 0; // Default camera for this time
/**
* Correct the color range- it depends upon the object, camera quality,
* environment.
*/
static CvScalar rgba_min = cvScalar(0, 0, 100, 0);// RED
static CvScalar rgba_max = cvScalar(30, 30, 255, 0);
static CvScalar rgbb_min = cvScalar(100, 50, 0, 0);// BLUE
static CvScalar rgbb_max = cvScalar(255, 190, 30, 0);
//640 x 480 image resolution
RemoteMotor motorA = Motor.A;
RemoteMotor motorC = Motor.C;
IplImage image;
CanvasFrame canvas = new CanvasFrame("Web Cam Live");
CanvasFrame path = new CanvasFrame("Detection");
JPanel jp = new JPanel();
public RoboPong() {
canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
path.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
path.setContentPane(jp);
// set robot's speed
motorA.setSpeed(600);
motorC.setSpeed(600);
}
@Override
public void run() {
FrameGrabber grabber = new VideoInputFrameGrabber(CAMERA_NUM);
try {
grabber.start();
IplImage img;
int redX = 0;
int redY = 0;
int blueX = 0;
int blueY = 0;
while (true) {
img = grabber.grab();
if (img != null) {
// show image on window
cvFlip(img, img, 1);// l-r = 90_degrees_steps_anti_clockwise
canvas.showImage(img);
IplImage[] detectThrsArray = getThresholdImage(img);
IplImage detectThrsRed = detectThrsArray[0];
IplImage detectThrsBlue = detectThrsArray[1];
CvMoments moments = new CvMoments();
cvMoments(detectThrsRed, moments, 1);
double mom10a = cvGetSpatialMoment(moments, 1, 0);
double mom01a = cvGetSpatialMoment(moments, 0, 1);
double area1 = cvGetCentralMoment(moments, 0, 0);
redX = (int) (mom10a / area1);
redY = (int) (mom01a / area1);
cvMoments(detectThrsBlue, moments, 1);
double mom10b = cvGetSpatialMoment(moments, 1, 0);
double mom01b = cvGetSpatialMoment(moments, 0, 1);
double area2 = cvGetCentralMoment(moments, 0, 0);
blueX = (int) (mom10b / area2);
blueY = (int) (mom01b / area2);
// only if its a valid position
if (redX > 0 && redY > 0 && blueX > 0 && blueY > 0) {
paint1(img, redX, redY);
paint2(img, blueX, blueY);
compare(redX, redY, blueX, blueY);
}
else{
stop();
}
}
//Thread.sleep(INTERVAL);
}
} catch (Exception e) {
}
}
private void compare(int redX, int redY, int blueX, int blueY){
if(blueX > 600 && redX > blueX || blueX < 40 && redX < blueX){
stop();
}
else if((Math.abs(redX - blueX)) < 100){
stop();
}
else if(redX < blueX){
goLeft();
}
else if(redX > blueX){
goRight();
}
}
private void goRight(){
motorA.forward();
motorC.backward();
}
private void goLeft(){
motorA.backward();
motorC.forward();
}
private void stop(){
motorA.stop();
motorC.stop();
}
private void paint1(IplImage img, int posX, int posY) {
Graphics g = jp.getGraphics();
path.setSize(img.width(), img.height());
g.setColor(Color.RED);
g.drawOval(posX, posY, 20, 20);
System.out.println(posX + " , " + posY);
}
private void paint2(IplImage img, int posX, int posY) {
Graphics g = jp.getGraphics();
path.setSize(img.width(), img.height());
g.setColor(Color.BLUE);
g.drawOval(posX, posY, 20, 20);
System.out.println(posX + " , " + posY);
}
private IplImage[] getThresholdImage(IplImage orgImg) {
IplImage[] imgThresholdArray = new IplImage[2];
IplImage imgThresholdRed = IplImage.create(cvGetSize(orgImg), 8, 1);
IplImage imgThresholdBlue = IplImage.create(cvGetSize(orgImg), 8, 1);
cvInRangeS(orgImg, rgba_min, rgba_max, imgThresholdRed);// red
cvInRangeS(orgImg, rgbb_min, rgbb_max, imgThresholdBlue);// blue
cvSmooth(imgThresholdRed, imgThresholdRed, CV_MEDIAN, 15);
cvSmooth(imgThresholdBlue, imgThresholdBlue, CV_MEDIAN, 15);
imgThresholdArray[0] = imgThresholdRed;
imgThresholdArray[1] = imgThresholdBlue;
return imgThresholdArray;
}
public static void main(String[] args) {
RoboPong cot = new RoboPong();
Thread th = new Thread(cot);
th.start();
}
}