2

I would like to use the selective search algorithm to segment images into possible object locations. I found that the library I already use for computer vision, OpenCV, implements this functionality as shown in the documentation here. However, I'm using Python and not C++, so I looked through OpenCV's github repositories until I found the example that I reproduced below.

#!/usr/bin/env python

'''
A program demonstrating the use and capabilities of a particular image segmentation algorithm described
in Jasper R. R. Uijlings, Koen E. A. van de Sande, Theo Gevers, Arnold W. M. Smeulders:
    "Selective Search for Object Recognition"
International Journal of Computer Vision, Volume 104 (2), page 154-171, 2013
Usage:
    ./selectivesearchsegmentation_demo.py input_image (single|fast|quality)
Use "a" to display less rects, 'd' to display more rects, "q" to quit.
'''

import cv2
import sys

if __name__ == '__main__':
    img = cv2.imread(sys.argv[1])

    cv2.setUseOptimized(True)
    cv2.setNumThreads(8)

    gs = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()
    gs.setBaseImage(img)

    if (sys.argv[2][0] == 's'):
        gs.switchToSingleStrategy()

    elif (sys.argv[2][0] == 'f'):
        gs.switchToSelectiveSearchFast()

    elif (sys.argv[2][0] == 'q'):
        gs.switchToSelectiveSearchQuality()
    else:
        print(__doc__)
        sys.exit(1)

    rects = gs.process()
    nb_rects = 10

    while True:
        wimg = img.copy()

        for i in range(len(rects)):
            if (i < nb_rects):
                x, y, w, h = rects[i]
                cv2.rectangle(wimg, (x, y), (x+w, y+h), (0, 255, 0), 1, cv2.LINE_AA)

        cv2.imshow("Output", wimg);
        c = cv2.waitKey()

        if (c == 100):
            nb_rects += 10

        elif (c == 97 and nb_rects > 10):
            nb_rects -= 10

        elif (c == 113):
            break

    cv2.destroyAllWindows()

Unfortunately, running this program with the command python selective_search.py "/home/christopher/DroneKit/Vision/Face Detection/Annotated Faces in the Wild/originalPics/2002/07/19/big/img_135.jpg" f gives me the following error:

Traceback (most recent call last):
  File "selective_search.py", line 37, in <module>
    rects = gs.process()
TypeError: Required argument 'rects' (pos 1) not found

Based upon that error message, I figured maybe I could just pass it a Python list and then the underlying C++ function would fill it with the algorithm's output. However, when I excecuted the following code:

rects = []
gs.process(rects)
print(rects)

The output was an empty list, and the image was displayed with no rectangles drawn on it. Therefore, I am at a loss on how I should call gs.process(). If it helps, the C++ declaration of the function is

CV_WRAP virtual void process(CV_OUT std::vector<Rect>& rects) = 0;

(Edit) Additional information copied from the comments:

Output from help(gs.process):

process(...) method of cv2.ximgproc_segmentation_SelectiveSearchSegmentation instance process(rects) -> None. rects = gs.process(rects) just makes rects None and causes the program to terminate with an exception

Using rects = gs.process(rects) sets rects to None and causes the program to terminate with an exception.

OpenCV version is 3.2.0.

Using a numpy array instead of a python list crashes my program with the following message:

OpenCV Error: Assertion failed (channels() == CV_MAT_CN(dtype)) in copyTo, file /home/christopher/opencv/modules/core/src/copy.cpp, line 259
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/christopher/opencv/modules/core/src/copy.cpp:259: error: (-215) channels() == CV_MAT_CN(dtype) in function copyTo

Aborted (core dumped)
6
  • Try help(gs.process) and see what it tells you. IIRC CV_WRAP with CV_OUT parameter means that in Python it will be an argument, as well as one of the return values. Usually the argument is optional, but I guess this is a proof that not always. Hence I would expect you want rects = gs.process(rects). Commented Aug 5, 2017 at 23:11
  • 1
    @Dan Mašek process(...) method of cv2.ximgproc_segmentation_SelectiveSearchSegmentation instance process(rects) -> None. rects = gs.process(rects) just makes rects None and causes the program to terminate with an exception. Commented Aug 5, 2017 at 23:17
  • What if you try to pass a numpy array instead of a Python list? What version of OpenCV is this? Commented Aug 5, 2017 at 23:34
  • 1
    @Dan Mašek It's OpenCV 3.2.0. Using rects = np.array([]); gs.process(rects) crashes my program with the following message OpenCV Error: Assertion failed (channels() == CV_MAT_CN(dtype)) in copyTo, file /home/christopher/opencv/modules/core/src/copy.cpp, line 259 terminate called after throwing an instance of 'cv::Exception' what(): /home/christopher/opencv/modules/core/src/copy.cpp:259: error: (-215) channels() == CV_MAT_CN(dtype) in function copyTo Aborted (core dumped) Commented Aug 5, 2017 at 23:42
  • 1
    @Dan Mašek Created a ticket: github.com/opencv/opencv_contrib/issues/1312 Commented Aug 6, 2017 at 1:08

1 Answer 1

1

Apparently, the version of OpenCV 3.2.0 that I compiled for Python was missing this fix locally. I went ahead and recompiled my python bindings using the latest stable release of OpenCV 3.3.0 and the latest changes to the OpenCV contrib repository and the sample script worked as expected after that.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.