Here is a link to the code and an XML file with the raw image.
https://drive.google.com/drive/folders/15fgQeUXAFV8LLjD6mn7UBVnZhnCxEW_k?usp=sharing
This code indicates that 10 contours are detected, 9 of which have duplicates.
Only the sixth (starting from zero) contour does not have duplicates.
Any help in figuring this out appreciated.
For the purposes of the forum, I am including a copy of the code.
The forum will not let me upload an XML file or any file big enough to store the raw image.
// constants for image processing
#define BILATERAL_DIAMETER 5
#define CANNY_SOBEL_SIZE 3
// constants for image cropping
#define CROPTOP 0
#define CROPLEFT 443
#define CROPRIGHT 545
#define CROPBOTTOM 169
#define OPENCV_BLACK Scalar(0, 0, 0)
using namespace cv;
int main()
{
Mat LoadFrame, GrayFrame, AnalysisFrame, MaskFrame;
bool Opened = false;
std::vector<std::vector<Point>> Contours;
std::vector<Vec4i> Hierarchy;
bool duplicatesfound = false;
int ContoursWithDupes = 0;
int BiggestContour = 0;
FileStorage fs("findContoursDuplicates.xml", FileStorage::READ);
Opened = fs.isOpened();
if (Opened)
fs["LoadFrame"] >> LoadFrame;
fs.releaseAndGetString();
if (Opened)
{
// convert the image to gray for Canny
cvtColor(LoadFrame, GrayFrame, COLOR_BGR2GRAY);
// apply a bilateral filter to reduce noise
bilateralFilter(GrayFrame, AnalysisFrame, BILATERAL_DIAMETER, 25, 25);
// run Canny and make white lines
MaskFrame = Mat::zeros(AnalysisFrame.rows, AnalysisFrame.cols, CV_8UC3);
Canny(AnalysisFrame, MaskFrame, 50, 100, CANNY_SOBEL_SIZE, false);
// crop the image to get rid of unwanted areas appearing in camera
if (CROPTOP != 0)
cv::rectangle(MaskFrame, cv::Point(0, 0), cv::Point(MaskFrame.cols, CROPTOP), OPENCV_BLACK, -1, 8);
if (CROPLEFT != 0)
cv::rectangle(MaskFrame, cv::Point(0, 0), cv::Point(CROPLEFT, MaskFrame.rows), OPENCV_BLACK, -1, 8);
if (CROPBOTTOM != 0)
cv::rectangle(MaskFrame, cv::Point(0, MaskFrame.rows - CROPBOTTOM - 1), cv::Point(MaskFrame.cols - 1, MaskFrame.rows - 1), OPENCV_BLACK, -1, 8);
if (CROPRIGHT != 0)
cv::rectangle(MaskFrame, cv::Point(MaskFrame.cols - CROPRIGHT - 1, 0), cv::Point(MaskFrame.cols - 1, MaskFrame.rows - 1), OPENCV_BLACK, -1, 8);
// determine the contours and store result in Contours
findContours(MaskFrame, Contours, Hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);
// check for duplicates
for (int x = 0; x < Contours.size(); x++)
{
for (int y = 0; y < Contours[x].size(); y++)
{
if (Contours[x].size() > BiggestContour)
BiggestContour = Contours[x].size();
for (int z = y + 1; z < Contours[x].size(); z++)
{
if (Contours[x][y].x == Contours[x][z].x)
{
if (Contours[x][y].y == Contours[x][z].y)
{
duplicatesfound = true;
ContoursWithDupes++;
break;
}
}
}
if (duplicatesfound == true)
break;
}
if (duplicatesfound == true)
{
std::cout << "Duplicate Contour: " << x;
for (int y = 0; y < Contours[x].size(); y++)
std::cout << " (" << Contours[x][y].x << "," << Contours[x][y].y << ")";
std::cout << std::endl;
}
duplicatesfound = false;
}
if (ContoursWithDupes != 0)
{
std::cout << "Total Contours: " << Contours.size() << std::endl;
std::cout << "Biggest Contour: " << BiggestContour << std::endl;
std::cout << "Contours With Dupes: " << ContoursWithDupes << std::endl;
}
else
{
imshow("Display Window", MaskFrame);
waitKey(4000);
}
}
else
std::cout << "File Not Found\n";
}