Razgriz
Razgriz

Reputation: 7343

Python OpenCV - ConvexHull error "Points is not a numpy array, neither a scalar"?

I'm trying to run some Convex Hull image processing. Basically what I want to do is to close off an open contour.

I found this answer over at the opencv forum and it's exactly what I wanted to do. I started converting the code from C++ to Python some time ago. I succeeded with converting the code of the question, but the code for the answer is giving me a tougher time than expected.

This is what I have so far:

import cv2
import numpy as np

def contoursConvexHull(contours):
    print("contours length = ", len(contours))
    print("contours length of first item = ", len(contours[1]))
    pts = []
    for i in range(0, len(contours)):
        for j in range(0, len(contours[i])):
            pts.append(contours[i][j])

    result = cv2.convexHull(pts)
    return result

# Get our image in color mode (1)
src = cv2.imread("source.png", 1);

# Convert the color from BGR to Gray
srcGray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

# Use Gaussian Blur 
srcBlur = cv2.GaussianBlur(srcGray, (3, 3), 0)

# ret is the returned value, otsu is an image
ret, otsu = cv2.threshold(srcBlur, 0, 255,
                          cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# Use canny
srcCanny = cv2.Canny(srcBlur, ret, ret*2, 3)

# im is the output image
# contours is the contour list
# I forgot what heirarchy was
im, contours, heirarchy = cv2.findContours(srcCanny,
                                           cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(src, contours, -1, (0, 255, 0), 3)

ConvexHullPoints = contoursConvexHull(contours)
cv2.polylines(src, [ConvexHullPoints], True, (0, 255, 255), 2)


cv2.imshow("Test", src)

cv2.waitKey(0)

And when I'm trying to run it, it's giving me

    result = cv2.convexHull(pts)
TypeError: points is not a numpy array, neither a scalar

And I'm guessing that I'm feeding the convexHull an input and it wants something else.

I'm pretty decent at C++ but I'm a total beginner at Python. I think I may be doing something wrong with I'm appending the contour elements to the pts list?

And honestly, I'm not all too sure why we need to append the points back to a new array, there doesn't seem to be any value manipulation or rearrangement that's going on.

Here's the C++ code for reference:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;
using namespace std;

vector<Point> contoursConvexHull( vector<vector<Point> > contours )
{
    vector<Point> result;
    vector<Point> pts;
    for ( size_t i = 0; i< contours.size(); i++)
        for ( size_t j = 0; j< contours[i].size(); j++)
            pts.push_back(contours[i][j]);
    convexHull( pts, result );
    return result;
}

int main( int, char** argv )
{
    Mat src, srcGray,srcBlur,srcCanny;

    src = imread( argv[1], 1 );
    cvtColor(src, srcGray, CV_BGR2GRAY);
    blur(srcGray, srcBlur, Size(3, 3));

    Canny(srcBlur, srcCanny, 0, 100, 3, true);

    vector<vector<Point> > contours;

    findContours( srcCanny, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );

    Mat drawing = Mat::zeros(srcCanny.size(), CV_8UC3);

    for (int i = 0; i< contours.size(); i++)
    {
        Scalar color = Scalar( 255,255,255);
        drawContours( drawing, contours, i, color, 2 );
    }

    vector<Point> ConvexHullPoints =  contoursConvexHull(contours);

    polylines( drawing, ConvexHullPoints, true, Scalar(0,0,255), 2 );
    imshow("Contours", drawing);

    polylines( src, ConvexHullPoints, true, Scalar(0,0,255), 2 );
    imshow("contoursConvexHull", src);
    waitKey();
    return 0;
}

Upvotes: 0

Views: 2040

Answers (1)

parsethis
parsethis

Reputation: 8078

The error say that pts is not an numpy array; its a python list.

To convert pts to an array, import numpy and do the simple conversion:

import numpy as np

# code ....

pts = np.array(pts)
result = cv2.convexHull(pts)

Upvotes: 1

Related Questions