Ask Your Question
1

Find nodes in an image

asked 2015-11-30 09:33:27 -0600

Neil96 gravatar image

updated 2017-08-25 13:55:29 -0600

Below is an image having 5 X 4 grid numbered as shown. The grid is made up of nodes which can be represented by x and y co-ordinates as shown in the figure. For example, the node highlighted by the blue circle can be represented as (X, Y) = (3, 2)

I want to write a python program using opencv2 module to save the nodes into an array. Can anyone please help me to do the same I am using pyhton 2.7

edit retag flag offensive close merge delete

Comments

What's a node for you? Only those intersections with 4 children (like your (3,2)) or also those with 3 children (like (4,1)) or 2 children (like (2,0)) ?

LorenaGdL gravatar imageLorenaGdL ( 2015-11-30 11:25:54 -0600 )edit

all 4 3 2 1children

Neil96 gravatar imageNeil96 ( 2015-11-30 11:55:04 -0600 )edit

If you want 1, 2, 3 and 4 children, then you have the whole set of coordinates pairs...

LorenaGdL gravatar imageLorenaGdL ( 2015-11-30 11:58:29 -0600 )edit

you could use matchTemplate with a template for intersection or hit and miss (recently available thanks to @LorenaGdL in morphologyex)

pklab gravatar imagepklab ( 2015-11-30 12:34:38 -0600 )edit

sorry i do not understand

Neil96 gravatar imageNeil96 ( 2015-11-30 12:44:09 -0600 )edit

What don't you understand?

LorenaGdL gravatar imageLorenaGdL ( 2015-11-30 13:17:40 -0600 )edit

what do u mean by whole set of coordinates ,, how to have it

Neil96 gravatar imageNeil96 ( 2015-11-30 13:37:34 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
6

answered 2015-11-30 17:25:15 -0600

theodore gravatar image

updated 2015-12-01 13:33:53 -0600

An example in C++ that can easily ported in python is the following (bear in mind that there are quite some techniques that you could follow, such as to apply a skeletonize algorithm first, etc...):

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // Load source image
    string filename = "nodes.bmp";
    Mat src = imread(filename);

    // Check if image is loaded fine
    if(!src.data)
        cerr << "Problem loading image!!!" << endl;

    // Show source image
    imshow("src", src);

    // Transform source image to gray if it is not
    Mat gray;

    if (src.channels() == 3)
    {
        cvtColor(src, gray, CV_BGR2GRAY);
    }
    else
    {
        gray = src;
    }

    // Show gray image
    imshow("gray", gray);

    // Apply threshold to grayscale image
    Mat bw;
    threshold(gray, bw, 50, 255, THRESH_BINARY || THRESH_OTSU);

    // Show binary image
    imshow("binary", bw);

    // Create the images that will use to extract the horizonta and vertical lines
    Mat horizontal = bw.clone();
    Mat vertical = bw.clone();

    // Specify size on horizontal axis
    int horizontalsize = horizontal.cols / 10;

    // Create structure element for extracting horizontal lines through morphology operations
    Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontalsize,1));

    // Apply morphology operations
    erode(horizontal, horizontal, horizontalStructure, Point(-1, -1));
    dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1));
    horizontalStructure = getStructuringElement(MORPH_RECT, Size(500,1)); // 500 is a random value choose whatever you want here
    dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1)); // expand horizontal lines

    // Show extracted horizontal lines
    imshow("horizontal", horizontal);

    // Specify size on vertical axis
    int verticalsize = vertical.rows / 10;

    // Create structure element for extracting vertical lines through morphology operations
    Mat verticalStructure = getStructuringElement(MORPH_RECT, Size( 1,verticalsize));

    // Apply morphology operations
    erode(vertical, vertical, verticalStructure, Point(-1, -1));
    dilate(vertical, vertical, verticalStructure, Point(-1, -1));
    verticalStructure = getStructuringElement(MORPH_RECT, Size( 1,500)); // same stand here as previous
    dilate(vertical, vertical, verticalStructure, Point(-1, -1)); // expand vertical lines

    // Show extracted vertical lines
    imshow("vertical", vertical);

    Mat joints;
    bitwise_and(horizontal, vertical, joints);
    imshow("joints", joints);

    vector<vector<Point> > contours;
    findContours(joints, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE);

    /// Get the moments
    vector<Moments> mu(contours.size() );
    for( size_t i = 0; i < contours.size(); i++ )
        { mu[i] = moments( contours[i], false ); }

    ///  Get the mass centers:
    vector<Point2f> mc( contours.size() );
    for( size_t i = 0; i < contours.size(); i++ )
        { mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }

    struct Less
    {
        bool operator () (const Point2f &a, const Point2f &b)
        {
            return (a.x + a.y*10000) < (b.x + b.y*10000);
        }
    };

    std::sort(mc.begin(), mc.end(), Less());

    for( size_t i = 0; i< contours.size(); i++ )
    {
        string text = to_string(static_cast<int>(i));
        Point origin = Point(mc[i].x + 1, mc[i].y + 20);

        if((mc[i].x + 20) > src.cols/* && mc[i].y < src.rows*/)
            origin = Point(mc[i].x - 25, mc[i].y + 22);
        if ((mc[i].y + 20) > src.rows/* && mc[i].x < src.cols*/)
            origin = Point(mc[i].x + 1, mc[i].y - 10);
        if (((mc[i].x + 20) > src.cols) && ((mc[i].y + 20) > src.rows))
            origin = Point(mc[i].x - 27, mc[i].y - 10);

        putText(src, text, origin, FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar( 0, 255, 0 ...
(more)
edit flag offensive delete link more

Comments

Thank U Sir But is there a way to count even the nodes displayed in green as shown in this figure lfigure link

Neil96 gravatar imageNeil96 ( 2015-11-30 21:16:54 -0600 )edit
3

Nice answer from @theodore even if user questions looks not clear. @Neil96 at the end do you want all grid points ? do you want intersections classified by type ?... what do you want exactly ?

pklab gravatar imagepklab ( 2015-12-01 02:59:39 -0600 )edit

@Neil96 in order to achieve what you are showing in the link above, as I said just expand the horizontal and vertical extracted lines and then you just follow the same procedure. I will try to update my answer when I go back home until then you try to do it by yourself as a task :-p....

theodore gravatar imagetheodore ( 2015-12-01 03:16:06 -0600 )edit

+1 I am still wondering where you got the image from :D original topic does not show it?

StevenPuttemans gravatar imageStevenPuttemans ( 2015-12-01 03:54:27 -0600 )edit
1

@StevenPuttemans paint did the trick :-p...

theodore gravatar imagetheodore ( 2015-12-01 05:14:16 -0600 )edit
1

@StevenPuttemans it did show it, but then he updated the question and it misteriously disappeared...

LorenaGdL gravatar imageLorenaGdL ( 2015-12-01 07:43:21 -0600 )edit

@Neil96 the updated code should give the corresponding updated image as you wanted.

theodore gravatar imagetheodore ( 2015-12-01 13:35:48 -0600 )edit
1

Thank You Guys .. Hats of to you @theodore

Neil96 gravatar imageNeil96 ( 2015-12-01 22:14:45 -0600 )edit

can anybody please explain the section of the code from "GET THE MOMENTS". What is done?

pari16 gravatar imagepari16 ( 2015-12-05 09:38:31 -0600 )edit

@pari16 once you have the contours of the extracted joints you need to find the centers of each contour. There are different ways to do it. One of them is to extract the hu moments of each contour and then extract the centers by using these moments as I am doing in the "Get the mass centers" part. Once you have the centers, is not guaranteed that are sorted properly. Therefore the next part of the code sorts these extracted center points from top to the bottom and from left to the right. As for the last for loop it just analyzes where to put the text regarding how close these center points are to the image borders, in order to avoid putting the text outside the limits of the image. I hope it helped.

theodore gravatar imagetheodore ( 2015-12-06 07:12:12 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2015-11-30 09:33:27 -0600

Seen: 1,210 times

Last updated: Dec 01 '15