Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Detach blobs with a contact point

Hello. I'm working with blob analysis and i'm having problems on detaching 2 blobs which have a contact point. The images i'm working on are of this type:

image description image description

These are the same images binarized:

image description image description

My problem is morphological operators like erosion, dilation and opening don't work since the dimensions of the contact points are the same or even greater than some important points of the image (like the heads of the objects with 2 holes) and so when I set my operator (opening in this case) in order to delete contact points I end up deleting also parts of the image which I need to do other calculations (like number of holes per object).

I thought of applying a certain number of opening operators using a rectangle oriented as each of the objects as structuring element (as suggested here http://answers.opencv.org/question/56042/detach-two-blob/), but this solution doesn't work well, since it is not assured that the contact points are oriented as one of the objects involved (as it happens, for example, for the contact point in the inferior part of the second image). Anyone of you have ideas of how I could solve this problem?

click to hide/show revision 2
retagged

updated 2016-02-13 11:13:48 -0500

berak gravatar image

Detach blobs with a contact point

Hello. I'm working with blob analysis and i'm having problems on detaching 2 blobs which have a contact point. The images i'm working on are of this type:

image description image description

These are the same images binarized:

image description image description

My problem is morphological operators like erosion, dilation and opening don't work since the dimensions of the contact points are the same or even greater than some important points of the image (like the heads of the objects with 2 holes) and so when I set my operator (opening in this case) in order to delete contact points I end up deleting also parts of the image which I need to do other calculations (like number of holes per object).

I thought of applying a certain number of opening operators using a rectangle oriented as each of the objects as structuring element (as suggested here http://answers.opencv.org/question/56042/detach-two-blob/), but this solution doesn't work well, since it is not assured that the contact points are oriented as one of the objects involved (as it happens, for example, for the contact point in the inferior part of the second image). Anyone of you have ideas of how I could solve this problem?

Detach blobs with a contact point

Hello. I'm working with blob analysis and i'm having problems on detaching 2 blobs which have a contact point. The images i'm working on are of this type:

image description image description

These are the same images binarized:

image description image description

My problem is morphological operators like erosion, dilation and opening don't work since the dimensions of the contact points are the same or even greater than some important points of the image (like the heads of the objects with 2 holes) and so when I set my operator (opening in this case) in order to delete contact points I end up deleting also parts of the image which I need to do other calculations (like number of holes per object).

I thought of applying a certain number of opening operators using a rectangle oriented as each of the objects as structuring element (as suggested here http://answers.opencv.org/question/56042/detach-two-blob/), but this solution doesn't work well, since it is not assured that the contact points are oriented as one of the objects involved (as it happens, for example, for the contact point in the inferior part of the second image). Anyone of you have ideas of how I could solve this problem?

Edit: Here are the results thanks to sturkmen

image description image description

image description image description

Detach blobs with a contact point

Hello. I'm working with blob analysis and i'm having problems on detaching 2 blobs which have a contact point. The images i'm working on are of this type:

image description image description

These are the same images binarized:

image description image description

My problem is morphological operators like erosion, dilation and opening don't work since the dimensions of the contact points are the same or even greater than some important points of the image (like the heads of the objects with 2 holes) and so when I set my operator (opening in this case) in order to delete contact points I end up deleting also parts of the image which I need to do other calculations (like number of holes per object).

I thought of applying a certain number of opening operators using a rectangle oriented as each of the objects as structuring element (as suggested here http://answers.opencv.org/question/56042/detach-two-blob/), but this solution doesn't work well, since it is not assured that the contact points are oriented as one of the objects involved (as it happens, for example, for the contact point in the inferior part of the second image). Anyone of you have ideas of how I could solve this problem?

Edit: Here are the results thanks to sturkmen

image description image description

image description image description

And here's the code (pastebin cause it was a bit messed with the code snippet here).

Detach blobs with a contact point

Hello. I'm working with blob analysis and i'm having problems on detaching 2 blobs which have a contact point. The images i'm working on are of this type:

image description image description

These are the same images binarized:

image description image description

My problem is morphological operators like erosion, dilation and opening don't work since the dimensions of the contact points are the same or even greater than some important points of the image (like the heads of the objects with 2 holes) and so when I set my operator (opening in this case) in order to delete contact points I end up deleting also parts of the image which I need to do other calculations (like number of holes per object).

I thought of applying a certain number of opening operators using a rectangle oriented as each of the objects as structuring element (as suggested here http://answers.opencv.org/question/56042/detach-two-blob/), but this solution doesn't work well, since it is not assured that the contact points are oriented as one of the objects involved (as it happens, for example, for the contact point in the inferior part of the second image). Anyone of you have ideas of how I could solve this problem?

Edit: Here are the results thanks to sturkmen

image description image description

image description image description

And here's here's the code (pastebin (it's a little bit messy, sorry for that):

void detachRods(Mat& image) {
Mat invImage;
bitwise_not(image, invImage);
// Find contours
std::list<Point> defectPoints;
std::list<Point>::iterator it;
it = defectPoints.begin();
vector<Point> defectPointsVect;
vector<vector<Point> > contours;
vector<int> contoursHull;
vector<Vec4i> defects;
findContours(invImage, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

for ( size_t i = 0; i < contours.size(); i++)
{
    double contArea = contourArea(contours[i]);

    if(contourArea(contours[i]) > 6000) // This permits to not alter single rods, since 2 or 3 connected rods have a total area much bigger than a single rod
    {
        approxPolyDP(contours[i],contours[i],9,true);
        convexHull(contours[i], contoursHull,true);
        convexityDefects(contours[i], contoursHull,defects);

        for ( size_t j = 0; j <  defects.size(); j++)
        {
            Vec4i defpoint = defects[j];
            defectPoints.insert(it, contours[i][defpoint[2]]);
        }
    }
}

defectPointsVect = std::vector<Point>(std::begin(defectPoints), std::end(defectPoints));
float dist = 0;
int linesCount = 0;
for (int i=0; i<defectPointsVect.size(); i++)
{
    if (linesCount >= defectPointsVect.size()) break; // Needed to not redraw the same line 2 times
    for (int k=0; k<defectPointsVect.size(); k++)
    {
        if (i!=k)
        {
            dist = sqrt(std::pow((defectPointsVect[i].x-defectPointsVect[k].x), 2) + std::pow((defectPointsVect[i].y-defectPointsVect[k].y), 2));
            if (dist <= 25)
            {
                line(image, defectPointsVect[i], defectPointsVect[k], Scalar(B), 2);

                // Algorithm to fix the image after the rods have been detached (needed cause the detach process may detach also parts of the same rod too):
                // _________________________________________________________________________________________________________________________________________________________________
                // For each point of the line that detaches 2 rods (except 2 points at each extreme of the line), all his surrounding pixels are selected (8 connectovity).         |  
                // For each of this surrounding point, if it's value of grayscale in the image depict a foreground pixel, all his surrounding pixels are selected (4 connectovity)  |
                // For each of this surrounding pixel, if it was a bit messed with the code snippet here).

doesn't belong to the line that detaches 2 rods, it's grayscale level is set to foreground value. | // _________________________________________________________________________________________________________________________________________________________________| // // Grabs pixels along the line (pt1, pt2) LineIterator it(image, defectPointsVect[i], defectPointsVect[k], 8); std::vector<Point> linePoints(it.count); for(int i = 0; i < it.count; i++, ++it) linePoints[i] = it.pos(); for(int i = 2; i < it.count-2; i++) { for (int x=-1; x<=1; x++) { for (int y=-1; y<=1; y++) { Point pxlPoint(linePoints[i].x+x, linePoints[i].y+y); unsigned char pxlVal = image.at<uchar>(pxlPoint.y, pxlPoint.x); if (pxlVal == F) { Point topPxl(pxlPoint.x, pxlPoint.y-1); if (std::find(linePoints.begin(), linePoints.end(), topPxl) == linePoints.end()) image.at<uchar>(topPxl.y, topPxl.x) = F; Point botPxl(pxlPoint.x, pxlPoint.y+1); if (std::find(linePoints.begin(), linePoints.end(), botPxl) == linePoints.end()) image.at<uchar>(botPxl.y, botPxl.x) = F; Point leftPxl(pxlPoint.x-1, pxlPoint.y); if (std::find(linePoints.begin(), linePoints.end(), leftPxl) == linePoints.end()) image.at<uchar>(leftPxl.y, leftPxl.x) = F; Point rightPxl(pxlPoint.x+1, pxlPoint.y); if (std::find(linePoints.begin(), linePoints.end(), rightPxl) == linePoints.end()) image.at<uchar>(rightPxl.y, rightPxl.x) = F; } } } } linesCount++; } } } } }

Detach blobs with a contact point

Hello. I'm working with blob analysis and i'm having problems on detaching 2 blobs which have a contact point. The images i'm working on are of this type:

image description image description

These are the same images binarized:

image description image description

My problem is morphological operators like erosion, dilation and opening don't work since the dimensions of the contact points are the same or even greater than some important points of the image (like the heads of the objects with 2 holes) and so when I set my operator (opening in this case) in order to delete contact points I end up deleting also parts of the image which I need to do other calculations (like number of holes per object).

I thought of applying a certain number of opening operators using a rectangle oriented as each of the objects as structuring element (as suggested here http://answers.opencv.org/question/56042/detach-two-blob/), but this solution doesn't work well, since it is not assured that the contact points are oriented as one of the objects involved (as it happens, for example, for the contact point in the inferior part of the second image). Anyone of you have ideas of how I could solve this problem?

Edit: Here are the results thanks to sturkmen

image description image description

image description image description

And here's the code (it's a little bit messy, sorry for that):

void detachRods(Mat& image) {
Mat invImage;
bitwise_not(image, invImage);
// Find contours
std::list<Point> defectPoints;
std::list<Point>::iterator it;
it = defectPoints.begin();
vector<Point> defectPointsVect;
vector<vector<Point> > contours;
vector<int> contoursHull;
vector<Vec4i> defects;
findContours(invImage, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

for ( size_t i = 0; i < contours.size(); i++)
{
    double contArea = contourArea(contours[i]);

    if(contourArea(contours[i]) > 6000) // This permits to not alter single rods, since 2 or 3 connected rods have a total area much bigger than a single rod
    {
        approxPolyDP(contours[i],contours[i],9,true);
        convexHull(contours[i], contoursHull,true);
        convexityDefects(contours[i], contoursHull,defects);

        for ( size_t j = 0; j <  defects.size(); j++)
        {
            Vec4i defpoint = defects[j];
            defectPoints.insert(it, contours[i][defpoint[2]]);
        }
    }
}

defectPointsVect = std::vector<Point>(std::begin(defectPoints), std::end(defectPoints));
float dist = 0;
int linesCount = 0;
for (int i=0; i<defectPointsVect.size(); i++)
{
    if (linesCount >= defectPointsVect.size()) break; // Needed to not redraw the same line 2 times
    for (int k=0; k<defectPointsVect.size(); k++)
    {
        if (i!=k)
        {
            dist = sqrt(std::pow((defectPointsVect[i].x-defectPointsVect[k].x), 2) + std::pow((defectPointsVect[i].y-defectPointsVect[k].y), 2));
            if (dist <= 25)
            {
                line(image, defectPointsVect[i], defectPointsVect[k], Scalar(B), 2);

                // Algorithm to fix the image after the rods have been detached (needed cause the detach process may detach also parts of the same rod too):
                // _________________________________________________________________________________________________________________________________________________________________
                // For each point of the line that detaches 2 rods (except 2 points at each extreme of the line), all his surrounding pixels are selected (8 connectovity).         |  
                // For each of this surrounding point, if it's value of grayscale in the image depict a foreground pixel, all his surrounding pixels are selected (4 connectovity)  |
                // For each of this surrounding pixel, if it doesn't belong to the line that detaches 2 rods, it's grayscale level is set to foreground value.                      |
                // _________________________________________________________________________________________________________________________________________________________________|
                // 
                // Grabs pixels along the line (pt1, pt2)
                LineIterator it(image, defectPointsVect[i], defectPointsVect[k], 8);

                std::vector<Point> linePoints(it.count);
                for(int i = 0; i < it.count; i++, ++it) linePoints[i] = it.pos();

                for(int i = 2; i < it.count-2; i++)
                {
                    for (int x=-1; x<=1; x++)
                    {
                        for (int y=-1; y<=1; y++)
                        {
                            Point pxlPoint(linePoints[i].x+x, linePoints[i].y+y);
                            unsigned char pxlVal = image.at<uchar>(pxlPoint.y, pxlPoint.x);
                            if (pxlVal == F)
                            {
                                Point topPxl(pxlPoint.x, pxlPoint.y-1);
                                if (std::find(linePoints.begin(), linePoints.end(), topPxl) == linePoints.end()) 
                                    image.at<uchar>(topPxl.y, topPxl.x) = F;

                                Point botPxl(pxlPoint.x, pxlPoint.y+1);
                                if (std::find(linePoints.begin(), linePoints.end(), botPxl) == linePoints.end()) 
                                    image.at<uchar>(botPxl.y, botPxl.x) = F;

                                Point leftPxl(pxlPoint.x-1, pxlPoint.y);
                                if (std::find(linePoints.begin(), linePoints.end(), leftPxl) == linePoints.end()) 
                                    image.at<uchar>(leftPxl.y, leftPxl.x) = F;

                                Point rightPxl(pxlPoint.x+1, pxlPoint.y);
                                if (std::find(linePoints.begin(), linePoints.end(), rightPxl) == linePoints.end()) 
                                    image.at<uchar>(rightPxl.y, rightPxl.x) = F;

                            }
                        }
                    }
                }

                linesCount++;
            }
        }
    }
}   }

Detach blobs with a contact point

Hello. I'm working with blob analysis and i'm having problems on detaching 2 blobs which have a contact point. The images i'm working on are of this type:

image description image description

These are the same images binarized:

image description image description

My problem is morphological operators like erosion, dilation and opening don't work since the dimensions of the contact points are the same or even greater than some important points of the image (like the heads of the objects with 2 holes) and so when I set my operator (opening in this case) in order to delete contact points I end up deleting also parts of the image which I need to do other calculations (like number of holes per object).

I thought of applying a certain number of opening operators using a rectangle oriented as each of the objects as structuring element (as suggested here http://answers.opencv.org/question/56042/detach-two-blob/), but this solution doesn't work well, since it is not assured that the contact points are oriented as one of the objects involved (as it happens, for example, for the contact point in the inferior part of the second image). Anyone of you have ideas of how I could solve this problem?

Edit: Here are the results thanks to sturkmen

image description image description

image description image description

Detach blobs with a contact point

Hello. I'm working with blob analysis and i'm having problems on detaching 2 blobs which have a contact point. The images i'm working on are of this type:

image description image description

These are the same images binarized:

image description image description

My problem is morphological operators like erosion, dilation and opening don't work since the dimensions of the contact points are the same or even greater than some important points of the image (like the heads of the objects with 2 holes) and so when I set my operator (opening in this case) in order to delete contact points I end up deleting also parts of the image which I need to do other calculations (like number of holes per object).

I thought of applying a certain number of opening operators using a rectangle oriented as each of the objects as structuring element (as suggested here http://answers.opencv.org/question/56042/detach-two-blob/), but this solution doesn't work well, since it is not assured that the contact points are oriented as one of the objects involved (as it happens, for example, for the contact point in the inferior part of the second image). Anyone of you have ideas of how I could solve this problem?

Edit: Here are the results thanks to sturkmen

image description image description

image description image description