Let's swap data!
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 06-02-2017, 18:32
PhilBot's Avatar
PhilBot PhilBot is offline
Get a life? This IS my life!
AKA: Phil Malone
FRC #1629 (GaCo: The Garrett Coalition)
Team Role: Mentor
 
Join Date: Jan 2006
Rookie Year: 2006
Location: Maryland
Posts: 756
PhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond repute
Sort array in filterContours

Hi

New to Java....

In the Grip generated pipeline code, I want to sort the list of filtered contours to locate the best matches....

Assuming for the moment that I wanted to use area, can anyone show me a code snipit that I can add to the filterContours() method to sort the output array....

Seems like I need to use the Collections.sort() method but I can't get it to accept my arguments.

Code:
	/**
	 * Filters out contours that do not meet certain criteria.
	 * @param inputContours is the input list of contours
	 * @param output is the the output list of contours
	 * @param minArea is the minimum area of a contour that will be kept
	 * @param minPerimeter is the minimum perimeter of a contour that will be kept
	 * @param minWidth minimum width of a contour
	 * @param maxWidth maximum width
	 * @param minHeight minimum height
	 * @param maxHeight maximimum height
	 * @param Solidity the minimum and maximum solidity of a contour
	 * @param minVertexCount minimum vertex Count of the contours
	 * @param maxVertexCount maximum vertex Count
	 * @param minRatio minimum ratio of width to height
	 * @param maxRatio maximum ratio of width to height
	 */
	private void filterContours(List<MatOfPoint> inputContours, double minArea,
		double minPerimeter, double minWidth, double maxWidth, double minHeight, double
		maxHeight, double[] solidity, double maxVertexCount, double minVertexCount, double
		minRatio, double maxRatio, List<MatOfPoint> output) {
		final MatOfInt hull = new MatOfInt();
		output.clear();
		
		//operation
		for (int i = 0; i < inputContours.size(); i++) {
			final MatOfPoint contour = inputContours.get(i);
			final Rect bb = Imgproc.boundingRect(contour);
			if (bb.width < minWidth || bb.width > maxWidth) continue;
			if (bb.height < minHeight || bb.height > maxHeight) continue;
			final double area = Imgproc.contourArea(contour);
			if (area < minArea) continue;
			if (Imgproc.arcLength(new MatOfPoint2f(contour.toArray()), true) < minPerimeter) continue;
			Imgproc.convexHull(contour, hull);
			
			// Add new huul
			MatOfPoint mopHull = new MatOfPoint();
			mopHull.create((int) hull.size().height, 1, CvType.CV_32SC2);
			for (int j = 0; j < hull.size().height; j++) {
				int index = (int)hull.get(j, 0)[0];
				double[] point = new double[] { contour.get(index, 0)[0], contour.get(index, 0)[1]};
				mopHull.put(j, 0, point);
			}
			final double solid = 100 * area / Imgproc.contourArea(mopHull);
			if (solid < solidity[0] || solid > solidity[1]) continue;
			if (contour.rows() < minVertexCount || contour.rows() > maxVertexCount)	continue;
			final double ratio = bb.width / (double)bb.height;
			if (ratio < minRatio || ratio > maxRatio) continue;
			
			// Add to main output list
			output.add(contour);
		}

	}
__________________
Phil Malone
Garrett Engineering And Robotics Society (GEARS) founder.
http://www.GEARSinc.org

FRC1629 Mentor, FTC2818 Coach, FTC4240 Mentor, FLL NeXTGEN Mentor
Reply With Quote
  #2   Spotlight this post!  
Unread 07-02-2017, 06:58
pblankenbaker pblankenbaker is offline
Registered User
FRC #0868
 
Join Date: Feb 2012
Location: Carmel, IN, USA
Posts: 124
pblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of light
Re: Sort array in filterContours

When sorting objects with the Collections.sort() method, you will typically want to supply the "comparator" parameter that lets you control the comparison between each object (decide which should come before the other).

For example, if you want to sort by area, I think you can use a static helper method something like the following:

Code:
  public static void sortContoursByArea(List<MatOfPoint> contours) {
    Collections.sort(contours, new Comparator<MatOfPoint>() {

      @Override
      public int compare(MatOfPoint a, MatOfPoint b) {
        // Not sure how expensive this will be computationally as the
        // area is computed for each comparison
        double areaA = Imgproc.contourArea(a);
        double areaB = Imgproc.contourArea(b);

        // Change sign depending on whether your want sorted small to big
        // or big to small
        if (areaA < areaB) {
          return -1;
        } else if (areaA > areaB) {
          return 1;
        }
        return 0;
      }
    });
  }
Hope that helps
Reply With Quote
  #3   Spotlight this post!  
Unread 07-02-2017, 10:03
SamCarlberg's Avatar
SamCarlberg SamCarlberg is offline
GRIP, WPILib. 2084 alum
FRC #2084
Team Role: Mentor
 
Join Date: Nov 2015
Rookie Year: 2009
Location: MA
Posts: 169
SamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to behold
Re: Sort array in filterContours

FWIW you could also write that as

Code:
public static void sortContoursByArea(List<MatOfPoint> contours) {
  Collections.sort(contours, Comparator.comparingDouble(Imgproc::contourArea));
}
__________________
WPILib
GRIP, RobotBuilder
Reply With Quote
  #4   Spotlight this post!  
Unread 07-02-2017, 12:05
PhilBot's Avatar
PhilBot PhilBot is offline
Get a life? This IS my life!
AKA: Phil Malone
FRC #1629 (GaCo: The Garrett Coalition)
Team Role: Mentor
 
Join Date: Jan 2006
Rookie Year: 2006
Location: Maryland
Posts: 756
PhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond repute
Re: Sort array in filterContours

Quote:
Originally Posted by pblankenbaker View Post
When sorting objects with the Collections.sort() method, you will typically want to supply the "comparator" parameter that lets you control the comparison between each object (decide which should come before the other).

For example, if you want to sort by area, I think you can use a static helper method something like the following:
Hope that helps
Terrific. We were heading in that direction but couldn't get the eclipse to accept our code.

We were just trying to call the Collections.sort in-line.

Your static method went in with no problems.

I'll have to investigate further to understand why the static method worked, but the inline code didn't.

Thanks again for the detailed response.
__________________
Phil Malone
Garrett Engineering And Robotics Society (GEARS) founder.
http://www.GEARSinc.org

FRC1629 Mentor, FTC2818 Coach, FTC4240 Mentor, FLL NeXTGEN Mentor
Reply With Quote
  #5   Spotlight this post!  
Unread 07-02-2017, 12:13
PhilBot's Avatar
PhilBot PhilBot is offline
Get a life? This IS my life!
AKA: Phil Malone
FRC #1629 (GaCo: The Garrett Coalition)
Team Role: Mentor
 
Join Date: Jan 2006
Rookie Year: 2006
Location: Maryland
Posts: 756
PhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond repute
Re: Sort array in filterContours

Quote:
Originally Posted by SamCarlberg View Post
FWIW you could also write that as

Code:
public static void sortContoursByArea(List<MatOfPoint> contours) {
  Collections.sort(contours, Comparator.comparingDouble(Imgproc::contourArea));
}
That's a really interesting syntax.

Is there a name for what is hapening with "Imgproc::contourArea" ?
I'd like to look up the explanation of how that works...

Clearly it's getting expanded internally into Imgprog.contourArea(contours[n]) for the comparison.... but I don't know how/why.....
__________________
Phil Malone
Garrett Engineering And Robotics Society (GEARS) founder.
http://www.GEARSinc.org

FRC1629 Mentor, FTC2818 Coach, FTC4240 Mentor, FLL NeXTGEN Mentor
Reply With Quote
  #6   Spotlight this post!  
Unread 07-02-2017, 13:12
SamCarlberg's Avatar
SamCarlberg SamCarlberg is offline
GRIP, WPILib. 2084 alum
FRC #2084
Team Role: Mentor
 
Join Date: Nov 2015
Rookie Year: 2009
Location: MA
Posts: 169
SamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to beholdSamCarlberg is a splendid one to behold
Re: Sort array in filterContours

That's called a method reference.

This article explains it quite well

Also, you don't even need a special method for sorting a list. The List interface defines a method "sort(Comparator)" that you can use inline like

Code:
contours.sort(Comparator.comparingDouble(Imgproc::contourArea));
__________________
WPILib
GRIP, RobotBuilder
Reply With Quote
  #7   Spotlight this post!  
Unread 07-02-2017, 14:01
PhilBot's Avatar
PhilBot PhilBot is offline
Get a life? This IS my life!
AKA: Phil Malone
FRC #1629 (GaCo: The Garrett Coalition)
Team Role: Mentor
 
Join Date: Jan 2006
Rookie Year: 2006
Location: Maryland
Posts: 756
PhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond reputePhilBot has a reputation beyond repute
Re: Sort array in filterContours

Quote:
Originally Posted by SamCarlberg View Post
That's called a method reference.

This article explains it quite well

Also, you don't even need a special method for sorting a list. The List interface defines a method "sort(Comparator)" that you can use inline like

Code:
contours.sort(Comparator.comparingDouble(Imgproc::contourArea));
Dang... As an "vintage" programmer, it's sometimes scary when I realize how much I don't know about the "newer" languages. That's pretty darn powerful.
__________________
Phil Malone
Garrett Engineering And Robotics Society (GEARS) founder.
http://www.GEARSinc.org

FRC1629 Mentor, FTC2818 Coach, FTC4240 Mentor, FLL NeXTGEN Mentor
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 15:35.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi