mayur manyar
mayur manyar

Reputation: 11

Trace an image in python

I Wrote this python script to trace the image. But it is throwing an error. It is showing "IndexError: index 181 is out of bounds for axis 0 with size 181" where my image size is 181x158. I decreased the range in order to rectify this error but, no use.

import cv2
import numpy as np
global p
a = cv2.imread('t.png',0);
b = (255 -a);
c = np.asarray(b);
p = np.count_nonzero(c)
[ay , ax] = c.shape;
z = np.zeros(c.shape, dtype=np.int)

def startTrace(yt,xt):
    global p
    p = p-1
    z[yt,xt] = 255;
    c[yt,xt] =0;
    if (c[yt, xt+1] > 0):
        startTrace(yt,xt+1)
    elif (c[yt+1,xt+1] > 0):
        startTrace(yt+1,xt+1)
    elif (c[yt+1,xt] > 0):
        startTrace(yt+1,xt)
    elif (c[yt+1,xt-1] >0) :
        startTrace(yt+1,xt-1)
    elif (c[yt,xt-1] >0):
        startTrace(yt,xt-1)
    elif (c[yt-1,xt-1] > 0):
        startTrace(yt-1,xt-1)
    elif (c[yt-1,xt] > 0):
        startTrace(yt-1,xt)
    elif (c[yt-1,xt+1] > 0):
        startTrace(yt-1,xt+1)


while (p > 0):
    for y in range(1,ay-2):
        for x in range(1,ax-2):
            if c[y,x] > 0 :
                startTrace(y,x);

Upvotes: 1

Views: 4207

Answers (2)

mayur manyar
mayur manyar

Reputation: 11

Thanks to you all for your help. This code is working correctly.

import cv2
import numpy as np


global p
a = cv2.imread('t.png',0);
[ty,tx] = a.shape;
o = np.zeros((ty+2,tx+2),dtype=np.int)
o[1:ty+1,1:tx+1] = (255 -a);
c = np.asarray(o);
p = np.count_nonzero(c)
[ay , ax] = c.shape;
z = np.zeros(c.shape, dtype=np.int)

def startTrace(yt,xt):
    global p
    cv2.imshow('image',z);
    z[yt,xt] = 255;
    c[yt,xt] =0;
    p = np.count_nonzero(c)
    if((yt < ay-1) and (xt < ax -1)): 
        if (c[yt, xt+1] > 0):
            startTrace(yt,xt+1)
        elif (c[yt+1,xt+1] > 0):
            startTrace(yt+1,xt+1)
        elif (c[yt+1,xt] > 0):
            startTrace(yt+1,xt)
        elif (c[yt+1,xt-1] >0) :
            startTrace(yt+1,xt-1)
        elif (c[yt,xt-1] >0):
            startTrace(yt,xt-1)
        elif (c[yt-1,xt-1] > 0):
            startTrace(yt-1,xt-1)
        elif (c[yt-1,xt] > 0):
            startTrace(yt-1,xt)
        elif (c[yt-1,xt+1] > 0):
            startTrace(yt-1,xt+1)


while (p > 0):
    for y in range(1,ay-2):
        for x in range(1,ax-2):
            if (c[y,x] > 0) :
                startTrace(y,x);

Upvotes: 0

user2518618
user2518618

Reputation: 1408

Note that your code is recursive (startTrace calls itself) and you don't know how many times it will call itself. In fact, can you assure that a single call to startTrace() will ever exit? Could startTrace() call startTrace() forever? This would cause a stack overflow eventually. But this is not your problem (yet).

The code fails because each call to startTrace has different parameters (+1, -1) than the original call to startTrace(). Even if call inside the "while" assures that you are not out of bounds, if startTrace() is called recursively, each new call may have the original parameter +1, which eventually will grow to be out of bounds (there is no check inside startTrace() that the parameter is inside the bounds of the image). You should add an if at the beginning of your function to check that xt an yt are inside the bounds of the image.

Anyway, I would suggest to search in OpenCV for a method that does what you want. Take a look at findContours, for example.

Upvotes: 1

Related Questions