View Single Post
  #1   Spotlight this post!  
Unread 25-01-2017, 07:37
Noam Noam is offline
Registered User
None #3034 (galileo)
Team Role: Programmer
 
Join Date: Jan 2017
Rookie Year: 2015
Location: Israel
Posts: 14
Noam is an unknown quantity at this point
image processing - robot code crash after a few seconds

I'm trying to do image processing with opencv, but the code crash after a few seconds
this is the code

Code:
package org.usfirst.frc.team3034.robot;


import java.util.ArrayList;
import java.util.List;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.videoio.VideoCapture;

import com.ctre.CANTalon;

import edu.wpi.cscore.UsbCamera;
import edu.wpi.first.wpilibj.CameraServer;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;

public class Robot extends IterativeRobot {
	
	public void mySleep(long time) {
		try {
			Thread.sleep(time);
		} catch (InterruptedException e) {
		}
	}
	
	RobotDrive robot1;
	Joystick js1;
	//Compressor cop1;
	
	CANTalon drive1; 
	CANTalon drive2;
	public static UsbCamera cam1;
	public static VideoCapture cap1;

    public void robotInit() {
    	// CameraServer.getInstance().startAutomaticCapture("cam0", 0);
    	// CameraServer.getInstance().startAutomaticCapture(0);
    	// CameraServer.getInstance().startAutomaticCapture(1);
    	
    	js1 = new Joystick(0);
    	drive1 = new CANTalon(3);
    	drive2 = new CANTalon(1);
    	robot1 = new RobotDrive(drive1, drive2);
    	// VideoCapture vd1 = new VideoCapture(0);
    	// CameraServer.getInstance().startAutomaticCapture(1);
    	// cam1 = CameraServer.getInstance().startAutomaticCapture(1);
    	cap1 = new VideoCapture();
    	cap1.open(0);
    }
    
    public void autonomousInit() {
    }
    
    public void autonomousPeriodic() {
    }
    
    public void teleopInit(){
    }
    
    public void teleopPeriodic() {
    	// robot1.arcadeDrive(js1);
    	// System.out.println(cap1.grab());
    	Mat feed = new Mat();
    	try {
    		cap1.retrieve(feed);
    	} catch (Exception e) {
    		System.out.println("thr1 error1");
    	}
    	System.out.println("before1");
		proc1 thr1 = new proc1(feed);
    	proc1.start();
    	System.out.println("after1");
    }
    
    public void testPeriodic() {
    	LiveWindow.run();
    }

	static int largestContour(List<MatOfPoint> contours){
		int returnIndex = 0;//the index of the biggest contour
		int maxSize = 0;//holds the biggest size 
		for(int i = 0; i < contours.size(); i++){//iterate through the list
			MatOfPoint contour = contours.get(i);//get the contour at index i
			int size = (int) contour.total();//get the amount of points in the matrix (Might not work, havn't tried it)
			/**int size = contour.toList().size();*/ //another way of getting the size. this will work for sure
			if(size > maxSize){//if the size of the current size is bigger than the maximum size 
				returnIndex = i;//saving the current index as largest
				maxSize = size;//saving the size of the current 
			}
		}
		return returnIndex;//return the size of the largest contour
	}
	
	static Point centerPoint(MatOfPoint contour){
		int sumX = 0, sumY = 0;//variables to hold the sum of each coordinate
		List<Point> points = contour.toList();//convert to list to iterate through the points
		for(int i = 0; i < points.size(); i++){//You can change the i increase (i++) to minimize runtime!
			Point p = points.get(i);
			sumX += p.x;
			sumY += p.y;
		}
		//returning the average of each coordinate as a point
		return new Point(sumX / points.size(), sumY / points.size());
	}
	
	static Point centerPoint2(MatOfPoint contour){
		Rect rect = Imgproc.boundingRect(contour);//creating a bounding rect
		return new Point(rect.x + rect.width/2, rect.y + rect.height/2);//getting its center
	}
}
and proc1 code (the image processing (in a new thread))

Code:
package org.usfirst.frc.team3034.robot;

import java.util.ArrayList;
import java.util.List;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;

public class proc1 implements Runnable {
	Mat feed;
	
	public proc1(Mat feed) {
		this.feed = feed;
	}
	
	public void run() {
		try {
			// Thread.sleep(500);
	    	// System.out.println(feed.height() + " | " + feed.width());
			Mat hsv = new Mat();
			Mat thres = new Mat();
			// feed2 = feed.clone();
			Imgproc.cvtColor(feed, hsv, Imgproc.COLOR_RGB2HSV);
			Core.inRange(hsv,
					new Scalar(0, 0, 240),
					new Scalar(255, 255, 255),
					thres);
			// morphOps(mat3);
			List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
			//
			Mat hierarchy = new Mat();
			Imgproc.findContours(thres, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE);
			for(int i = 0; i < contours.size(); i++) {
				Imgproc.drawContours(feed, contours, i, new Scalar(15, 15, 15), -1);
			}
			/**/
			if (contours.size() > 0) {
				MatOfPoint contour = contours.get(0);
				// Rect rect = Imgproc.boundingRect(contour);
				MatOfPoint2f approxCurve = new MatOfPoint2f();
				MatOfPoint2f contour2f = new MatOfPoint2f();
				contour2f.fromList(contour.toList());
				Imgproc.approxPolyDP(contour2f//Input Matrix
						,approxCurve//Output Matrix
						,Imgproc.arcLength(contour2f, true) * 0.02
						,true//Indicates whether the shape is a closed shape or not
						);
				//Getting the amount of vertices of the shape
				// long verteciesCount = approxCurve.total();
				MatOfPoint p = new MatOfPoint();
			    approxCurve.convertTo(p, CvType.CV_32S);
				List<MatOfPoint> drawPoints = new ArrayList<MatOfPoint>();
				drawPoints.add(p);
				Imgproc.drawContours(feed, drawPoints, 0, new Scalar(9, 87, 255));
				/**/
				int largestIndex = Robot.largestContour(contours);//get the largest contour
				Imgproc.drawContours(feed, contours, largestIndex, new Scalar(15, 150, 4), 4);//draw the largest contour
				Point centerLargest = Robot.centerPoint(contours.get(largestIndex));//get the center pointt
				Imgproc.circle(feed, centerLargest, 3, new Scalar(55, 0, 100), 3);//draw a circle where the center point i;
				/**/
				if (centerLargest.x <= feed.width()) {
					System.out.println("left1");
				} else if (centerLargest.x >= feed.height()) {
					System.out.println("right1");
				} else {
					System.out.println("else1");
				}
			} else {
				// System.out.println("else1");
			}
		} catch (Exception e) {
			// System.out.println("error1");
		}
=	}
	private Thread thr1 = null;
	
	public void start () {
		if (thr1 == null) {
			System.out.println("proc1- start new thread");
			thr1 = new Thread(this);
			thr1.start();
		}
	}	
}
and this is the log

Code:
 before1 
 proc1 - start new thread 
 after1 
 before1 
 proc1 - start new thread 
 after1 
 OpenCV Error: Insufficient memory (Failed to allocate 921600 bytes) in OutOfMemoryError, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/alloc.cpp, line 52 
 OpenCV Error: Insufficient memory (Failed to allocate 921600 bytes) in OutOfMemoryError, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/alloc.cpp, line 52 
 OpenCV Error: Assertion failed (u != 0) in create, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/matrix.cpp, line 424 
 OpenCV Error: Assertion failed (u != 0) in create, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/matrix.cpp, line 424 
 thr1 error1 
 before1 
 proc1 - start new thread 
 after1 
 OpenCV Error: Insufficient memory (Failed to allocate 921600 bytes) in OutOfMemoryError, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/alloc.cpp, line 52 
 OpenCV Error: Assertion failed (u != 0) in create, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/matrix.cpp, line 424 
 thr1 error1 
 before1 
 proc1 - start new thread 
 OpenCV Error: Insufficient memory (Failed to allocate 921600 bytes) in OutOfMemoryError, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/alloc.cpp, line 52 
 OpenCV Error: Assertion failed (u != 0) in create, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/matrix.cpp, line 424 
 after1 
 OpenCV Error: Insufficient memory (Failed to allocate 921600 bytes) in OutOfMemoryError, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/alloc.cpp, line 52 
 OpenCV Error: Assertion failed (u != 0) in create, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/matrix.cpp, line 424 
 thr1 error1 
 before1 
 proc1 - start new thread 
 after1 
 OpenCV Error: Insufficient memory (Failed to allocate 921600 bytes) in OutOfMemoryError, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/alloc.cpp, line 52 
 OpenCV Error: Assertion failed (u != 0) in create, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/matrix.cpp, line 424 
 thr1 error1 
 before1 
 proc1 - start new thread 
 Java HotSpot(TM) Embedded Client VM warning: INFO: os::commit_memory(0xabfc7000, 12288, 0) failed; error='Cannot allocate memory' (errno=12) 
 # 
 after1OpenCV Error: Insufficient memory (Failed to allocate 921600 bytes) in OutOfMemoryError, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/alloc.cpp, line 52 
 OpenCV Error: Assertion failed (u != 0) in create, file /var/lib/jenkins/workspace/OpenCV-roborio/modules/core/src/matrix.cpp, line 424 
 Java HotSpot(TM) Embedded Client VM warning: INFO: os::commit_memory(0xab8c1000, 12288, 0) failed; error='Cannot allocate memory' (errno=12) 
 # There is insufficient memory for the Java Runtime Environment to continue. 
 [thread -1416559520 also had an error] 
 # Native memory allocation (mmap) failed to map 12288 bytes for committing reserved memory. 
 # An error report file with more information is saved as: 
 # //hs_err_pid1605.log 
 ➔ Launching «'/usr/local/frc/JRE/bin/java' '-Djava.library.path=/usr/local/frc/lib/' '-jar' '/home/lvuser/FRCUserProgram.jar'» 
 ********** Robot program starting ********** 
 Default IterativeRobot.disabledInit() method... Overload me! 
Warning  44003  FRC:  No robot code is currently running.  Driver Station 
 Default IterativeRobot.disabledPeriodic() method... Overload me! 
 Default IterativeRobot.robotPeriodic() method... Overload me! 
 NT: server: client CONNECTED: 10.30.34.17 port 52775
after a few seconds (after about 2-5 seconds) the code crash - the robot code is changing to red, and it restart the code.. why its happening ?
and before I did that with thread, I did that just in the teleop, and I found that if I add a thread.sleep() after the cap1.retrieve, if I write 300 (300 milliseconds) so the robot still working for about 2-3 seconds longer (and if I write 400 or 500 so its longer, but it still crash (and its not a good solution - to add big delay))

Any idea why its happening ? and how to fix that ?
Thanks in advance
Reply With Quote