Eroding with subsequent dilation will distort the shape of your triangles. You can use connected components (CC) or even better a floodFill and remove (fill with zeros) based on the area (floodFill outputs the area of every CC it finds). Of course if you are sure that what you want to preserve is always triangles you can add an extra step to verify a triangular shape before erasing noise. The code below finds the largest segment and outlines its contour in red. Verification of triangle shape is indicated by green circles and can be further explored by a looking at a polygonal approximation in approx vector.
vector<vector<Point> > contours;
Mat hierarchy, I Icol;
Icol = imread("triang.png");
cvtColor(Icol, I, CV_BGR2GRAY);
// Find connected components (CC)
findContours(I.clone(), contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
// Select the largest CC
int ncontours = contours.size();
int max_sz = 0, max_idx;
for (int i=0; i<ncontours; i++) {
int sz = contours[i].size();
if (max_sz<sz) {
max_sz = sz;
max_idx = i;
}
}
for (int i=0; i<max_sz; i++) {
Point pt = contours[max_idx][i];
Icol.at<Vec3b>(pt.y, pt.x) = Vec3b(0, 0, 255);
}
// Verify triangle
vector<Point> approx;
approxPolyDP(contours[max_idx], approx, 10, true);
cout<<Mat(approx)<<endl;
for (int i=0; i<approx.size(); i++) {
Point pt = approx[i];
circle(Icol, pt, 3, Scalar(0, 255, 0), 2);
}
imshow("largest", Icol); imwrite("triangle.png", Icol);
waitKey(-1);
