1 | initial version |
I am not well versed with the implementation of Java's Collections but I doubt contours.remove(i)
is doing exactly what you are thinking its doing.
You are removing an element from a container whilst iterating over it. If this even works, then i
will have an offset of sorts because the container might be changing lengths after each iteration. I would recommend looping over your container with an iterator then using it to remove elements or creating another list to hold the found squares as shown below
List<MatOfPoint> squareContours = new ArrayList<>();
//Remove contours that aren't close to a square shape.
for(int i = 0; i < contours.size(); ++i)
{
double area = Imgproc.contourArea( contours.get(i));
MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(i).toArray());
double perimeter = Imgproc.arcLength(contour2f, true);
//Found squareness equation on wiki...
// https://en.wikipedia.org/wiki/Shape_factor_(image_analysis_and_microscopy)
double squareness = 4 * Math.PI * area / Math.pow(perimeter, 2);
System.out.println("Squareness: " + squareness);
if(squareness <= 0.7 && squareness >= 0.8)
{
squareContours.add(contours[i]);
}
}
Then use squareContours
from this point onwards
2 | No.2 Revision |
I am not well versed with the implementation of Java's Collections but I doubt contours.remove(i)
is doing exactly what you are thinking its doing.
You are removing an element from a container whilst iterating over it. If this even works, then i
will have an offset of sorts because the container might be changing lengths after each iteration. I would recommend looping the following methods:
Method 1: Creating another list to hold the found squares as shown below
List<MatOfPoint> squareContours = new ArrayList<>();
//Remove contours that aren't close to a square shape.
for(int i = 0; i < contours.size(); ++i)
{
double area = Imgproc.contourArea(contours.get(i));
MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(i).toArray());
double perimeter = Imgproc.arcLength(contour2f, true);
//Found squareness equation on wiki...
// https://en.wikipedia.org/wiki/Shape_factor_(image_analysis_and_microscopy)
double squareness = 4 * Math.PI * area / Math.pow(perimeter, 2);
System.out.println("Squareness: " + squareness);
if(squareness <= 0.7 && squareness >= 0.8)
{
squareContours.add(contours[i]); // similar to squareContours.add(contours.get(i))
}
}
Then use squareContours
from this point onwards
Method 2:
Looping over your container with an iterator then using it to remove elements or creating another list to hold the found squares as shown below elements
List<MatOfPoint> squareContours = new ArrayList<>();
//Remove contours that aren't close to a square shape.
for(int i = 0; i < contours.size(); ++i)
ListIterator <MatOfPoint> iter = contours.listIterator();
while(iter.hasNext())
{
MatOfPoint contour = iter.next(); // this gets the actual element the iterator is pointing @
// then you can go ahead and perform other tasks.
double area = Imgproc.contourArea( contours.get(i));
MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(i).toArray());
double perimeter = Imgproc.arcLength(contour2f, true);
//Found squareness equation on wiki...
// https://en.wikipedia.org/wiki/Shape_factor_(image_analysis_and_microscopy)
double squareness = 4 * Math.PI * area / Math.pow(perimeter, 2);
System.out.println("Squareness: " + squareness);
Imgproc.contourArea(contour);
..................
if(squareness <= 0.7 && squareness >= 0.8)
{
squareContours.add(contours[i]);
iter.remove(); // this removes that particular element the iterator is pointing @
}
}
Then use squareContours
from this point onwards
3 | No.3 Revision |
I am not well versed with the implementation of Java's Collections but I doubt contours.remove(i)
is doing exactly what you are thinking its doing.
You are removing an element from a container whilst iterating over it. If this even works, then i
will have an offset of sorts because the container might be changing lengths after each iteration. I would recommend the following methods:
Method 1: Creating another list to hold the found squares as shown below
List<MatOfPoint> squareContours = new ArrayList<>();
//Remove contours that aren't close to a square shape.
for(int i = 0; i < contours.size(); ++i)
{
double area = Imgproc.contourArea(contours.get(i));
MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(i).toArray());
double perimeter = Imgproc.arcLength(contour2f, true);
//Found squareness equation on wiki...
// https://en.wikipedia.org/wiki/Shape_factor_(image_analysis_and_microscopy)
double squareness = 4 * Math.PI * area / Math.pow(perimeter, 2);
System.out.println("Squareness: " + squareness);
if(squareness <= >= 0.7 && squareness >= <= 0.8)
{
squareContours.add(contours[i]); // similar to squareContours.add(contours.get(i))
}
}
Then use squareContours
from this point onwards
Method 2: Looping over your container with an iterator then using it to remove elements
ListIterator <MatOfPoint> iter = contours.listIterator();
while(iter.hasNext())
{
MatOfPoint contour = iter.next(); // this gets the actual element the iterator is pointing @
// then you can go ahead and perform other tasks.
double area = Imgproc.contourArea(contour);
..................
if(squareness <= >= 0.7 && squareness >= <= 0.8)
{
iter.remove(); // this removes that particular element the iterator is pointing @
}
}
This and this might be helpful in understanding iterators in Java