-1

I'm working on a project in which I have to detect some disease on leaves. For this purpose, I've to detect salient features i.e. leaves (in my case) and remove the background of the image. I've the following code.

    import cv2, sys
    import numpy as np

    def backproject(source, target, levels = 2, scale = 1):
            hsv = cv2.cvtColor(source,  cv2.COLOR_BGR2HSV)
            hsvt = cv2.cvtColor(target, cv2.COLOR_BGR2HSV)
            # calculating object histogram
            roihist = cv2.calcHist([hsv],[0, 1], None, [levels, levels], [0, 180, 0, 256] )

            # normalize histogram and apply backprojection
            cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)
            dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256], scale)
            return dst

    def saliency_by_backprojection(img):
            cv2.pyrMeanShiftFiltering(img, 2, 10, img, 4)

            backproj = np.uint8(backproject(img, img, levels = 2))
            cv2.normalize(backproj,backproj,0,255,cv2.NORM_MINMAX)
            saliencies = [backproj, backproj, backproj]
            saliency = cv2.merge(saliencies)

            cv2.pyrMeanShiftFiltering(saliency, 20, 200, saliency, 2)
            saliency = cv2.cvtColor(saliency, cv2.COLOR_BGR2GRAY)
            cv2.equalizeHist(saliency, saliency)

            return 255-saliency

    def saliency_map(img):
            saliency_hsv = saliency_by_backprojection(img * 1)
            saliency = saliency_hsv
            (T, saliency) = cv2.threshold(saliency, 200, 255, cv2.THRESH_BINARY)
            return saliency

    def largest_contours_rect(saliency):
            contours, hierarchy = cv2.findContours(saliency * 1,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
            contours = sorted(contours, key = cv2.contourArea)
            return cv2.boundingRect(contours[-1])

    def refine_saliency_with_grabcut(img, saliency):
            rect = largest_contours_rect(saliency)
            bgdmodel = np.zeros((1, 65),np.float64)
            fgdmodel = np.zeros((1, 65),np.float64)
            saliency[np.where(saliency > 0)] = cv2.GC_FGD
            mask = saliency
            cv2.grabCut(img, mask, rect, bgdmodel, fgdmodel, 1, cv2.GC_INIT_WITH_RECT)
            mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
            return mask

    def backprojection_saliency(img):
            saliency = saliency_map(img)
            mask = refine_saliency_with_grabcut(img, saliency)
            return mask

    if __name__ == "__main__":
            name = sys.argv[1].strip('k5.jpg')

            img = cv2.imread(sys.argv[1], 1)
            img = cv2.resize(img, (640/2, 480/2))
            mask = backprojection_saliency(img)
            segmentation = img*mask[:,:,np.newaxis]

            cv2.imshow("original", img)
            cv2.imshow("segmentation", segmentation)
            cv2.waitKey(-1)

Since I'm new to Python and openCV, I am unable to resolve the following error.

        Traceback (most recent call last):
         File "F:\FYP\Code\saliency-from-backproj-master\saliency.py", line 
      56, in <module>
            name = sys.argv[1].strip('k5.jpg')
           IndexError: list index out of range

Why is this happening?

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Ezza Ali
  • 1
  • 1
  • 4
  • 1
    Looks like you are not passing the required number of arguments to your script – Rakesh Jan 25 '18 at 10:59
  • You are calling argv[1], so the 2nd argument. As you might be calling your script with less than 2 arguments, your program tries to access something that does not exist. Hence the "IndexError". – IMCoins Jan 25 '18 at 11:03
  • Perhaps you should spend a little time learning core Python before you try to use it with advanced tools like OpenCV. Not only will that eliminate most problems like this one, it will also make it easier to understand the `cv2` module docs. – PM 2Ring Jan 25 '18 at 11:09
  • Not only is this a duplicate (and something easy to debug anyway), but also you posted lines and lines of totally unrelated code. Please learn to reduce your code to a MCVE before posting (https://stackoverflow.com/help/mcve) – bruno desthuilliers Jan 25 '18 at 12:03
  • Unrelated: you might want to read the doc for `str.strip()` too (and try it out in your interactive python shell) - this : `sys.argv[1].strip('k5.jpg')` is certainly not going to do what you expect. – bruno desthuilliers Jan 25 '18 at 12:05

1 Answers1

0

You're not supplying any command line arguments.
argv variable contains the command line arguments passed into a program. Like when you do python your_script.py verbose print, the argv variable contains ['your_script.py', 'verbose', 'print'].
However, if you only supply python your_script.py argv contains ['your_script.py'] (only one element argv[0]). So, call to argv[1] is an IndexError.

Python documentation on sys.agv:

sys.argv
The list of command line arguments passed to a Python script. argv[0] is the script name (it is operating system dependent whether this is a full pathname or not). If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'. If no script name was passed to the Python interpreter, argv[0] is the empty string.

jpp
  • 159,742
  • 34
  • 281
  • 339
Anuj Gautam
  • 1,235
  • 1
  • 7
  • 14